diff -purN linux-2.6.34/arch/arm/boot/compressed/lib1funcs.S linux-2.6.34-dev/arch/arm/boot/compressed/lib1funcs.S --- linux-2.6.34/arch/arm/boot/compressed/lib1funcs.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/boot/compressed/lib1funcs.S 2010-10-15 14:15:54.478524470 +0100 @@ -0,0 +1,348 @@ +/* + * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines + * + * Author: Nicolas Pitre + * - contributed to gcc-3.4 on Sep 30, 2003 + * - adapted for the Linux kernel on Oct 2, 2003 + */ + +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include +#include + + +.macro ARM_DIV_BODY dividend, divisor, result, curbit + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \curbit, \divisor + clz \result, \dividend + sub \result, \curbit, \result + mov \curbit, #1 + mov \divisor, \divisor, lsl \result + mov \curbit, \curbit, lsl \result + mov \result, #0 + +#else + + @ Initially shift the divisor left 3 bits if possible, + @ set curbit accordingly. This allows for curbit to be located + @ at the left end of each 4 bit nibbles in the division loop + @ to save one loop in most cases. + tst \divisor, #0xe0000000 + moveq \divisor, \divisor, lsl #3 + moveq \curbit, #8 + movne \curbit, #1 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + movlo \curbit, \curbit, lsl #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + movlo \curbit, \curbit, lsl #1 + blo 1b + + mov \result, #0 + +#endif + + @ Division loop +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + orrhs \result, \result, \curbit + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + orrhs \result, \result, \curbit, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + orrhs \result, \result, \curbit, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + orrhs \result, \result, \curbit, lsr #3 + cmp \dividend, #0 @ Early termination? + movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? + movne \divisor, \divisor, lsr #4 + bne 1b + +.endm + + +.macro ARM_DIV2_ORDER divisor, order + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + rsb \order, \order, #31 + +#else + + cmp \divisor, #(1 << 16) + movhs \divisor, \divisor, lsr #16 + movhs \order, #16 + movlo \order, #0 + + cmp \divisor, #(1 << 8) + movhs \divisor, \divisor, lsr #8 + addhs \order, \order, #8 + + cmp \divisor, #(1 << 4) + movhs \divisor, \divisor, lsr #4 + addhs \order, \order, #4 + + cmp \divisor, #(1 << 2) + addhi \order, \order, #3 + addls \order, \order, \divisor, lsr #1 + +#endif + +.endm + + +.macro ARM_MOD_BODY dividend, divisor, order, spare + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + mov \divisor, \divisor, lsl \order + +#else + + mov \order, #0 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + addlo \order, \order, #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + addlo \order, \order, #1 + blo 1b + +#endif + + @ Perform all needed substractions to keep only the reminder. + @ Do comparisons in batch of 4 first. + subs \order, \order, #3 @ yes, 3 is intended here + blt 2f + +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + cmp \dividend, #1 + mov \divisor, \divisor, lsr #4 + subges \order, \order, #4 + bge 1b + + tst \order, #3 + teqne \dividend, #0 + beq 5f + + @ Either 1, 2 or 3 comparison/substractions are left. +2: cmn \order, #2 + blt 4f + beq 3f + cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +3: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +4: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor +5: +.endm + + +ENTRY(__udivsi3) +ENTRY(__aeabi_uidiv) + + subs r2, r1, #1 + moveq pc, lr + bcc Ldiv0 + cmp r0, r1 + bls 11f + tst r1, r2 + beq 12f + + ARM_DIV_BODY r0, r1, r2, r3 + + mov r0, r2 + mov pc, lr + +11: moveq r0, #1 + movne r0, #0 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + mov r0, r0, lsr r2 + mov pc, lr + +ENDPROC(__udivsi3) +ENDPROC(__aeabi_uidiv) + +ENTRY(__umodsi3) + + subs r2, r1, #1 @ compare divisor with 1 + bcc Ldiv0 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + movls pc, lr + + ARM_MOD_BODY r0, r1, r2, r3 + + mov pc, lr + +ENDPROC(__umodsi3) + +ENTRY(__divsi3) +ENTRY(__aeabi_idiv) + + cmp r1, #0 + eor ip, r0, r1 @ save the sign of the result. + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + subs r2, r1, #1 @ division by 1 or -1 ? + beq 10f + movs r3, r0 + rsbmi r3, r0, #0 @ positive dividend value + cmp r3, r1 + bls 11f + tst r1, r2 @ divisor is power of 2 ? + beq 12f + + ARM_DIV_BODY r3, r1, r0, r2 + + cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +10: teq ip, r0 @ same sign ? + rsbmi r0, r0, #0 + mov pc, lr + +11: movlo r0, #0 + moveq r0, ip, asr #31 + orreq r0, r0, #1 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + cmp ip, #0 + mov r0, r3, lsr r2 + rsbmi r0, r0, #0 + mov pc, lr + +ENDPROC(__divsi3) +ENDPROC(__aeabi_idiv) + +ENTRY(__modsi3) + + cmp r1, #0 + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + movs ip, r0 @ preserve sign of dividend + rsbmi r0, r0, #0 @ if negative make positive + subs r2, r1, #1 @ compare divisor with 1 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + bls 10f + + ARM_MOD_BODY r0, r1, r2, r3 + +10: cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +ENDPROC(__modsi3) + +#ifdef CONFIG_AEABI + +ENTRY(__aeabi_uidivmod) + + stmfd sp!, {r0, r1, ip, lr} + bl __aeabi_uidiv + ldmfd sp!, {r1, r2, ip, lr} + mul r3, r0, r2 + sub r1, r1, r3 + mov pc, lr + +ENDPROC(__aeabi_uidivmod) + +ENTRY(__aeabi_idivmod) + + stmfd sp!, {r0, r1, ip, lr} + bl __aeabi_idiv + ldmfd sp!, {r1, r2, ip, lr} + mul r3, r0, r2 + sub r1, r1, r3 + mov pc, lr + +ENDPROC(__aeabi_idivmod) + +#endif + +Ldiv0: + + str lr, [sp, #-8]! + bl __div0 + mov r0, #0 @ About as wrong as it could be. + ldr pc, [sp], #8 + + Binary files linux-2.6.34/arch/arm/boot/compressed/piggy.gzip and linux-2.6.34-dev/arch/arm/boot/compressed/piggy.gzip differ diff -purN linux-2.6.34/arch/arm/configs/ea3250_defconfig linux-2.6.34-dev/arch/arm/configs/ea3250_defconfig --- linux-2.6.34/arch/arm/configs/ea3250_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/configs/ea3250_defconfig 2010-10-15 14:10:00.098525816 +0100 @@ -0,0 +1,1669 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +CONFIG_ARCH_LPC32XX=y +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_MACH_PHY3250 is not set +CONFIG_MACH_EA3250=y + +# +# Embedded Artists Display Selection +# +CONFIG_EA3250_QVGA_3_2_LCD=y +# CONFIG_EA3250_QVGA_2_8_OLED is not set + +# +# Standard UARTS +# +# CONFIG_ARCH_LPC32XX_UART3_SELECT is not set +# CONFIG_ARCH_LPC32XX_UART4_SELECT is not set +CONFIG_ARCH_LPC32XX_UART5_SELECT=y +# CONFIG_ARCH_LPC32XX_UART6_SELECT is not set + +# +# High speed UARTS +# +# CONFIG_ARCH_LPC32XX_HSUART1_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART2_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART7_SELECT is not set + +# +# LPC32XX chip components +# +# CONFIG_ARCH_LPC32XX_IRAM_FOR_NET is not set +# CONFIG_ARCH_LPC32XX_MII_SUPPORT is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_MUSEUM_IDS=y +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_SLC_LPC32XX=y +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +CONFIG_EEPROM_AT25=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_NATIONAL_PHY=y +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_LPC_ENET=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LPC32XX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=y +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_LPC32XX is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_HS_LPC32XX is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PNX=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_PL061 is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_PNX4008_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX 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 is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y +CONFIG_SND_LPC3XXX_SOC=y +CONFIG_SND_LPC3XXX_SOC_I2S_UDA1380=y +CONFIG_SND_LPC32XX_USEI2S1=y +# CONFIG_SND_LPC32XX_USEI2S_SLAVE_MODETX is not set +# CONFIG_SND_LPC32XX_USEI2S_SLAVE_MODERX is not set +CONFIG_SND_LPC32XX_SLAVE_TX_CLK_TO_RX=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_UDA1380=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# 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_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 is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_ARMMMCI=y +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_RTC_DRV_LPC32XX=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -purN linux-2.6.34/arch/arm/configs/fdi3250_config linux-2.6.34-dev/arch/arm/configs/fdi3250_config --- linux-2.6.34/arch/arm/configs/fdi3250_config 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/configs/fdi3250_config 2010-10-15 14:10:00.098525816 +0100 @@ -0,0 +1,1576 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +CONFIG_ARCH_LPC32XX=y +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_MACH_PHY3250 is not set +# CONFIG_MACH_EA3250 is not set +CONFIG_MACH_FDI3250=y +CONFIG_SOM9DIMM3250_LCD_PANEL=y +CONFIG_SOM9DIMM3250_LCD_OKAYA_VGA_35=y +# CONFIG_SOM9DIMM3250_LCD_TOSHIBA_QVGA_35 is not set + +# +# Standard UARTS +# +# CONFIG_ARCH_LPC32XX_UART3_SELECT is not set +# CONFIG_ARCH_LPC32XX_UART4_SELECT is not set +CONFIG_ARCH_LPC32XX_UART5_SELECT=y +# CONFIG_ARCH_LPC32XX_UART6_SELECT is not set + +# +# High speed UARTS +# +CONFIG_ARCH_LPC32XX_HSUART1_SELECT=y +# CONFIG_ARCH_LPC32XX_HSUART2_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART7_SELECT is not set + +# +# LPC32XX chip components +# +# CONFIG_ARCH_LPC32XX_IRAM_FOR_NET is not set +# CONFIG_ARCH_LPC32XX_MII_SUPPORT is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyTX0,115200n81 init=/sbin/init" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_MUSEUM_IDS=y +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_SLC_LPC32XX=y +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=4 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_LPC_ENET=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +CONFIG_TOUCHSCREEN_LPC32XX=y +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_HS_LPC32XX=y +CONFIG_SERIAL_HS_LPC32XX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PNX=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_PL061 is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_PNX4008_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX 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 is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 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 is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_RTC_DRV_LPC32XX=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# 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_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -purN linux-2.6.34/arch/arm/configs/lpc3250stick_defconfig linux-2.6.34-dev/arch/arm/configs/lpc3250stick_defconfig --- linux-2.6.34/arch/arm/configs/lpc3250stick_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/configs/lpc3250stick_defconfig 2010-10-19 08:56:14.191452468 +0100 @@ -0,0 +1,1531 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34 +# Fri Oct 15 14:12:58 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +CONFIG_ARCH_LPC32XX=y +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_MACH_PHY3250 is not set +# CONFIG_MACH_EA3250 is not set +# CONFIG_MACH_FDI3250 is not set +CONFIG_MACH_STK3250=y + +# +# Standard UARTS +# +# CONFIG_ARCH_LPC32XX_UART3_SELECT is not set +# CONFIG_ARCH_LPC32XX_UART4_SELECT is not set +CONFIG_ARCH_LPC32XX_UART5_SELECT=y +# CONFIG_ARCH_LPC32XX_UART6_SELECT is not set + +# +# High speed UARTS +# +CONFIG_ARCH_LPC32XX_HSUART1_SELECT=y +# CONFIG_ARCH_LPC32XX_HSUART2_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART7_SELECT is not set + +# +# LPC32XX chip components +# +CONFIG_ARCH_LPC32XX_IRAM_FOR_NET=y +# CONFIG_ARCH_LPC32XX_MII_SUPPORT is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_MUSEUM_IDS=y +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_SLC_LPC32XX=y +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_LPC_ENET=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_HS_LPC32XX=y +# CONFIG_SERIAL_HS_LPC32XX_CONSOLE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PNX=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_PL061 is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_PNX4008_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# 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_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 is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_ARMMMCI=y +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_RTC_DRV_LPC32XX=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -purN linux-2.6.34/arch/arm/configs/phy3250_defconfig linux-2.6.34-dev/arch/arm/configs/phy3250_defconfig --- linux-2.6.34/arch/arm/configs/phy3250_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/configs/phy3250_defconfig 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,1700 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34 +# Wed Aug 18 09:54:34 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +CONFIG_ARCH_LPC32XX=y +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_MACH_PHY3250=y +# CONFIG_MACH_EA3250 is not set + +# +# Standard UARTS +# +# CONFIG_ARCH_LPC32XX_UART3_SELECT is not set +# CONFIG_ARCH_LPC32XX_UART4_SELECT is not set +CONFIG_ARCH_LPC32XX_UART5_SELECT=y +# CONFIG_ARCH_LPC32XX_UART6_SELECT is not set + +# +# High speed UARTS +# +# CONFIG_ARCH_LPC32XX_HSUART1_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART2_SELECT is not set +# CONFIG_ARCH_LPC32XX_HSUART7_SELECT is not set + +# +# LPC32XX chip components +# +# CONFIG_ARCH_LPC32XX_IRAM_FOR_NET is not set +# CONFIG_ARCH_LPC32XX_MII_SUPPORT is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_MUSEUM_IDS=y +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_SLC_LPC32XX=y +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +CONFIG_EEPROM_AT25=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_LPC_ENET=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LPC32XX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +CONFIG_TOUCHSCREEN_LPC32XX=y +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_HS_LPC32XX is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PNX=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_PL061 is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_PNX4008_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX 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 is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y +CONFIG_SND_LPC3XXX_SOC=y +CONFIG_SND_LPC3XXX_SOC_I2S_UDA1380=y +CONFIG_SND_LPC32XX_USEI2S1=y +# CONFIG_SND_LPC32XX_USEI2S_SLAVE_MODETX is not set +# CONFIG_SND_LPC32XX_USEI2S_SLAVE_MODERX is not set +CONFIG_SND_LPC32XX_SLAVE_TX_CLK_TO_RX=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_UDA1380=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# 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_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 is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_LPC32XX is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_ARMMMCI=y +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +CONFIG_RTC_DRV_LPC32XX=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -purN linux-2.6.34/arch/arm/Kconfig linux-2.6.34-dev/arch/arm/Kconfig --- linux-2.6.34/arch/arm/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/Kconfig 2010-10-15 14:10:00.098525816 +0100 @@ -484,6 +484,19 @@ config ARCH_LOKI help Support for the Marvell Loki (88RC8480) SoC. +config ARCH_LPC32XX + bool "NXP LPC32XX" + select CPU_ARM926T + select ARCH_REQUIRE_GPIOLIB + select HAVE_IDE + select ARM_AMBA + select USB_ARCH_HAS_OHCI + select COMMON_CLKDEV + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + help + Support for the NXP LPC32XX family of processors + config ARCH_MV78XX0 bool "Marvell MV78xx0" select CPU_FEROCEON @@ -851,6 +864,8 @@ source "arch/arm/mach-lh7a40x/Kconfig" source "arch/arm/mach-loki/Kconfig" +source "arch/arm/mach-lpc32xx/Kconfig" + source "arch/arm/mach-msm/Kconfig" source "arch/arm/mach-mv78xx0/Kconfig" diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/clock.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/clock.c --- linux-2.6.34/arch/arm/mach-lpc32xx/clock.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/clock.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,1181 @@ +/* + * arch/arm/mach-lpc32xx/clock.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * LPC32xx clock management driver overview + * + * The LPC32XX contains a number of high level system clocks that can be + * generated from different sources. These system clocks are used to + * generate the CPU and bus rates and the individual peripheral clocks in + * the system. When Linux is started by the boot loader, the system + * clocks are already running. Stopping a system clock during normal + * Linux operation should never be attempted, as peripherals that require + * those clocks will quit working (ie, DRAM). + * + * The LPC32xx high level clock tree looks as follows. Clocks marked with + * an asterisk are always on and cannot be disabled. Clocks marked with + * an ampersand can only be disabled in CPU suspend mode. Clocks marked + * with a caret are always on if it is the selected clock for the SYSCLK + * source. The clock that isn't used for SYSCLK can be enabled and + * disabled normally. + * 32KHz oscillator* + * / | \ + * RTC* PLL397^ TOUCH + * / + * Main oscillator^ / + * | \ / + * | SYSCLK& + * | \ + * | \ + * USB_PLL HCLK_PLL& + * | | | + * USB host/device PCLK& | + * | | + * Peripherals + * + * The CPU and chip bus rates are derived from the HCLK PLL, which can + * generate various clock rates up to 266MHz and beyond. The internal bus + * rates (PCLK and HCLK) are generated from dividers based on the HCLK + * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate, + * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high + * level clocks are based on either HCLK or PCLK, but have their own + * dividers as part of the IP itself. Because of this, the system clock + * rates should not be changed. + * + * The HCLK PLL is clocked from SYSCLK, which can be derived from the + * main oscillator or PLL397. PLL397 generates a rate that is 397 times + * the 32KHz oscillator rate. The main oscillator runs at the selected + * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate + * is normally 13MHz, but depends on the selection of external crystals + * or oscillators. If USB operation is required, the main oscillator must + * be used in the system. + * + * Switching SYSCLK between sources during normal Linux operation is not + * supported. SYSCLK is preset in the bootloader. Because of the + * complexities of clock management during clock frequency changes, + * there are some limitations to the clock driver explained below: + * - The PLL397 and main oscillator can be enabled and disabled by the + * clk_enable() and clk_disable() functions unless SYSCLK is based + * on that clock. This allows the other oscillator that isn't driving + * the HCLK PLL to be used as another system clock that can be routed + * to an external pin. + * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with + * this driver. + * - HCLK and PCLK rates cannot be changed as part of this driver. + * - Most peripherals have their own dividers are part of the peripheral + * block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates + * will also impact the individual peripheral rates. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "clock.h" +#include "common.h" + +static int usb_pll_enable, usb_pll_valid; + +static struct clk clk_armpll; +static struct clk clk_usbpll; +static DEFINE_MUTEX(clkm_lock); + +/* + * Post divider values for PLLs based on selected register value + */ +static const u32 pll_postdivs[4] = {1, 2, 4, 8}; + +static unsigned long local_return_parent_rate(struct clk *clk) +{ + /* + * If a clock has a rate of 0, then it inherits it's parent + * clock rate + */ + while (clk->rate == 0) + clk = clk->parent; + + return clk->rate; +} + +/* 32KHz clock has a fixed rate and is not stoppable */ +static struct clk osc_32KHz = { + .rate = LPC32XX_CLOCK_OSC_FREQ, + .get_rate = local_return_parent_rate, +}; + +static int local_pll397_enable(struct clk *clk, int enable) +{ + u32 reg; + unsigned long timeout = jiffies + msecs_to_jiffies(10); + + reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); + + if (enable == 0) { + reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; + __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); + } else { + /* Enable PLL397 */ + reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; + __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); + + /* Wait for PLL397 lock */ + while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & + LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && + (timeout > jiffies)) + cpu_relax(); + + if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & + LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) + return -ENODEV; + } + + return 0; +} + +static int local_oscmain_enable(struct clk *clk, int enable) +{ + u32 reg; + unsigned long timeout = jiffies + msecs_to_jiffies(10); + + reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); + + if (enable == 0) { + reg |= LPC32XX_CLKPWR_MOSC_DISABLE; + __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); + } else { + /* Enable main oscillator */ + reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE; + __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); + + /* Wait for main oscillator to start */ + while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & + LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && + (timeout > jiffies)) + cpu_relax(); + + if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & + LPC32XX_CLKPWR_MOSC_DISABLE) != 0) + return -ENODEV; + } + + return 0; +} + +static struct clk osc_pll397 = { + .parent = &osc_32KHz, + .enable = local_pll397_enable, + .rate = LPC32XX_CLOCK_OSC_FREQ * 397, + .get_rate = local_return_parent_rate, +}; + +static struct clk osc_main = { + .enable = local_oscmain_enable, + .rate = LPC32XX_MAIN_OSC_FREQ, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_sys; + +/* + * Convert a PLL register value to a PLL output frequency + */ +u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval) +{ + struct clk_pll_setup pllcfg; + + pllcfg.cco_bypass_b15 = 0; + pllcfg.direct_output_b14 = 0; + pllcfg.fdbk_div_ctrl_b13 = 0; + if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0) + pllcfg.cco_bypass_b15 = 1; + if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0) + pllcfg.direct_output_b14 = 1; + if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0) + pllcfg.fdbk_div_ctrl_b13 = 1; + pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF); + pllcfg.pll_n = 1 + ((regval >> 9) & 0x3); + pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)]; + + return clk_check_pll_setup(inputclk, &pllcfg); +} + +/* + * Setup the HCLK PLL with a PLL structure + */ +static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup) +{ + u32 tv, tmp = 0; + + if (PllSetup->analog_on != 0) + tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP; + if (PllSetup->cco_bypass_b15 != 0) + tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS; + if (PllSetup->direct_output_b14 != 0) + tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS; + if (PllSetup->fdbk_div_ctrl_b13 != 0) + tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK; + + tv = ffs(PllSetup->pll_p) - 1; + if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3)) + return 0; + + tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv); + tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1); + tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1); + + return tmp; +} + +/* + * Update the ARM core PLL frequency rate variable from the actual PLL setting + */ +static void local_update_armpll_rate(void) +{ + u32 clkin, pllreg; + + clkin = clk_armpll.parent->rate; + pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; + + clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg); +} + +/* + * Find a PLL configuration for the selected input frequency + */ +static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq, + struct clk_pll_setup *pllsetup) +{ + u32 ifreq, freqtol, m, n, p, fclkout; + + /* Determine frequency tolerance limits */ + freqtol = target_freq / 250; + ifreq = pllin_freq; + + /* Is direct bypass mode possible? */ + if (abs(pllin_freq - target_freq) <= freqtol) { + pllsetup->analog_on = 0; + pllsetup->cco_bypass_b15 = 1; + pllsetup->direct_output_b14 = 1; + pllsetup->fdbk_div_ctrl_b13 = 1; + pllsetup->pll_p = pll_postdivs[0]; + pllsetup->pll_n = 1; + pllsetup->pll_m = 1; + return clk_check_pll_setup(ifreq, pllsetup); + } else if (target_freq <= ifreq) { + pllsetup->analog_on = 0; + pllsetup->cco_bypass_b15 = 1; + pllsetup->direct_output_b14 = 0; + pllsetup->fdbk_div_ctrl_b13 = 1; + pllsetup->pll_n = 1; + pllsetup->pll_m = 1; + for (p = 0; p <= 3; p++) { + pllsetup->pll_p = pll_postdivs[p]; + fclkout = clk_check_pll_setup(ifreq, pllsetup); + if (abs(target_freq - fclkout) <= freqtol) + return fclkout; + } + } + + /* Is direct mode possible? */ + pllsetup->analog_on = 1; + pllsetup->cco_bypass_b15 = 0; + pllsetup->direct_output_b14 = 1; + pllsetup->fdbk_div_ctrl_b13 = 0; + pllsetup->pll_p = pll_postdivs[0]; + for (m = 1; m <= 256; m++) { + for (n = 1; n <= 4; n++) { + /* Compute output frequency for this value */ + pllsetup->pll_n = n; + pllsetup->pll_m = m; + fclkout = clk_check_pll_setup(ifreq, + pllsetup); + if (abs(target_freq - fclkout) <= + freqtol) + return fclkout; + } + } + + /* Is integer mode possible? */ + pllsetup->analog_on = 1; + pllsetup->cco_bypass_b15 = 0; + pllsetup->direct_output_b14 = 0; + pllsetup->fdbk_div_ctrl_b13 = 1; + for (m = 1; m <= 256; m++) { + for (n = 1; n <= 4; n++) { + for (p = 0; p < 4; p++) { + /* Compute output frequency */ + pllsetup->pll_p = pll_postdivs[p]; + pllsetup->pll_n = n; + pllsetup->pll_m = m; + fclkout = clk_check_pll_setup( + ifreq, pllsetup); + if (abs(target_freq - fclkout) <= freqtol) + return fclkout; + } + } + } + + /* Try non-integer mode */ + pllsetup->analog_on = 1; + pllsetup->cco_bypass_b15 = 0; + pllsetup->direct_output_b14 = 0; + pllsetup->fdbk_div_ctrl_b13 = 0; + for (m = 1; m <= 256; m++) { + for (n = 1; n <= 4; n++) { + for (p = 0; p < 4; p++) { + /* Compute output frequency */ + pllsetup->pll_p = pll_postdivs[p]; + pllsetup->pll_n = n; + pllsetup->pll_m = m; + fclkout = clk_check_pll_setup( + ifreq, pllsetup); + if (abs(target_freq - fclkout) <= freqtol) + return fclkout; + } + } + } + + return 0; +} + +static struct clk clk_armpll = { + .parent = &clk_sys, + .get_rate = local_return_parent_rate, +}; + +/* + * Setup the USB PLL with a PLL structure + */ +static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) +{ + u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup); + + reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF; + reg |= tmp; + __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + + return clk_check_pll_setup(clk_usbpll.parent->rate, + pHCLKPllSetup); +} + +static int local_usbpll_enable(struct clk *clk, int enable) +{ + u32 reg; + int ret = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(20); + + reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); + + __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 | + LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), + LPC32XX_CLKPWR_USB_CTRL); + __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1, + LPC32XX_CLKPWR_USB_CTRL); + + if (enable && usb_pll_valid && usb_pll_enable) { + ret = -ENODEV; + /* + * If the PLL rate has been previously set, then the rate + * in the PLL register is valid and can be enabled here. + * Otherwise, it needs to be enabled as part of setrate. + */ + + /* + * Gate clock into PLL + */ + reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; + __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + + /* + * Enable PLL + */ + reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP; + __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + + /* + * Wait for PLL to lock + */ + while ((timeout > jiffies) && (ret == -ENODEV)) { + reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); + if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) + ret = 0; + else + udelay(10); + } + + /* + * Gate clock from PLL if PLL is locked + */ + if (ret == 0) { + __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2, + LPC32XX_CLKPWR_USB_CTRL); + } + else { + __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | + LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), + LPC32XX_CLKPWR_USB_CTRL); + } + } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) { + usb_pll_valid = 0; + usb_pll_enable = 0; + } + + return ret; +} + +static unsigned long local_usbpll_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 clkin, usbdiv; + struct clk_pll_setup pllsetup; + + /* + * Unlike other clocks, this clock has a KHz input rate, so bump + * it up to work with the PLL function + */ + rate = rate * 1000; + + clkin = clk->get_rate(clk); + usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & + LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; + clkin = clkin / usbdiv; + + /* Try to find a good rate setup */ + if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) + return 0; + + return clk_check_pll_setup(clkin, &pllsetup); +} + +static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -ENODEV; + u32 clkin, usbdiv; + struct clk_pll_setup pllsetup; + + /* + * Unlike other clocks, this clock has a KHz input rate, so bump + * it up to work with the PLL function + */ + rate = rate * 1000; + + clkin = clk->get_rate(clk->parent); + usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & + LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; + clkin = clkin / usbdiv; + + /* Try to find a good rate setup */ + if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) + return -EINVAL; + + /* + * Disable PLL clocks during PLL change + */ + local_usbpll_enable(clk, 0); + pllsetup.analog_on = 0; + local_clk_usbpll_setup(&pllsetup); + + /* + * Start USB PLL and check PLL status + */ + + usb_pll_valid = 1; + usb_pll_enable = 1; + + ret = local_usbpll_enable(clk, 1); + if (ret >= 0) + clk->rate = clk_check_pll_setup(clkin, &pllsetup); + + return ret; +} + +static struct clk clk_usbpll = { + .parent = &osc_main, + .set_rate = local_usbpll_set_rate, + .enable = local_usbpll_enable, + .rate = 48000, /* In KHz */ + .get_rate = local_return_parent_rate, + .round_rate = local_usbpll_round_rate, +}; + +static u32 clk_get_hclk_div(void) +{ + static const u32 hclkdivs[4] = {1, 2, 4, 4}; + return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW( + __raw_readl(LPC32XX_CLKPWR_HCLK_DIV))]; +} + +static struct clk clk_hclk = { + .parent = &clk_armpll, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_pclk = { + .parent = &clk_armpll, + .get_rate = local_return_parent_rate, +}; + +static int local_onoff_enable(struct clk *clk, int enable) +{ + u32 tmp; + + tmp = __raw_readl(clk->enable_reg); + + if (enable == 0) + tmp &= ~clk->enable_mask; + else + tmp |= clk->enable_mask; + + __raw_writel(tmp, clk->enable_reg); + + return 0; +} + +/* Peripheral clock sources */ +static struct clk clk_timer0 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, + .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_timer1 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, + .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_timer2 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, + .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_timer3 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, + .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_wdt = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_TIMER_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_PWMCLK_WDOG_EN, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_vfp9 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_DEBUG_CTRL, + .enable_mask = LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT, + .get_rate = local_return_parent_rate, +}; +static struct clk clk_dma = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_DMA_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_uart3 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_uart4 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_uart5 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_uart6 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_i2c0 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_i2c1 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_i2c2 = { + .parent = &clk_pclk, + .enable = local_onoff_enable, + .enable_reg = io_p2v(LPC32XX_USB_BASE + 0xFF4), + .enable_mask = 0x4, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_ssp0 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_ssp1 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_kscan = { + .parent = &osc_32KHz, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_KEY_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_nand = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_i2s0 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_i2s1 = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN, + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_net = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_MACCLK_CTRL, + .enable_mask = (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN | + LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN | + LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN), + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_rtc = { + .parent = &osc_32KHz, + .rate = 1, /* 1 Hz */ + .get_rate = local_return_parent_rate, +}; + +static struct clk clk_usbd = { + .parent = &clk_usbpll, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_USB_CTRL, + .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN, + .get_rate = local_return_parent_rate, +}; + +static int tsc_onoff_enable(struct clk *clk, int enable) +{ + u32 tmp; + + /* Make sure 32KHz clock is the selected clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); + tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; + __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); + + if (enable == 0) + __raw_writel(0, clk->enable_reg); + else + __raw_writel(clk->enable_mask, clk->enable_reg); + + return 0; +} + +static struct clk clk_tsc = { + .parent = &osc_32KHz, + .enable = tsc_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, + .get_rate = local_return_parent_rate, +}; + +static int mmc_onoff_enable(struct clk *clk, int enable) +{ + u32 tmp; + + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & + ~LPC32XX_CLKPWR_MSCARD_SDCARD_EN; + + /* If rate is 0, disable clock */ + if (enable != 0) + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN; + + /* Start clock at highest rate */ + if (!(tmp & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xF))) + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(1); + + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + + return 0; +} + +static unsigned long mmc_get_rate(struct clk *clk) +{ + u32 div, rate; + + div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + + /* Get the parent clock rate */ + rate = clk->parent->get_rate(clk->parent); + + /* Get the MMC controller clock divider value */ + div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); + + if (!div) + div = 1; + + return rate / div; +} + +static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long div, prate; + + /* Get the parent clock rate */ + prate = clk->parent->get_rate(clk->parent); + + if (rate >= prate) + return prate; + + div = prate / rate; + if (div > 0xf) + div = 0xf; + + /* + * The divider is forced to 1 to keep the SD clock granularity + * good. Using a non-0 divider will limit the SD card clock rates + * the SD driver can generate. Remove it if your feeling crazy. + */ + div = 1; + + return prate / div; +} + +static int mmc_set_rate(struct clk *clk, unsigned long rate) +{ + u32 tmp; + unsigned long prate, div, crate = mmc_round_rate(clk, rate); + + prate = clk->parent->get_rate(clk->parent); + + div = prate / crate; + + /* The MMC clock must be on when accessing an MMC register */ + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & + ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div); + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + + return 0; +} + +/* + * This is the MMC IP clock, not the MMC CLK signal rate! + */ +static struct clk clk_mmc = { + .parent = &clk_armpll, + .set_rate = mmc_set_rate, + .get_rate = mmc_get_rate, + .round_rate = mmc_round_rate, + .enable = mmc_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_MS_CTRL, + .enable_mask = LPC32XX_CLKPWR_MSCARD_SDCARD_EN, +}; + +static unsigned long clcd_get_rate(struct clk *clk) +{ + u32 tmp, div, rate, oldclk; + + /* The LCD clock must be on when accessing an LCD register */ + oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); + __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, + LPC32XX_CLKPWR_LCDCLK_CTRL); + tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); + __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); + + rate = clk->parent->get_rate(clk->parent); + + /* Only supports internal clocking */ + if (tmp & TIM2_BCD) + return rate; + + div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22); + tmp = rate / (2 + div); + + return tmp; +} + +static int clcd_set_rate(struct clk *clk, unsigned long rate) +{ + u32 tmp, prate, div, oldclk; + + /* The LCD clock must be on when accessing an LCD register */ + oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); + __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, + LPC32XX_CLKPWR_LCDCLK_CTRL); + + tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD; + prate = clk->parent->get_rate(clk->parent); + + if (rate < prate) { + /* Find closest divider */ + div = prate / rate; + if (div >= 2) { + div -= 2; + tmp &= ~TIM2_BCD; + } + + tmp &= ~(0xF800001F); + tmp |= (div & 0x1F); + tmp |= (((div >> 5) & 0x1F) << 27); + } + + __raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); + __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); + + return 0; +} + +static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate) +{ + u32 prate, div; + + prate = clk->parent->get_rate(clk->parent); + + if (rate >= prate) + rate = prate; + else { + div = prate / rate; + if (div > 0x3ff) + div = 0x3ff; + + rate = prate / div; + } + + return rate; +} + +static struct clk clk_lcd = { + .parent = &clk_hclk, + .set_rate = clcd_set_rate, + .get_rate = clcd_get_rate, + .round_rate = clcd_round_rate, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_LCDCLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, +}; + +static inline void clk_lock(void) +{ + mutex_lock(&clkm_lock); +} + +static inline void clk_unlock(void) +{ + mutex_unlock(&clkm_lock); +} + +static void local_clk_disable(struct clk *clk) +{ + // WARN_ON(clk->usecount == 0); + + /* Don't attempt to disable clock if it has no users */ + if (clk->usecount > 0) { + clk->usecount--; + + /* Only disable clock when it has no more users */ + if ((clk->usecount == 0) && (clk->enable)) + clk->enable(clk, 0); + + /* Check parent clocks, they may need to be disabled too */ + if (clk->parent) + local_clk_disable(clk->parent); + } +} + +static int local_clk_enable(struct clk *clk) +{ + int ret = 0; + + /* Enable parent clocks first and update use counts */ + if (clk->parent) + ret = local_clk_enable(clk->parent); + + if (!ret) { + /* Only enable clock if it's currently disabled */ + if ((clk->usecount == 0) && (clk->enable)) + ret = clk->enable(clk, 1); + + if (!ret) + clk->usecount++; + else if (clk->parent) + local_clk_disable(clk->parent); + } + + return ret; +} + +/* + * clk_enable - inform the system when the clock source should be running. + */ +int clk_enable(struct clk *clk) +{ + int ret; + + clk_lock(); + ret = local_clk_enable(clk); + clk_unlock(); + + return ret; +} +EXPORT_SYMBOL(clk_enable); + +/* + * clk_disable - inform the system when the clock source is no longer required + */ +void clk_disable(struct clk *clk) +{ + clk_lock(); + local_clk_disable(clk); + clk_unlock(); +} +EXPORT_SYMBOL(clk_disable); + +/* + * clk_get_rate - obtain the current clock rate (in Hz) for a clock source + */ +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long rate; + + clk_lock(); + rate = clk->get_rate(clk); + clk_unlock(); + + return rate; +} +EXPORT_SYMBOL(clk_get_rate); + +/* + * clk_set_rate - set the clock rate for a clock source + */ +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + + /* + * Most system clocks can only be enabled or disabled, with + * the actual rate set as part of the peripheral dividers + * instead of high level clock control + */ + if (clk->set_rate) { + clk_lock(); + ret = clk->set_rate(clk, rate); + clk_unlock(); + } + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * clk_round_rate - adjust a rate to the exact rate a clock can provide + */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + clk_lock(); + + if (clk->round_rate) + rate = clk->round_rate(clk, rate); + else + rate = clk->get_rate(clk); + + clk_unlock(); + + return rate; +} +EXPORT_SYMBOL(clk_round_rate); + +/* + * clk_set_parent - set the parent clock source for this clock + */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + /* Clock re-parenting is not supported */ + return -EINVAL; +} +EXPORT_SYMBOL(clk_set_parent); + +/* + * clk_get_parent - get the parent clock source for this clock + */ +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = (d), \ + .con_id = (n), \ + .clk = &(c), \ + }, + +static struct clk_lookup lookups[] = { + _REGISTER_CLOCK(NULL, "osc_32KHz", osc_32KHz) + _REGISTER_CLOCK(NULL, "osc_pll397", osc_pll397) + _REGISTER_CLOCK(NULL, "osc_main", osc_main) + _REGISTER_CLOCK(NULL, "sys_ck", clk_sys) + _REGISTER_CLOCK(NULL, "arm_pll_ck", clk_armpll) + _REGISTER_CLOCK(NULL, "ck_pll5", clk_usbpll) + _REGISTER_CLOCK(NULL, "hclk_ck", clk_hclk) + _REGISTER_CLOCK(NULL, "pclk_ck", clk_pclk) + _REGISTER_CLOCK(NULL, "timer0_ck", clk_timer0) + _REGISTER_CLOCK(NULL, "timer1_ck", clk_timer1) + _REGISTER_CLOCK(NULL, "timer2_ck", clk_timer2) + _REGISTER_CLOCK(NULL, "timer3_ck", clk_timer3) + _REGISTER_CLOCK(NULL, "vfp9_ck", clk_vfp9) + _REGISTER_CLOCK(NULL, "clk_dmac", clk_dma) + _REGISTER_CLOCK("pnx4008-watchdog", NULL, clk_wdt) + _REGISTER_CLOCK(NULL, "uart3_ck", clk_uart3) + _REGISTER_CLOCK(NULL, "uart4_ck", clk_uart4) + _REGISTER_CLOCK(NULL, "uart5_ck", clk_uart5) + _REGISTER_CLOCK(NULL, "uart6_ck", clk_uart6) + _REGISTER_CLOCK("pnx-i2c.0", NULL, clk_i2c0) + _REGISTER_CLOCK("pnx-i2c.1", NULL, clk_i2c1) + _REGISTER_CLOCK("pnx-i2c.2", NULL, clk_i2c2) + _REGISTER_CLOCK("dev:ssp0", NULL, clk_ssp0) + _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1) + _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan) + _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) + _REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0) + _REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1) + _REGISTER_CLOCK("lpc32xx-ts", NULL, clk_tsc) + _REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc) + _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) + _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) + _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd) + _REGISTER_CLOCK("lpc32xx_rtc", NULL, clk_rtc) +}; + +static int __init clk_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); + + /* + * Setup muxed SYSCLK for HCLK PLL base -this selects the + * parent clock used for the ARM PLL and is used to derive + * the many system clock rates in the device. + */ + if (clk_is_sysclk_mainosc() != 0) + clk_sys.parent = &osc_main; + else + clk_sys.parent = &osc_pll397; + + clk_sys.rate = clk_sys.parent->rate; + + /* Compute the current ARM PLL and USB PLL frequencies */ + local_update_armpll_rate(); + + /* Compute HCLK and PCLK bus rates */ + clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div(); + clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div(); + + /* + * Enable system clocks - this step is somewhat formal, as the + * clocks are already running, but it does get the clock data + * inline with the actual system state. Never disable these + * clocks as they will only stop if the system is going to sleep. + * In that case, the chip/system power management functions will + * handle clock gating. + */ + if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk)) + printk(KERN_ERR "Error enabling system HCLK and PCLK\n"); + + /* + * Timers 0 and 1 were enabled and are being used by the high + * resolution tick function prior to this driver being initialized. + * Tag them now as used. + */ + if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1)) + printk(KERN_ERR "Error enabling timer tick clocks\n"); + + return 0; +} +core_initcall(clk_init); + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/clock.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/clock.h --- linux-2.6.34/arch/arm/mach-lpc32xx/clock.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/clock.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,38 @@ +/* + * arch/arm/mach-lpc32xx/clock.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LPC32XX_CLOCK_H +#define __LPC32XX_CLOCK_H + +struct clk { + struct list_head node; + struct clk *parent; + u32 rate; + u32 usecount; + + int (*set_rate) (struct clk *, unsigned long); + unsigned long (*round_rate) (struct clk *, unsigned long); + unsigned long (*get_rate) (struct clk *clk); + int (*enable) (struct clk *, int); + + /* Register address and bit mask for simple clocks */ + void __iomem *enable_reg; + u32 enable_mask; +}; + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/common.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/common.c --- linux-2.6.34/arch/arm/mach-lpc32xx/common.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/common.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,397 @@ +/* + * arch/arm/mach-lpc32xx/common.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include "common.h" + +/* + * Watchdog timer + */ +static struct resource watchdog_resources[] = { + [0] = { + .start = LPC32XX_WDTIM_BASE, + .end = LPC32XX_WDTIM_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device lpc32xx_watchdog_device = { + .name = "pnx4008-watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(watchdog_resources), + .resource = watchdog_resources, +}; + +/* + * Real Time Clock + */ +static struct resource rtc_resources[] = { + [0] = { + .start = LPC32XX_RTC_BASE, + .end = LPC32XX_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LPC32XX_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device lpc32xx_rtc_device = { + .name = "rtc-lpc32xx", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +/* + * I2C busses + */ +static struct i2c_pnx_data i2c0_data = { + .name = I2C_CHIP_NAME "1", + .base = LPC32XX_I2C1_BASE, + .irq = IRQ_LPC32XX_I2C_1, +}; + +static struct i2c_pnx_data i2c1_data = { + .name = I2C_CHIP_NAME "2", + .base = LPC32XX_I2C2_BASE, + .irq = IRQ_LPC32XX_I2C_2, +}; + +static struct i2c_pnx_data i2c2_data = { + .name = "USB-I2C", + .base = LPC32XX_OTG_I2C_BASE, + .irq = IRQ_LPC32XX_USB_I2C, +}; + +struct platform_device lpc32xx_i2c0_device = { + .name = "pnx-i2c", + .id = 0, + .dev = { + .platform_data = &i2c0_data, + }, +}; + +struct platform_device lpc32xx_i2c1_device = { + .name = "pnx-i2c", + .id = 1, + .dev = { + .platform_data = &i2c1_data, + }, +}; + +struct platform_device lpc32xx_i2c2_device = { + .name = "pnx-i2c", + .id = 2, + .dev = { + .platform_data = &i2c2_data, + }, +}; + +/* + * Touch Screen support + */ +static struct resource tsc_resources[] = { + [0] = { + .start = LPC32XX_ADC_BASE, + .end = LPC32XX_ADC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LPC32XX_TS_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; +struct platform_device lpc32xx_tsc_device = { + .name = "lpc32xx-ts", + .id = -1, + .num_resources = ARRAY_SIZE(tsc_resources), + .resource = tsc_resources, +}; + +#if defined (CONFIG_USB_OHCI_HCD) +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32) 0; +static struct resource ohci_resources[] = { + { + .start = IO_ADDRESS(LPC32XX_USB_BASE), + .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100), + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LPC32XX_USB_HOST, + .flags = IORESOURCE_IRQ, + }, +}; +struct platform_device lpc32xx_ohci_device = { + .name = "usb-ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xFFFFFFFF, + }, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; +#endif + + +#if defined(CONFIG_USB_GADGET_LPC32XX) +static void phy3250_usbd_conn_chg(int conn) { + /* Do nothing, it might be nice to enable an LED + * based on conn state being !0 */ +} + +static void phy3250_usbd_susp_chg(int susp) { + /* Device suspend if susp != 0 */ +} + +static void phy3250_rmwkup_chg(int remote_wakup_enable) { + /* Enable or disable USB remote wakeup */ +} + +struct lpc32xx_usbd_cfg lpc32xx_usbddata = { + .vbus_drv_pol = 1, + .conn_chgb = &phy3250_usbd_conn_chg, + .susp_chgb = &phy3250_usbd_susp_chg, + .rmwk_chgb = &phy3250_rmwkup_chg, +}; + +/* The dmamask must be set for OHCI to work, align to 128 bytes */ +static u64 usbd_dmamask = ~(u32) 0x7F; +static struct resource usbd_resources[] = { + { + .start = LPC32XX_USB_BASE, + .end = LPC32XX_USB_BASE + 0x100, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LPC32XX_USB_DEV_LP, + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_LPC32XX_USB_DEV_HP, + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_LPC32XX_USB_DEV_DMA, + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_LPC32XX_USB_OTG_ATX, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device lpc32xx_usbd_device = { + .name = "lpc32xx_udc", + .id = -1, + .dev = { + .dma_mask = &usbd_dmamask, + .coherent_dma_mask = 0xFFFFFFFF, + .platform_data = &lpc32xx_usbddata, + }, + .num_resources = ARRAY_SIZE(usbd_resources), + .resource = usbd_resources, +}; +#endif + +/* + * Returns the unique ID for the device + */ +void lpc32xx_get_uid(u32 devid[4]) +{ + int i; + + for (i = 0; i < 4; i++) + devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2)); +} + +/* + * Returns SYSCLK source + * 0 = PLL397, 1 = main oscillator + */ +int clk_is_sysclk_mainosc(void) +{ + if ((__raw_readl(LPC32XX_CLKPWR_SYSCLK_CTRL) & + LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX) == 0) + return 1; + + return 0; +} + +/* + * System reset via the watchdog timer + */ +void lpc32xx_watchdog_reset(void) +{ + /* Make sure WDT clocks are enabled */ + __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN, + LPC32XX_CLKPWR_TIMER_CLK_CTRL); + + /* Instant assert of RESETOUT_N with pulse length 1mS */ + __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18)); + __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC)); +} + +/* + * Detects and returns IRAM size for the device variation + */ +#define LPC32XX_IRAM_BANK_SIZE SZ_128K +static u32 iram_size; +u32 lpc32xx_return_iram_size(void) +{ + if (iram_size == 0) { + u32 savedval1, savedval2; + void __iomem *iramptr1, *iramptr2; + + iramptr1 = io_p2v(LPC32XX_IRAM_BASE); + iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE); + savedval1 = __raw_readl(iramptr1); + savedval2 = __raw_readl(iramptr2); + + if (savedval1 == savedval2) { + __raw_writel(savedval2 + 1, iramptr2); + if (__raw_readl(iramptr1) == savedval2 + 1) + iram_size = LPC32XX_IRAM_BANK_SIZE; + else + iram_size = LPC32XX_IRAM_BANK_SIZE * 2; + __raw_writel(savedval2, iramptr2); + } else + iram_size = LPC32XX_IRAM_BANK_SIZE * 2; + } + + return iram_size; +} + +/* + * Computes PLL rate from PLL register and input clock + */ +u32 clk_check_pll_setup(u32 ifreq, struct clk_pll_setup *pllsetup) +{ + u32 ilfreq, p, m, n, fcco, fref, cfreq; + int mode; + + /* + * PLL requirements + * ifreq must be >= 1MHz and <= 20MHz + * FCCO must be >= 156MHz and <= 320MHz + * FREF must be >= 1MHz and <= 27MHz + * Assume the passed input data is not valid + */ + + ilfreq = ifreq; + m = pllsetup->pll_m; + n = pllsetup->pll_n; + p = pllsetup->pll_p; + + mode = (pllsetup->cco_bypass_b15 << 2) | + (pllsetup->direct_output_b14 << 1) | + pllsetup->fdbk_div_ctrl_b13; + + switch (mode) { + case 0x0: /* Non-integer mode */ + cfreq = (m * ilfreq) / (2 * p * n); + fcco = (m * ilfreq) / n; + fref = ilfreq / n; + break; + + case 0x1: /* integer mode */ + cfreq = (m * ilfreq) / n; + fcco = (m * ilfreq) / (n * 2 * p); + fref = ilfreq / n; + break; + + case 0x2: + case 0x3: /* Direct mode */ + cfreq = (m * ilfreq) / n; + fcco = cfreq; + fref = ilfreq / n; + break; + + case 0x4: + case 0x5: /* Bypass mode */ + cfreq = ilfreq / (2 * p); + fcco = 156000000; + fref = 1000000; + break; + + case 0x6: + case 0x7: /* Direct bypass mode */ + default: + cfreq = ilfreq; + fcco = 156000000; + fref = 1000000; + break; + } + + if (fcco < 156000000 || fcco > 320000000) + cfreq = 0; + + if (fref < 1000000 || fref > 27000000) + cfreq = 0; + + return (u32) cfreq; +} + +u32 clk_get_pclk_div(void) +{ + return 1 + ((__raw_readl(LPC32XX_CLKPWR_HCLK_DIV) >> 2) & 0x1F); +} + +static struct map_desc lpc32xx_io_desc[] __initdata = { + { + .virtual = IO_ADDRESS(LPC32XX_AHB0_START), + .pfn = __phys_to_pfn(LPC32XX_AHB0_START), + .length = LPC32XX_AHB0_SIZE, + .type = MT_DEVICE + }, + { + .virtual = IO_ADDRESS(LPC32XX_AHB1_START), + .pfn = __phys_to_pfn(LPC32XX_AHB1_START), + .length = LPC32XX_AHB1_SIZE, + .type = MT_DEVICE + }, + { + .virtual = IO_ADDRESS(LPC32XX_FABAPB_START), + .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), + .length = LPC32XX_FABAPB_SIZE, + .type = MT_DEVICE + }, + { + .virtual = IO_ADDRESS(LPC32XX_IRAM_BASE), + .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), + .length = (LPC32XX_IRAM_BANK_SIZE * 2), + .type = MT_DEVICE + }, +}; + +void __init lpc32xx_map_io(void) +{ + iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); +} diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/common.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/common.h --- linux-2.6.34/arch/arm/mach-lpc32xx/common.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/common.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,77 @@ +/* + * arch/arm/mach-lpc32xx/common.h + * + * Author: Kevin Wells + * + * Copyright (C) 2009-2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LPC32XX_COMMON_H +#define __LPC32XX_COMMON_H + +#include + +/* + * Arch specific platform device structures + */ +extern struct platform_device lpc32xx_watchdog_device; +extern struct platform_device lpc32xx_i2c0_device; +extern struct platform_device lpc32xx_i2c1_device; +extern struct platform_device lpc32xx_i2c2_device; +extern struct platform_device lpc32xx_tsc_device; +extern struct platform_device lpc32xx_rtc_device; +extern struct platform_device lpc32xx_ohci_device; +extern struct platform_device lpc32xx_usbd_device; + +/* + * Other arch specific structures and functions + */ +extern struct sys_timer lpc32xx_timer; +extern void __init lpc32xx_init_irq(void); +extern void __init lpc32xx_map_io(void); +extern void __init lpc32xx_serial_init(void); +extern void __init lpc32xx_gpio_init(void); + +/* + * Structure used for setting up and querying the PLLS + */ +struct clk_pll_setup { + int analog_on; + int cco_bypass_b15; + int direct_output_b14; + int fdbk_div_ctrl_b13; + int pll_p; + int pll_n; + u32 pll_m; +}; + +extern int clk_is_sysclk_mainosc(void); +extern u32 clk_check_pll_setup(u32 ifreq, struct clk_pll_setup *pllsetup); +extern u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval); +extern u32 clk_get_pclk_div(void); + +/* + * Returns the LPC32xx unique 128-bit chip ID + */ +extern void lpc32xx_get_uid(u32 devid[4]); + +extern void lpc32xx_watchdog_reset(void); +extern u32 lpc32xx_return_iram_size(void); + +/* + * Pointers used for sizing and copying suspend function data + */ +extern int lpc32xx_sys_suspend(void); +extern int lpc32xx_sys_suspend_sz; + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/dma.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/dma.c --- linux-2.6.34/arch/arm/mach-lpc32xx/dma.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/dma.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,745 @@ +/* + * linux/arch/arm/mach-lpc32xx/ma-lpc32xx.c + * + * Copyright (C) 2008 NXP Semiconductors + * (Based on parts of the PNX4008 DMA driver) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DMAIOBASE io_p2v(LPC32XX_DMA_BASE) +#define VALID_CHANNEL(c) (((c) >= 0) && ((c) < MAX_DMA_CHANNELS)) + +static DEFINE_SPINLOCK(dma_lock); + +struct dma_linked_list { + u32 src; + u32 dest; + u32 next_lli; + u32 ctrl; +}; + +/* For DMA linked list operation, a linked list of DMA descriptors + is maintained along with some data to manage the list in software. */ +struct dma_list_ctrl { + struct dma_linked_list dmall; /* DMA list descriptor */ + struct dma_list_ctrl *next_list_addr; /* Virtual address to next list entry */ + struct dma_list_ctrl *prev_list_addr; /* Virtual address to previous list entry */ + u32 next_list_phy; /* Physical address to next list entry */ + u32 prev_list_phy; /* Physical address to previous list entry */ +}; + +/* Each DMA channel has one of these structures */ +struct dma_channel { + char *name; + void (*irq_handler) (int, int, void *); + void *data; + struct dma_config *dmacfg; + u32 control; + u32 config; + u32 config_int_mask; + + int list_entries; /* Number of list entries */ + u32 list_size; /* Total size of allocated list in bytes */ + u32 list_vstart; /* Allocated (virtual) address of list */ + u32 list_pstart; /* Allocated (physical) address of list */ + int free_entries; /* Number of free descriptors */ + struct dma_list_ctrl *list_head, *list_tail, *list_curr; +}; + +struct dma_control { + struct clk *clk; + int num_clks; + struct dma_channel dma_channels[MAX_DMA_CHANNELS]; +}; +static struct dma_control dma_ctrl; + +static inline void __dma_regs_lock(void) +{ + spin_lock_irq(&dma_lock); +} + +static inline void __dma_regs_unlock(void) +{ + spin_unlock_irq(&dma_lock); +} + +static inline void __dma_enable(int ch) { + u32 ch_cfg = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + ch_cfg |= DMAC_CHAN_ENABLE; + __raw_writel(ch_cfg, DMACH_CONFIG_CH(DMAIOBASE, ch)); +} + +static inline void __dma_disable(int ch) { + u32 ch_cfg = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + ch_cfg &= ~DMAC_CHAN_ENABLE; + __raw_writel(ch_cfg, DMACH_CONFIG_CH(DMAIOBASE, ch)); +} + +static void dma_clocks_up(void) +{ + /* Enable DMA clock if needed */ + if (dma_ctrl.num_clks == 0) + { + clk_enable(dma_ctrl.clk); + __raw_writel(DMAC_CTRL_ENABLE, DMA_CONFIG(DMAIOBASE)); + } + + dma_ctrl.num_clks++; +} + +static void dma_clocks_down(void) +{ + dma_ctrl.num_clks--; + + /* Disable DMA clock if needed */ + if (dma_ctrl.num_clks == 0) + { + __raw_writel(0, DMA_CONFIG(DMAIOBASE)); + clk_disable(dma_ctrl.clk); + } +} + +static int lpc32xx_ch_setup(struct dma_config *dmachcfg) +{ + u32 tmpctrl, tmpcfg, tmp; + int ch = dmachcfg->ch; + + /* Channel control setup */ + tmpctrl = 0; + switch (dmachcfg->src_size) + { + case 1: + tmpctrl |= DMAC_CHAN_SRC_WIDTH_8; + break; + + case 2: + tmpctrl |= DMAC_CHAN_SRC_WIDTH_16; + break; + + case 4: + tmpctrl |= DMAC_CHAN_SRC_WIDTH_32; + break; + + default: + return -EINVAL; + } + switch (dmachcfg->dst_size) + { + case 1: + tmpctrl |= DMAC_CHAN_DEST_WIDTH_8; + break; + + case 2: + tmpctrl |= DMAC_CHAN_DEST_WIDTH_16; + break; + + case 4: + tmpctrl |= DMAC_CHAN_DEST_WIDTH_32; + break; + + default: + return -EINVAL; + } + if (dmachcfg->src_inc != 0) + { + tmpctrl |= DMAC_CHAN_SRC_AUTOINC; + } + if (dmachcfg->dst_inc != 0) + { + tmpctrl |= DMAC_CHAN_DEST_AUTOINC; + } + if (dmachcfg->src_ahb1 != 0) + { + tmpctrl |= DMAC_CHAN_SRC_AHB1; + } + if (dmachcfg->dst_ahb1 != 0) + { + tmpctrl |= DMAC_CHAN_DEST_AHB1; + } + if (dmachcfg->tc_inten != 0) + { + tmpctrl |= DMAC_CHAN_INT_TC_EN; + } + tmpctrl |= dmachcfg->src_bsize | dmachcfg->dst_bsize; + dma_ctrl.dma_channels[ch].control = tmpctrl; + + /* Channel config setup */ + tmpcfg = dmachcfg->src_prph | dmachcfg->dst_prph | + dmachcfg->flowctrl; + dma_ctrl.dma_channels[ch].config = tmpcfg; + + dma_ctrl.dma_channels[ch].config_int_mask = 0; + if (dmachcfg->err_inten != 0) + { + dma_ctrl.dma_channels[ch].config_int_mask |= + DMAC_CHAN_IE; + } + if (dmachcfg->tc_inten != 0) + { + dma_ctrl.dma_channels[ch].config_int_mask |= + DMAC_CHAN_ITC; + } + + tmp = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + tmp &= ~DMAC_CHAN_ENABLE; + __raw_writel(tmp, DMACH_CONFIG_CH(DMAIOBASE, ch)); + + /* Clear interrupts for channel */ + __raw_writel((1 << ch), DMA_INT_TC_CLEAR(DMAIOBASE)); + __raw_writel((1 << ch), DMA_INT_ERR_CLEAR(DMAIOBASE)); + + /* Write control and config words */ + __raw_writel(tmpctrl, DMACH_CONTROL(DMAIOBASE, ch)); + __raw_writel(tmpcfg, DMACH_CONFIG_CH(DMAIOBASE, ch)); + + return 0; +} + +int lpc32xx_dma_ch_enable(int ch) +{ + if (!VALID_CHANNEL(ch) || !dma_ctrl.dma_channels[ch].name) + return -EINVAL; + + __dma_regs_lock(); + __dma_enable(ch); + __dma_regs_unlock(); + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_ch_enable); + +int lpc32xx_dma_ch_disable(int ch) +{ + if (!VALID_CHANNEL(ch) || !dma_ctrl.dma_channels[ch].name) + return -EINVAL; + + __dma_regs_lock(); + __dma_disable(ch); + __dma_regs_unlock(); + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_ch_disable); + +int lpc32xx_dma_ch_get(struct dma_config *dmachcfg, char *name, + void *irq_handler, void *data) { + int ret; + + if (!VALID_CHANNEL(dmachcfg->ch)) + return -EINVAL; + + /* If the channel is already enabled, return */ + if (dma_ctrl.dma_channels[dmachcfg->ch].name != NULL) + return -ENODEV; + + /* Save channel data */ + dma_ctrl.dma_channels[dmachcfg->ch].dmacfg = dmachcfg; + dma_ctrl.dma_channels[dmachcfg->ch].name = name; + dma_ctrl.dma_channels[dmachcfg->ch].irq_handler = irq_handler; + dma_ctrl.dma_channels[dmachcfg->ch].data = data; + + /* Setup channel */ + __dma_regs_lock(); + dma_clocks_up(); + ret = lpc32xx_ch_setup(dmachcfg); + __dma_regs_unlock(); + + return ret; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_ch_get); + +int lpc32xx_dma_ch_put(int ch) +{ + u32 tmp; + + if (!VALID_CHANNEL(ch)) + return -EINVAL; + + /* If the channel is already disabled, return */ + if (dma_ctrl.dma_channels[ch].name == NULL) + return -EINVAL; + + tmp = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + tmp &= ~DMAC_CHAN_ENABLE; + __raw_writel(tmp, DMACH_CONFIG_CH(DMAIOBASE, ch)); + + __dma_regs_lock(); + lpc32xx_dma_ch_disable(ch); + dma_clocks_down(); + __dma_regs_unlock(); + + dma_ctrl.dma_channels[ch].name = NULL; + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_ch_put); + +int lpc32xx_dma_ch_pause_unpause(int ch, int pause) { + u32 tmp; + + if (!VALID_CHANNEL(ch)) + return -EINVAL; + + /* If the channel is already disabled, return */ + if (dma_ctrl.dma_channels[ch].name == NULL) + return -EINVAL; + + tmp = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + if (pause) { + tmp |= DMAC_CHAN_HALT; + } + else { + tmp &= ~DMAC_CHAN_HALT; + } + __raw_writel(tmp, DMACH_CONFIG_CH(DMAIOBASE, ch)); + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_ch_pause_unpause); + +int lpc32xx_dma_start_pflow_xfer(int ch, + void *src, + void *dst, + int enable) +{ + u32 tmp; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL)) + return -EINVAL; + + /* When starting a DMA transfer where the peripheral is the flow + controller, DMA must be previously disabled */ + tmp = __raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)); + if (tmp & DMAC_CHAN_ENABLE) + return -EBUSY; + + __dma_regs_lock(); + __raw_writel((u32) src, DMACH_SRC_ADDR(DMAIOBASE, ch)); + __raw_writel((u32) dst, DMACH_DEST_ADDR(DMAIOBASE, ch)); + __raw_writel(0, DMACH_LLI(DMAIOBASE, ch)); + __raw_writel(dma_ctrl.dma_channels[ch].control, DMACH_CONTROL(DMAIOBASE, ch)); + + tmp = dma_ctrl.dma_channels[ch].config | + dma_ctrl.dma_channels[ch].config_int_mask; + if (enable != 0) + tmp |= DMAC_CHAN_ENABLE; + __raw_writel(tmp, DMACH_CONFIG_CH(DMAIOBASE, ch)); + + __dma_regs_unlock(); + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_start_pflow_xfer); + +extern u32 lpc32xx_dma_llist_v_to_p(int ch, + u32 vlist) { + u32 pptr; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + pptr = vlist - dma_ctrl.dma_channels[ch].list_vstart; + pptr += dma_ctrl.dma_channels[ch].list_pstart; + + return pptr; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_llist_v_to_p); + +u32 lpc32xx_dma_llist_p_to_v(int ch, + u32 plist) { + u32 vptr; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + vptr = plist - dma_ctrl.dma_channels[ch].list_pstart; + vptr += dma_ctrl.dma_channels[ch].list_vstart; + + return vptr; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_llist_p_to_v); + +u32 lpc32xx_dma_alloc_llist(int ch, + int entries) { + int i; + dma_addr_t dma_handle; + struct dma_list_ctrl *pdmalist, *pdmalistst; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL)) + return 0; + + /* + * Limit number of list entries, but add 1 extra entry as a spot holder + * for the end of the list + */ + if (entries < 2) { + entries = 2; + } + if (entries > 64) { + entries = 64; + } + entries++; + + /* Save list information */ + dma_ctrl.dma_channels[ch].list_entries = entries; + dma_ctrl.dma_channels[ch].list_size = (entries * sizeof(struct dma_list_ctrl)); + dma_ctrl.dma_channels[ch].list_vstart = (u32) dma_alloc_coherent(NULL, + dma_ctrl.dma_channels[ch].list_size, &dma_handle, GFP_KERNEL); + if (dma_ctrl.dma_channels[ch].list_vstart == 0) { + /* No allocated DMA space */ + return 0; + } + dma_ctrl.dma_channels[ch].list_pstart = (u32) dma_handle; + + /* Setup list tail and head pointers */ + pdmalist = pdmalistst = (struct dma_list_ctrl *) dma_ctrl.dma_channels[ch].list_vstart; + for (i = 0; i < entries; i++) { + pdmalistst->next_list_addr = pdmalistst + 1; + pdmalistst->prev_list_addr = pdmalistst - 1; + pdmalistst->next_list_phy = lpc32xx_dma_llist_v_to_p(ch, (u32) pdmalistst->next_list_addr); + pdmalistst->prev_list_phy = lpc32xx_dma_llist_v_to_p(ch, (u32) pdmalistst->prev_list_addr); + pdmalistst++; + } + pdmalist[entries - 1].next_list_addr = pdmalist; + pdmalist[entries - 1].next_list_phy = lpc32xx_dma_llist_v_to_p(ch, + (u32) pdmalist[entries - 1].next_list_addr); + pdmalist->prev_list_addr = &pdmalist[entries - 1]; + pdmalist->prev_list_phy = lpc32xx_dma_llist_v_to_p(ch, (u32) pdmalist->prev_list_addr); + + /* Save current free descriptors and current head/tail */ + dma_ctrl.dma_channels[ch].free_entries = entries - 1; + dma_ctrl.dma_channels[ch].list_head = pdmalist; + dma_ctrl.dma_channels[ch].list_tail = pdmalist; + dma_ctrl.dma_channels[ch].list_curr = pdmalist; + + return dma_ctrl.dma_channels[ch].list_vstart; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_alloc_llist); + +void lpc32xx_dma_dealloc_llist(int ch) { + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return; + + dma_free_coherent(NULL, dma_ctrl.dma_channels[ch].list_size, + (void *) dma_ctrl.dma_channels[ch].list_vstart, + (dma_addr_t) dma_ctrl.dma_channels[ch].list_pstart); + dma_ctrl.dma_channels[ch].list_head = 0; + dma_ctrl.dma_channels[ch].list_tail = 0; + dma_ctrl.dma_channels[ch].list_entries = 0; + dma_ctrl.dma_channels[ch].free_entries = 0; + dma_ctrl.dma_channels[ch].list_vstart = 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_dealloc_llist); + +extern u32 lpc32xx_dma_get_llist_head(int ch) { + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + /* Return the current list pointer (virtual) for the + DMA channel */ + return lpc32xx_dma_llist_p_to_v(ch, + __raw_readl(DMACH_LLI(DMAIOBASE, ch))); +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_get_llist_head); + +extern void lpc32xx_dma_flush_llist(int ch) { + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return; + + /* Disable channel and clear LLI */ + __dma_regs_lock(); + __dma_disable(ch); + __raw_writel(0, DMACH_LLI(DMAIOBASE, ch)); + __dma_regs_unlock(); + + dma_ctrl.dma_channels[ch].list_head = (struct dma_list_ctrl *) + dma_ctrl.dma_channels[ch].list_vstart; + dma_ctrl.dma_channels[ch].list_tail = (struct dma_list_ctrl *) + dma_ctrl.dma_channels[ch].list_vstart; + dma_ctrl.dma_channels[ch].list_curr = (struct dma_list_ctrl *) + dma_ctrl.dma_channels[ch].list_vstart; + dma_ctrl.dma_channels[ch].free_entries = + dma_ctrl.dma_channels[ch].list_entries - 1; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_flush_llist); + +u32 lpc32xx_dma_queue_llist_entry(int ch, + void *src, + void *dst, + int size) { + struct dma_list_ctrl *plhead; + u32 ctrl, cfg; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + /* Exit if all the buffers are used */ + if (dma_ctrl.dma_channels[ch].free_entries == 0) { + return 0; + } + + /* Next available DMA link descriptor */ + plhead = dma_ctrl.dma_channels[ch].list_head; + + /* Adjust size to number of transfers (vs bytes) */ + size = size / dma_ctrl.dma_channels[ch].dmacfg->dst_size; + + /* Setup control and config words */ + ctrl = dma_ctrl.dma_channels[ch].control | size; + cfg = dma_ctrl.dma_channels[ch].config | DMAC_CHAN_ENABLE | + dma_ctrl.dma_channels[ch].config_int_mask; + + /* Populate DMA linked data structure */ + plhead->dmall.src = (u32) src; + plhead->dmall.dest = (u32) dst; + plhead->dmall.next_lli = 0; + plhead->dmall.ctrl = ctrl; + + __dma_regs_lock(); + + /* Append this link to the end of the previous link */ + plhead->prev_list_addr->dmall.next_lli = lpc32xx_dma_llist_v_to_p(ch, (u32) plhead); + + /* Decrement available buffers */ + dma_ctrl.dma_channels[ch].free_entries--; + + /* If the DMA channel is idle, then the buffer needs to be placed directly into + the DMA registers */ + if ((__raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)) & DMAC_CHAN_ENABLE) == 0) { + /* DMA is disabled, so move the current buffer into the + channel registers and start transfer */ + __raw_writel((u32) src, DMACH_SRC_ADDR(DMAIOBASE, ch)); + __raw_writel((u32) dst, DMACH_DEST_ADDR(DMAIOBASE, ch)); + __raw_writel(0, DMACH_LLI(DMAIOBASE, ch)); + __raw_writel(ctrl, DMACH_CONTROL(DMAIOBASE, ch)); + __raw_writel(cfg, DMACH_CONFIG_CH(DMAIOBASE, ch)); + } + else if (__raw_readl(DMACH_LLI(DMAIOBASE, ch)) == 0) { + /* Update current entry to next entry */ + __raw_writel(dma_ctrl.dma_channels[ch].list_tail->next_list_phy, + DMACH_LLI(DMAIOBASE, ch)); + + /* + * If the channel was stopped before the next entry made it into the + * hardware descriptor, the next entry didn't make it there fast enough, + * so load the new descriptor here. + */ + if ((__raw_readl(DMACH_CONFIG_CH(DMAIOBASE, ch)) & DMAC_CHAN_ENABLE) == 0) { + __raw_writel((u32) src, DMACH_SRC_ADDR(DMAIOBASE, ch)); + __raw_writel((u32) dst, DMACH_DEST_ADDR(DMAIOBASE, ch)); + __raw_writel(0, DMACH_LLI(DMAIOBASE, ch)); + __raw_writel(ctrl, DMACH_CONTROL(DMAIOBASE, ch)); + __raw_writel(cfg, DMACH_CONFIG_CH(DMAIOBASE, ch)); + } + } + + /* Process next link on next call */ + dma_ctrl.dma_channels[ch].list_head = plhead->next_list_addr; + + __dma_regs_unlock(); + + return (u32) plhead; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_queue_llist_entry); + +extern u32 lpc32xx_get_free_llist_entry(int ch) { + struct dma_list_ctrl *pltail; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + /* Exit if no entries to free */ + if (dma_ctrl.dma_channels[ch].free_entries == + dma_ctrl.dma_channels[ch].list_entries) { + return 0; + } + + /* Get tail pointer */ + pltail = dma_ctrl.dma_channels[ch].list_tail; + + /* Next tail */ + dma_ctrl.dma_channels[ch].list_tail = pltail->next_list_addr; + + /* Increment available buffers */ + dma_ctrl.dma_channels[ch].free_entries++; + + return (u32) pltail; +} +EXPORT_SYMBOL_GPL(lpc32xx_get_free_llist_entry); + +int lpc32xx_dma_start_xfer(int ch, u32 config) +{ + struct dma_list_ctrl *plhead; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return -1; + + plhead = dma_ctrl.dma_channels[ch].list_head; + __dma_regs_lock(); + __raw_writel(plhead->dmall.src, DMACH_SRC_ADDR(DMAIOBASE, ch)); + __raw_writel(plhead->dmall.dest, DMACH_DEST_ADDR(DMAIOBASE, ch)); + __raw_writel(plhead->dmall.next_lli, DMACH_LLI(DMAIOBASE, ch)); + __raw_writel(plhead->dmall.ctrl, DMACH_CONTROL(DMAIOBASE, ch)); + __raw_writel(config, DMACH_CONFIG_CH(DMAIOBASE, ch)); + __dma_regs_unlock(); + + return 0; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_start_xfer); + +u32 lpc32xx_dma_queue_llist(int ch, void *src, void *dst, + int size, u32 ctrl) +{ + struct dma_list_ctrl *plhead; + + if ((!VALID_CHANNEL(ch)) || (dma_ctrl.dma_channels[ch].name == NULL) || + (dma_ctrl.dma_channels[ch].list_vstart == 0)) + return 0; + + /* Exit if all the buffers are used */ + if (dma_ctrl.dma_channels[ch].free_entries == 0) { + return 0; + } + + /* Next available DMA link descriptor */ + plhead = dma_ctrl.dma_channels[ch].list_curr; + + /* Populate DMA linked data structure */ + plhead->dmall.src = (u32) src; + plhead->dmall.dest = (u32) dst; + plhead->dmall.next_lli = 0; + plhead->dmall.ctrl = ctrl; + + /* Append this link to the end of the previous link */ + plhead->prev_list_addr->dmall.next_lli = lpc32xx_dma_llist_v_to_p(ch, (u32) plhead); + + /* Decrement available buffers */ + dma_ctrl.dma_channels[ch].free_entries--; + + /* Process next link on next call */ + dma_ctrl.dma_channels[ch].list_curr = plhead->next_list_addr; + + return (u32) plhead; +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_queue_llist); + +extern void lpc32xx_dma_force_burst(int ch, int src) +{ + __raw_writel(1 << src, DMA_SW_BURST_REQ(DMAIOBASE)); +} +EXPORT_SYMBOL_GPL(lpc32xx_dma_force_burst); + +static irqreturn_t dma_irq_handler(int irq, void *dev_id) +{ + int i; + unsigned long dint = __raw_readl(DMA_INT_STAT(DMAIOBASE)); + unsigned long tcint = __raw_readl(DMA_INT_TC_STAT(DMAIOBASE)); + unsigned long eint = __raw_readl(DMA_INT_ERR_STAT(DMAIOBASE)); + unsigned long i_bit; + + for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) { + i_bit = 1 << i; + if (dint & i_bit) { + struct dma_channel *channel = &dma_ctrl.dma_channels[i]; + + if (channel->name && channel->irq_handler) { + int cause = 0; + + if (eint & i_bit) { + __raw_writel(i_bit, DMA_INT_ERR_CLEAR(DMAIOBASE)); + cause |= DMA_ERR_INT; + } + if (tcint & i_bit) { + __raw_writel(i_bit, DMA_INT_TC_CLEAR(DMAIOBASE)); + cause |= DMA_TC_INT; + } + + channel->irq_handler(i, cause, channel->data); + } else { + /* + * IRQ for an unregistered DMA channel + */ + __raw_writel(i_bit, DMA_INT_ERR_CLEAR(DMAIOBASE)); + __raw_writel(i_bit, DMA_INT_TC_CLEAR(DMAIOBASE)); + printk(KERN_WARNING + "spurious IRQ for DMA channel %d\n", i); + } + } + } + + return IRQ_HANDLED; +} + +static int __init lpc32xx_dma_init(void) +{ + int ret; + + ret = request_irq(IRQ_LPC32XX_DMA, dma_irq_handler, 0, "DMA", NULL); + if (ret) { + printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n"); + goto out; + } + + /* Get DMA clock */ + dma_ctrl.clk = clk_get(NULL, "clk_dmac"); + if (IS_ERR(dma_ctrl.clk)) { + ret = -ENODEV; + goto errout; + } + clk_enable(dma_ctrl.clk); + + /* Clear DMA controller */ + __raw_writel(1, DMA_CONFIG(DMAIOBASE)); + __raw_writel(0xFF, DMA_INT_TC_CLEAR(DMAIOBASE)); + __raw_writel(0xFF, DMA_INT_ERR_CLEAR(DMAIOBASE)); + + /* Clock is only enabled when needed to save power */ + clk_disable(dma_ctrl.clk); + + return 0; + +errout: + free_irq(IRQ_LPC32XX_DMA, NULL); + +out: + return ret; +} +arch_initcall(lpc32xx_dma_init); diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/ea3250.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/ea3250.c --- linux-2.6.34/arch/arm/mach-lpc32xx/ea3250.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/ea3250.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,907 @@ +/* + * arch/arm/mach-lpc32xx/ea3250.c + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "common.h" + +#include + +#define I2C_PCA9532_ADDR 0x60 +#define I2C_24LC256_ADDR 0x50 + +/* + * Mapped GPIOLIB GPIOs + */ +#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P2_GRP, 1) +#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 11) +#define ADS_TS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 0) +#define NAND_WP_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 19) +#define LCD_CS_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) +#define LCD_RS_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5) +#define BKL_POW_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 14) +#define SSEL0_GPIO5 LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) + +/* + * LCD controller functions + */ +#define SET_RS (gpio_set_value(LCD_RS_GPIO, 1)) +#define RESET_RS (gpio_set_value(LCD_RS_GPIO, 0)) +#define PANEL_SIZE (3 * SZ_64K) + +/* SPI LCDC device structure */ +struct spi_device *ea3250_spi_lcd_dev = NULL; + +/* + * Tick LED + */ +static struct gpio_led phy_leds[] = { + { + .name = "led0", + .gpio = LED_GPIO, + .active_low = 1, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data led_data = { + .leds = phy_leds, + .num_leds = ARRAY_SIZE(phy_leds), +}; + +static struct platform_device lpc32xx_gpio_led_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &led_data, +}; + +/* + * AMBA SSP (SPI) + */ +static struct pl022_ssp_controller lpc32xx_ssp0_data = { + .bus_id = 0, + .num_chipselect = 2, + .enable_dma = 0, +}; + +static struct amba_device lpc32xx_ssp0_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:ssp0", + .platform_data = &lpc32xx_ssp0_data, + }, + .res = { + .start = LPC32XX_SSP0_BASE, + .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, +}; + +/* + * Touchscreen device + */ +/* Touch screen chip select function */ +static void ea3250_spi_cs_set(u32 control) +{ + gpio_set_value(SPI0_CS_GPIO, (int) control); +} + +/* Touch screen SPI parameters */ +static struct pl022_config_chip spi0_chip_info = { + .lbm = LOOPBACK_DISABLED, + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .endian_tx = SSP_TX_LSB, + .endian_rx = SSP_RX_LSB, + .data_size = SSP_DATA_BITS_8, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, + .clk_phase = SSP_CLK_FIRST_EDGE, + .clk_pol = SSP_CLK_POL_IDLE_LOW, + .ctrl_len = SSP_BITS_8, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = ea3250_spi_cs_set, +}; + +/* Touch screen interrupt status function */ +static int ea3250_ads7846_pendown_state(void) +{ + u32 tmp = gpio_get_value(ADS_TS_GPIO); + return (tmp == 0); +} + +/* Touch screen platform data */ +static struct ads7846_platform_data ea_ads7846_platform_data __initdata = { + .debounce_max = 10, + .debounce_tol = 3, + .pressure_max = 1024, + .get_pendown_state = ea3250_ads7846_pendown_state, +}; + +/* + * SPI based LCDC data + */ +/* LCDC chip select function */ +static void ea3250_spi_lcdc_cs_set(u32 control) +{ + gpio_set_value(LCD_CS_GPIO, (int) control); +} + +/* LCDC SPI parameters */ +static struct pl022_config_chip spi0_chip_info1 = { + .lbm = LOOPBACK_DISABLED, + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .endian_tx = SSP_TX_LSB, + .endian_rx = SSP_RX_LSB, + .data_size = SSP_DATA_BITS_8, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, + .clk_phase = SSP_CLK_FIRST_EDGE, + .clk_pol = SSP_CLK_POL_IDLE_LOW, + .ctrl_len = SSP_BITS_8, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = ea3250_spi_lcdc_cs_set, +}; + +/* SPI devices registration */ +static int __init ea3250_spi_devices_register(void) +{ +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + static struct spi_board_info info[] = { + { + .modalias = "spidev", + .max_speed_hz = 2500000, + .bus_num = 0, + .chip_select = 0, + .controller_data = &spi0_chip_info, + }, + }; +#else + struct spi_board_info info[] = { + { + .modalias = "ads7846", + .max_speed_hz = 2500000, + .chip_select = 0, + .irq = IRQ_LPC32XX_GPIO_00, + .platform_data = &ea_ads7846_platform_data, + .controller_data = &spi0_chip_info, + }, + { + .modalias = "ea3250_lcdc", + .max_speed_hz = 10000000, + .chip_select = 1, + .controller_data = &spi0_chip_info1, + }, + }; +#endif + + /* Configure ADS TS INT GPIO pin as input */ + if (gpio_request(ADS_TS_GPIO, "ADS7846 TS INT")) + return -EIO; + if(gpio_direction_input(ADS_TS_GPIO)) + return -EIO; + + /* Configure LCDC CS GPIO pin */ + if (gpio_request(LCD_CS_GPIO, "LCDC CS")) + return -EIO; + if(gpio_direction_output(LCD_CS_GPIO, 1)) + return -EIO; + + return spi_register_board_info(info, ARRAY_SIZE(info)); +} +arch_initcall(ea3250_spi_devices_register); + +#if defined (CONFIG_FB_ARMCLCD) +/* + * LCDC AMBA Driver Board Functions + */ +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) +/* + * Support for Embedded Artists 3.2 inch QVGA LCD panel + */ +static struct clcd_panel conn_lcd_panel = { + .mode = { + .name = "QVGA portrait", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 121654, + .left_margin = 28, + .right_margin = 10, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 2, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = (TIM2_IVS | TIM2_IHS), + .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) | + CNTL_LCDBPP16_565), + .bpp = 16, +}; + +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) +/* + * Support for Embedded Artists 2.8 inch QVGA OLED panel +*/ +static struct clcd_panel conn_lcd_panel = { + .mode = { + .name = "QVGA portrait", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 176366, + .left_margin = 33, + .right_margin = 26, + .upper_margin = 3, + .lower_margin = 8, + .hsync_len = 32, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = (TIM2_IVS | TIM2_IHS), + .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) | + CNTL_LCDBPP16_565), + .bpp = 16, +}; +#endif + +static int lpc32xx_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, + PANEL_SIZE, &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = PANEL_SIZE; + fb->panel = &conn_lcd_panel; + + if (gpio_request(SSEL0_GPIO5, "Unused GPIO5 input")) + return -EIO; + if(gpio_direction_input(SSEL0_GPIO5)) + return -EIO; + + /* Configure LCDC RS GPIO pin */ + if (gpio_request(LCD_RS_GPIO, "LCDC RS")) + return -EIO; + + if(gpio_direction_output(LCD_RS_GPIO, 1)) + return -EIO; + + /* Configure LCDC Backlight GPIO pin */ + if (gpio_request(BKL_POW_GPIO, "LCDC BKL")) + return -EIO; + +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + if(gpio_direction_output(BKL_POW_GPIO, 0)) { +#else + if(gpio_direction_output(BKL_POW_GPIO, 1)) { +#endif + return -EIO; + } + + return 0; +} + +static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void lpc32xx_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static void spiSend(u8 *buf, size_t len) +{ + BUG_ON(ea3250_spi_lcd_dev == NULL); + spi_write(ea3250_spi_lcd_dev, buf, len); +} + +#if defined (CONFIG_EA3250_QVGA_2_8_OLED) +static void writeToDisp(u16 data) +{ + u8 buf[3]; + + /* Initiliase buffer */ + buf[0] = 0x72; + buf[1] = data >> 8; + buf[2] = data & 0xff; + spiSend(buf, 3); +} +#endif + +static void writeToReg(u16 addr, u16 data) +{ + u8 buf[3]; + +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + RESET_RS; + buf[0] = 0x00; + buf[1] = addr & 0xff; + spiSend(buf, 2); + + SET_RS; + buf[0] = data >> 8; + buf[1] = data & 0xff; + spiSend(buf, 2); + + RESET_RS; + buf[0] = 0x00; + buf[1] = 0x22; + spiSend(buf, 2); +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) + buf[0] = 0x70; + buf[1] = data >> 8; + buf[2] = data & 0xff; + spiSend(buf, 3); +#endif + +} + +static void clcd_display_init(void) +{ + u32 tmp; + + /* setup MUX register to use SSP0 */ + __raw_writel(( _BIT(12) | _BIT(10) | _BIT(9) ), LPC32XX_GPIO_P_MUX_SET); + tmp = __raw_readl(LPC32XX_GPIO_P_MUX_SET); + +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + + writeToReg (0x00,0x0001); + mdelay(20); + writeToReg (0x03,0xA2A4); + writeToReg (0x0C,0x0004); + writeToReg (0x0D,0x0308); + writeToReg (0x0E,0x3000); + mdelay(50); + writeToReg (0x1E,0x00AF); + writeToReg (0x01,0x2B3F); + writeToReg (0x02,0x0600); + writeToReg (0x10,0x0000); + writeToReg (0x07,0x0233); + writeToReg (0x0B,0x0039); + writeToReg (0x0F,0x0000); + mdelay(50); + + writeToReg (0x30,0x0707); + writeToReg (0x31,0x0204); + writeToReg (0x32,0x0204); + writeToReg (0x33,0x0502); + writeToReg (0x34,0x0507); + writeToReg (0x35,0x0204); + writeToReg (0x36,0x0204); + writeToReg (0x37,0x0502); + writeToReg (0x3A,0x0302); + writeToReg (0x3B,0x0302); + + writeToReg (0x23,0x0000); + writeToReg (0x24,0x0000); + + writeToReg (0x48,0x0000); + writeToReg (0x49,0x013F); + writeToReg (0x4A,0x0000); + writeToReg (0x4B,0x0000); + + writeToReg (0x41,0x0000); + writeToReg (0x42,0x0000); + + writeToReg (0x44,0xEF00); + writeToReg (0x45,0x0000); + writeToReg (0x46,0x013F); + mdelay(50); + + writeToReg (0x44,0xEF00); + writeToReg (0x45,0x0000); + writeToReg (0x4E,0x0000); + writeToReg (0x4F,0x0000); + writeToReg (0x46,0x013F); + +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) + + writeToReg(0,0x02); + writeToDisp(0x0192); + + writeToReg(0,0x03); + writeToDisp(0x0130); + + /* set standby off */ + writeToReg(0,0x10); + writeToDisp(0x0000); + + mdelay(100); + + /* set display on */ + writeToReg(0,0x05); + writeToDisp(0x0001); + + /* enable image data transfer */ + writeToReg(0,0x22); +#endif +} + +void clcd_disable(struct clcd_fb *fb) +{ + /* Disable the backlight */ +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + gpio_set_value(BKL_POW_GPIO, 1); +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) + gpio_set_value(BKL_POW_GPIO, 0); +#endif +} + +void clcd_enable(struct clcd_fb *fb) +{ + clcd_display_init(); + + /* Enable the backlight */ +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + gpio_set_value(BKL_POW_GPIO, 0); +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) + gpio_set_value(BKL_POW_GPIO, 1); +#endif + +} + +struct clcd_board lpc32xx_clcd_data = { +#if defined (CONFIG_EA3250_QVGA_3_2_LCD) + .name = "Embedded Artists 3.2 inch LCD", +#elif defined (CONFIG_EA3250_QVGA_2_8_OLED) + .name = "Embedded Artists 2.8 inch OLED", +#else + .name = "Unknown Display", +#endif + .check = clcdfb_check, + .decode = clcdfb_decode, + .disable = clcd_disable, + .enable = clcd_enable, + .setup = lpc32xx_clcd_setup, + .mmap = lpc32xx_clcd_mmap, + .remove = lpc32xx_clcd_remove, +}; + +struct amba_device lpc32xx_clcd_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:clcd", + .platform_data = &lpc32xx_clcd_data, + }, + .res = { + .start = LPC32XX_LCD_BASE, + .end = (LPC32XX_LCD_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_LCD, NO_IRQ}, +}; +#endif + +/* + * SPI LCDC Driver Probe function + */ +static int ea3250_spi_lcdc_probe(struct spi_device *spi) +{ + int err; + + spi->mode = SPI_MODE_0; + ea3250_spi_lcd_dev = spi; + + /* SPI settings */ + err = spi_setup(spi); + if (err < 0) { + dev_err(&spi->dev, "Err in setting SPI \n"); + return err; + } + return 0; +} + +/* + * * SPI LCDC Driver remove function + * * */ +static int ea3250_spi_lcdc_remove(struct spi_device *spi) +{ + return 0; +} + +static struct spi_driver ea3250_spi_lcdc_driver = { + .driver = { + .name = "ea3250_lcdc", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ea3250_spi_lcdc_probe, + .remove = __devexit_p(ea3250_spi_lcdc_remove), +}; + +void __init ea3250_spi_lcdc_drv_init(void) +{ + spi_register_driver(&ea3250_spi_lcdc_driver); +} + +/* AMBA based devices list */ +static struct amba_device *amba_devs[] __initdata = { + &lpc32xx_ssp0_device, +#if defined (CONFIG_FB_ARMCLCD) + &lpc32xx_clcd_device, +#endif +}; + +/* + * Register AMBA BUS Devices. + * Call AMBA device restration after SPI driver probe(), + * as LCD controller uses SPI driver for initialization + */ +static int __init ea3250_amba_devices_register(void) +{ + u32 i = 0; + + /* Add AMBA devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + return 0; +} +device_initcall_sync(ea3250_amba_devices_register); + +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) +/* + * * Board specific NAND setup data + * */ +static int nandwp_enable(int enable) +{ + if (enable != 0) + gpio_set_value(NAND_WP_GPIO,0); + else + gpio_set_value(NAND_WP_GPIO,1); + + return 1; +} +#define BLK_SIZE (2048 * 64) +static struct mtd_partition __initdata ea3250_nand_partition[] = { + { + .name = "ea3250-boot", + .offset = 0, + .size = (BLK_SIZE * 25) + }, + { + .name = "ea3250-uboot", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 100) + }, + { + .name = "ea3250-ubt-prms", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 2) + }, + { + .name = "ea3250-kernel", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 32) + }, + { + .name = "ea3250-jffs2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; +static struct mtd_partition * __init ea3250_nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ea3250_nand_partition); + return ea3250_nand_partition; +} +struct lpc32XX_nand_cfg lpc32xx_nandcfg = +{ + .wdr_clks = 14, + .wwidth = 260000000, + .whold = 104000000, + .wsetup = 200000000, + .rdr_clks = 14, + .rwidth = 34666666, + .rhold = 104000000, + .rsetup = 200000000, + .use16bus = 0, + .enable_write_prot = nandwp_enable, + .partition_info = ea3250_nand_partitions, +}; + +/* + * * SLC NAND resources + * */ +static struct resource slc_nand_resources[] = { + [0] = { + .start = LPC32XX_SLC_BASE, + .end = LPC32XX_SLC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_FLASH, + .end = IRQ_LPC32XX_FLASH, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_slc_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_slc_nand_device = { + .name = "lpc32xx-nand", + .id = 0, + .dev = { + .platform_data = &lpc32xx_nandcfg, + .dma_mask = &lpc32xx_slc_dma_mask, + .coherent_dma_mask = ~0UL, + + }, + .num_resources = ARRAY_SIZE(slc_nand_resources), + .resource = slc_nand_resources, +}; +#endif + +/* + * Network Support + */ +static struct lpc_net_cfg lpc32xx_netdata = +{ + .phy_irq = -1, + .phy_mask = 0xFFFFFFF0, +}; + +static struct resource net_resources[] = { + [0] = { + .start = LPC32XX_ETHERNET_BASE, + .end = LPC32XX_ETHERNET_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_ETHERNET, + .end = IRQ_LPC32XX_ETHERNET, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_net_device = { + .name = "lpc-net", + .id = 0, + .dev = { + .dma_mask = &lpc32xx_mac_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &lpc32xx_netdata, + }, + .num_resources = ARRAY_SIZE(net_resources), + .resource = net_resources, +}; + +/* + * I2C devices support + */ +#if defined (CONFIG_SENSORS_PCA9532) || defined (CONFIG_AT24) + static struct i2c_board_info __initdata ea3250_i2c_board_info [] = { +#if defined (CONFIG_SENSORS_PCA9532) + { + I2C_BOARD_INFO("pca9532", I2C_PCA9532_ADDR), + + }, +#endif +#if defined (CONFIG_AT24) + { + I2C_BOARD_INFO("24c256", I2C_24LC256_ADDR), + }, +#endif + }; +#endif + +static struct platform_device* ea3250_devs[] __initdata = { + &lpc32xx_i2c0_device, + &lpc32xx_i2c1_device, + &lpc32xx_i2c2_device, + &lpc32xx_watchdog_device, + &lpc32xx_gpio_led_device, + &lpc32xx_rtc_device, + &lpc32xx_net_device, +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) + &lpc32xx_slc_nand_device, +#endif +#if defined(CONFIG_USB_OHCI_HCD) + &lpc32xx_ohci_device, +#endif +#if defined(CONFIG_USB_GADGET_LPC32XX) + &lpc32xx_usbd_device, +#endif +}; + +extern void __init ea3250_spi_lcdc_drv_init(void); + +/* + * Board specific functions + */ +void __init ea3250_board_init(void) +{ + u32 tmp; + + /* Intiliase GPIO */ + lpc32xx_gpio_init(); + + /* Set SPI CS GPIO to output */ + gpio_request(SPI0_CS_GPIO, "spi0 cs"); + gpio_direction_output(SPI0_CS_GPIO, 1); + + /* Setup network interface for RMII mode */ + tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); + + /* Setup SLC NAND controller */ + __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, + LPC32XX_CLKPWR_NAND_CLK_CTRL); + + /* Setup LCD muxing to RGB565 */ + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) & + ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK | + LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK); + tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; + __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); + + /* Set up I2C pull levels */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); + tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | + LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE; + __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); + + /* Enable DMA for I2S1 channel */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); + tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA; + __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL); + + /* Initalise Serial device */ + lpc32xx_serial_init(); + + /* + * AMBA peripheral clocks need to be enabled prior to AMBA device + * detection or a data fault will occur, so enable the clocks + * here. However, we don't want to enable them if the peripheral + * isn't included in the image + */ + /* Initialise SSP clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), + LPC32XX_CLKPWR_SSP_CLK_CTRL); + + /* Initialise LCD clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), + LPC32XX_CLKPWR_LCDCLK_CTRL); + + /* Enable SD card clock so AMBA driver will work correctly. The + AMBA driver needs the clock before the SD card controller + driver initializes it. The clock will turn off once the driver + has been initialized. */ + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | + LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + + /* Disable UART5->USB transparent mode or USB won't work */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + + /* Add platform devcies */ + platform_add_devices(ea3250_devs, ARRAY_SIZE(ea3250_devs)); + + /* Register SPI driver */ + ea3250_spi_lcdc_drv_init(); + + /* Test clock needed for UDA1380 initial init */ + __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | + LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, + LPC32XX_CLKPWR_TEST_CLK_SEL); + +#if defined (CONFIG_SENSORS_PCA9532) || defined (CONFIG_AT24) + i2c_register_board_info(0, ea3250_i2c_board_info, + ARRAY_SIZE(ea3250_i2c_board_info)); +#endif +} + +static int __init lpc32xx_display_uid(void) +{ + u32 uid[4]; + + lpc32xx_get_uid(uid); + + printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", + uid[3], uid[2], uid[1], uid[0]); + + return 1; +} +arch_initcall(lpc32xx_display_uid); + +MACHINE_START (EA3250, "Embedded Artists LPC3250 OEM board with the LPC3250 Microcontroller") + /* Maintainer: Embedded Artists */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = ea3250_board_init, + MACHINE_END + +/* For backwards compatibility with older bootloaders only */ +MACHINE_START (LPC3XXX, "Embedded Artists LPC3250 OEM board with the LPC3250 Microcontroller") + /* Maintainer: Embedded Artists */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = ea3250_board_init, + MACHINE_END diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/fdi3250.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/fdi3250.c --- linux-2.6.34/arch/arm/mach-lpc32xx/fdi3250.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/fdi3250.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,560 @@ +/* + * arch/arm/mach-lpc32xx/fdi3250.c + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "common.h" + +/* + * Mapped GPIOLIB GPIOs + */ +#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 3) +#define SPI_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) +#define NAND_WP_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 19) + +/* + * Tick LED + */ +static struct gpio_led phy_leds[] = { + { + .name = "led0", + .gpio = LED_GPIO, + .active_low = 1, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data led_data = { + .leds = phy_leds, + .num_leds = ARRAY_SIZE(phy_leds), +}; + +static struct platform_device lpc32xx_gpio_led_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &led_data, +}; + +/* + * AMBA SSP (SPI) + */ +static struct pl022_ssp_controller lpc32xx_ssp0_data = { + .bus_id = 0, + .num_chipselect = 2, + .enable_dma = 0, +}; + +static struct amba_device lpc32xx_ssp0_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:ssp0", + .platform_data = &lpc32xx_ssp0_data, + }, + .res = { + .start = LPC32XX_SSP0_BASE, + .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, +}; + +/* SPIDEV chip select function */ +static void fdi3250_spi_cs_set(u32 control) +{ + gpio_set_value(SPI_CS_GPIO, (int) control); +} + +/* SPIDEV parameters */ +static struct pl022_config_chip spi0_chip_info = { + .lbm = LOOPBACK_DISABLED, + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .endian_tx = SSP_TX_LSB, + .endian_rx = SSP_RX_LSB, + .data_size = SSP_DATA_BITS_8, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, + .clk_phase = SSP_CLK_FIRST_EDGE, + .clk_pol = SSP_CLK_POL_IDLE_LOW, + .ctrl_len = SSP_BITS_8, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = fdi3250_spi_cs_set, +}; + +/* SPI devices registration */ +static int __init fdi3250_spi_devices_register(void) +{ + static struct spi_board_info info[] = { + { + .modalias = "spidev", + .max_speed_hz = 2500000, + .bus_num = 0, + .chip_select = 0, + .controller_data = &spi0_chip_info, + }, + }; + + return spi_register_board_info(info, ARRAY_SIZE(info)); +} +arch_initcall(fdi3250_spi_devices_register); + +#if defined (CONFIG_FB_ARMCLCD) +/* + * Board specific LCD setup and functions + */ +#if defined (CONFIG_SOM9DIMM3250_LCD_PANEL) +/* + * Support for QVGA portrait panel + */ +#if defined (CONFIG_SOM9DIMM3250_LCD_TOSHIBA_QVGA_35) +static struct clcd_panel conn_lcd_panel = { + .mode = { + .name = "QVGA portrait", + .refresh = 30, + .xres = 320, + .yres = 240, + .pixclock = 158730, + .left_margin = 11, + .right_margin = 0, + .upper_margin = 7, + .lower_margin = 7, + .hsync_len = 69, + .vsync_len = 45, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = 0, + .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) | + CNTL_LCDBPP16_565), + .bpp = 16, +}; +#define PANEL_SIZE (3 * SZ_64K) +#endif +#if defined (CONFIG_SOM9DIMM3250_LCD_OKAYA_VGA_35) +static struct clcd_panel conn_lcd_panel = { + .mode = { + .name = "VGA portrait", + .refresh = 30, + .xres = 640, + .yres = 480, + .pixclock = 41666, + .left_margin = 10, + .right_margin = 120, + .upper_margin = 7, + .lower_margin = 35, + .hsync_len = 30, + .vsync_len = 3, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = 0, + .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) | + CNTL_LCDBPP16_565), + .bpp = 16, +}; +#define PANEL_SIZE (10 * SZ_64K) +#endif + +#endif // CONFIG_SOM9DIMM3250_LCD_PANEL + +static int lpc32xx_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, + PANEL_SIZE, &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = PANEL_SIZE; + fb->panel = &conn_lcd_panel; + + return 0; +} + +static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void lpc32xx_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +void clcd_disable(struct clcd_fb *fb) +{ + __raw_writel(0x00000000, io_p2v(LPC32XX_PWM1_BASE)); +} + +void clcd_enable(struct clcd_fb *fb) +{ + __raw_writel(0x40000000, io_p2v(LPC32XX_PWM1_BASE)); +} + +struct clcd_board lpc32xx_clcd_data = { +#if defined (CONFIG_SOM9DIMM3250_LCD_TOSHIBA_QVGA_35) + .name = "Toshiba 3.5 inch LCD", +#elif defined (CONFIG_SOM9DIMM3250_LCD_OKAYA_VGA_35) + .name = "Okaya 3.5 inch LCD", +#else + .name = "Unknown Display", +#endif + .check = clcdfb_check, + .decode = clcdfb_decode, + .disable = clcd_disable, + .enable = clcd_enable, + .setup = lpc32xx_clcd_setup, + .mmap = lpc32xx_clcd_mmap, + .remove = lpc32xx_clcd_remove, +}; + +struct amba_device lpc32xx_clcd_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:clcd", + .platform_data = &lpc32xx_clcd_data, + }, + .res = { + .start = LPC32XX_LCD_BASE, + .end = (LPC32XX_LCD_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_LCD, NO_IRQ}, +}; +#endif + +/* AMBA based devices list */ +static struct amba_device *amba_devs[] __initdata = { + &lpc32xx_ssp0_device, +#if defined (CONFIG_FB_ARMCLCD) + &lpc32xx_clcd_device, +#endif +}; + +/* + * Register AMBA BUS Devices. + * Call AMBA device restration after SPI driver probe(), + * as LCD controller uses SPI driver for initialization + */ +static int __init fdi3250_amba_devices_register(void) +{ + u32 i = 0; + + /* Add AMBA devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + return 0; +} +device_initcall_sync(fdi3250_amba_devices_register); + +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) +/* + * * Board specific NAND setup data + * */ +static int nandwp_enable(int enable) +{ + if (enable != 0) + gpio_set_value(NAND_WP_GPIO,0); + else + gpio_set_value(NAND_WP_GPIO,1); + + return 1; +} +#define BLK_SIZE (2048 * 64) +static struct mtd_partition __initdata fdi3250_nand_partition[] = { + { + .name = "fdi3250-boot", + .offset = 0, + .size = (BLK_SIZE * 25) + }, + { + .name = "fdi3250-uboot", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 102) + }, + { + .name = "fdi3250-kernel", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 32) + }, + { + .name = "fdi3250-jffs2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; +static struct mtd_partition * __init fdi3250_nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(fdi3250_nand_partition); + return fdi3250_nand_partition; +} +struct lpc32XX_nand_cfg lpc32xx_nandcfg = +{ + .wdr_clks = 14, + .wwidth = 260000000, + .whold = 104000000, + .wsetup = 200000000, + .rdr_clks = 14, + .rwidth = 34666666, + .rhold = 104000000, + .rsetup = 200000000, + .use16bus = 0, + .enable_write_prot = nandwp_enable, + .partition_info = fdi3250_nand_partitions, +}; + +/* + * * SLC NAND resources + * */ +static struct resource slc_nand_resources[] = { + [0] = { + .start = LPC32XX_SLC_BASE, + .end = LPC32XX_SLC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_FLASH, + .end = IRQ_LPC32XX_FLASH, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_slc_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_slc_nand_device = { + .name = "lpc32xx-nand", + .id = 0, + .dev = { + .platform_data = &lpc32xx_nandcfg, + .dma_mask = &lpc32xx_slc_dma_mask, + .coherent_dma_mask = ~0UL, + + }, + .num_resources = ARRAY_SIZE(slc_nand_resources), + .resource = slc_nand_resources, +}; +#endif + +/* + * Network Support + */ +static struct lpc_net_cfg lpc32xx_netdata = +{ + .phy_irq = -1, + .phy_mask = 0xFFFFFFF0, +}; + +static struct resource net_resources[] = { + [0] = { + .start = LPC32XX_ETHERNET_BASE, + .end = LPC32XX_ETHERNET_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_ETHERNET, + .end = IRQ_LPC32XX_ETHERNET, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_net_device = { + .name = "lpc-net", + .id = 0, + .dev = { + .dma_mask = &lpc32xx_mac_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &lpc32xx_netdata, + }, + .num_resources = ARRAY_SIZE(net_resources), + .resource = net_resources, +}; + +static struct platform_device* fdi3250_devs[] __initdata = { + &lpc32xx_i2c0_device, + &lpc32xx_i2c1_device, + &lpc32xx_i2c2_device, + &lpc32xx_watchdog_device, + &lpc32xx_gpio_led_device, + &lpc32xx_rtc_device, + &lpc32xx_net_device, +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) + &lpc32xx_slc_nand_device, +#endif +#if defined(CONFIG_USB_OHCI_HCD) + &lpc32xx_ohci_device, +#endif +#if defined(CONFIG_USB_GADGET_LPC32XX) + &lpc32xx_usbd_device, +#endif +}; + +/* + * Board specific functions + */ +void __init fdi3250_board_init(void) +{ + u32 tmp; + + /* Intiliase GPIO */ + lpc32xx_gpio_init(); + + /* Set SPI CS GPIO to output */ + gpio_request(SPI_CS_GPIO, "spi0 cs"); + gpio_direction_output(SPI_CS_GPIO, 1); + + gpio_request(NAND_WP_GPIO, "NAND WP GPIO"); + gpio_direction_input(NAND_WP_GPIO); + + /* Setup network interface for RMII mode */ + tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); + + /* Setup SLC NAND controller */ + __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, + LPC32XX_CLKPWR_NAND_CLK_CTRL); + + /* Setup LCD muxing to RGB565 */ + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) & + ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK | + LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK); + tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; + __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); + + /* Set up I2C pull levels */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); + tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | + LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE; + __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); + + /* Initalise Serial device */ + lpc32xx_serial_init(); + + /* + * AMBA peripheral clocks need to be enabled prior to AMBA device + * detection or a data fault will occur, so enable the clocks + * here. However, we don't want to enable them if the peripheral + * isn't included in the image + */ + /* Initialise SSP clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), + LPC32XX_CLKPWR_SSP_CLK_CTRL); + + /* Initialise LCD clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), + LPC32XX_CLKPWR_LCDCLK_CTRL); + + /* Enable SD card clock so AMBA driver will work correctly. The + AMBA driver needs the clock before the SD card controller + driver initializes it. The clock will turn off once the driver + has been initialized. */ + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | + LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + + /* Disable UART5->USB transparent mode or USB won't work */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + + /* Add platform devcies */ + platform_add_devices(fdi3250_devs, ARRAY_SIZE(fdi3250_devs)); +} + +static int __init lpc32xx_display_uid(void) +{ + u32 uid[4]; + + lpc32xx_get_uid(uid); + + printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", + uid[3], uid[2], uid[1], uid[0]); + + return 1; +} +arch_initcall(lpc32xx_display_uid); + +MACHINE_START (FDI3250, "Future Designs board with the LPC3250 Microcontroller") + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_HS_UART1_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = fdi3250_board_init, + MACHINE_END + +/* For backwards compatibility with older bootloaders only */ +MACHINE_START (LPC3XXX, "Future Designs board with the LPC3250 Microcontroller") + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_HS_UART1_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = fdi3250_board_init, + MACHINE_END diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/gpiolib.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/gpiolib.c --- linux-2.6.34/arch/arm/mach-lpc32xx/gpiolib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/gpiolib.c 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,446 @@ +/* + * arch/arm/mach-lpc32xx/gpiolib.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "common.h" + +#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) +#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) +#define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) +#define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) +#define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) +#define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) +#define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) +#define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) +#define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) +#define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) +#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) +#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) +#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) +#define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) +#define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) +#define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) +#define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) +#define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) +#define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) +#define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) +#define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) +#define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) +#define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) +#define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) +#define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) +#define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) +#define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) + +#define GPIO012_PIN_TO_BIT(x) (1 << (x)) +#define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) +#define GPO3_PIN_TO_BIT(x) (1 << (x)) +#define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) +#define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x)) +#define GPIO3_PIN_IN_SEL(x, y) (((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1) +#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1) +#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) + +struct gpio_regs { + void __iomem *inp_state; + void __iomem *outp_set; + void __iomem *outp_clr; + void __iomem *dir_set; + void __iomem *dir_clr; +}; + +/* + * GPIO names + */ +static char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = { + "p0.0", "p0.1", "p0.2", "p0.3", + "p0.4", "p0.5", "p0.6", "p0.7" +}; + +static char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = { + "p1.0", "p1.1", "p1.2", "p1.3", + "p1.4", "p1.5", "p1.6", "p1.7", + "p1.8", "p1.9", "p1.10", "p1.11", + "p1.12", "p1.13", "p1.14", "p1.15", + "p1.16", "p1.17", "p1.18", "p1.19", + "p1.20", "p1.21", "p1.22", "p1.23", +}; + +static char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = { + "p2.0", "p2.1", "p2.2", "p2.3", + "p2.4", "p2.5", "p2.6", "p2.7", + "p2.8", "p2.9", "p2.10", "p2.11", + "p2.12" +}; + +static char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = { + "gpi000", "gpio01", "gpio02", "gpio03", + "gpio04", "gpio05" +}; + +static char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = { + "gpi00", "gpi01", "gpi02", "gpi03", + "gpi04", "gpi05", "gpi06", "gpi07", + "gpi08", "gpi09", NULL, NULL, + NULL, NULL, NULL, "gpi15", + "gpi16", "gpi17", "gpi18", "gpi19", + "gpi20", "gpi21", "gpi22", "gpi23", + "gpi24", "gpi25", "gpi26", "gpi27" +}; + +static char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = { + "gpo00", "gpo01", "gpo02", "gpo03", + "gpo04", "gpo05", "gpo06", "gpo07", + "gpo08", "gpo09", "gpo10", "gpo11", + "gpo12", "gpo13", "gpo14", "gpo15", + "gpo16", "gpo17", "gpo18", "gpo19", + "gpo20", "gpo21", "gpo22", "gpo23" +}; + +static struct gpio_regs gpio_grp_regs_p0 = { + .inp_state = LPC32XX_GPIO_P0_INP_STATE, + .outp_set = LPC32XX_GPIO_P0_OUTP_SET, + .outp_clr = LPC32XX_GPIO_P0_OUTP_CLR, + .dir_set = LPC32XX_GPIO_P0_DIR_SET, + .dir_clr = LPC32XX_GPIO_P0_DIR_CLR, +}; + +static struct gpio_regs gpio_grp_regs_p1 = { + .inp_state = LPC32XX_GPIO_P1_INP_STATE, + .outp_set = LPC32XX_GPIO_P1_OUTP_SET, + .outp_clr = LPC32XX_GPIO_P1_OUTP_CLR, + .dir_set = LPC32XX_GPIO_P1_DIR_SET, + .dir_clr = LPC32XX_GPIO_P1_DIR_CLR, +}; + +static struct gpio_regs gpio_grp_regs_p2 = { + .inp_state = LPC32XX_GPIO_P2_INP_STATE, + .outp_set = LPC32XX_GPIO_P2_OUTP_SET, + .outp_clr = LPC32XX_GPIO_P2_OUTP_CLR, + .dir_set = LPC32XX_GPIO_P2_DIR_SET, + .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, +}; + +static struct gpio_regs gpio_grp_regs_p3 = { + .inp_state = LPC32XX_GPIO_P3_INP_STATE, + .outp_set = LPC32XX_GPIO_P3_OUTP_SET, + .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR, + .dir_set = LPC32XX_GPIO_P2_DIR_SET, + .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, +}; + +struct lpc32xx_gpio_chip { + struct gpio_chip chip; + struct gpio_regs *gpio_grp; +}; + +static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio( + struct gpio_chip *gpc) +{ + return container_of(gpc, struct lpc32xx_gpio_chip, chip); +} + +static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, + unsigned pin, int input) +{ + if (input) + __raw_writel(GPIO012_PIN_TO_BIT(pin), + group->gpio_grp->dir_clr); + else + __raw_writel(GPIO012_PIN_TO_BIT(pin), + group->gpio_grp->dir_set); +} + +static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group, + unsigned pin, int input) +{ + u32 u = GPIO3_PIN_TO_BIT(pin); + + if (input) + __raw_writel(u, group->gpio_grp->dir_clr); + else + __raw_writel(u, group->gpio_grp->dir_set); +} + +static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, + unsigned pin, int high) +{ + if (high) + __raw_writel(GPIO012_PIN_TO_BIT(pin), + group->gpio_grp->outp_set); + else + __raw_writel(GPIO012_PIN_TO_BIT(pin), + group->gpio_grp->outp_clr); +} + +static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group, + unsigned pin, int high) +{ + u32 u = GPIO3_PIN_TO_BIT(pin); + + if (high) + __raw_writel(u, group->gpio_grp->outp_set); + else + __raw_writel(u, group->gpio_grp->outp_clr); +} + +static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, + unsigned pin, int high) +{ + if (high) + __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); + else + __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); +} + +static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, + unsigned pin) +{ + return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), + pin); +} + +static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, + unsigned pin) +{ + int state = __raw_readl(group->gpio_grp->inp_state); + + /* + * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped + * to bits 10..14, while GPIOP3-5 is mapped to bit 24. + */ + return GPIO3_PIN_IN_SEL(state, pin); +} + +static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, + unsigned pin) +{ + return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); +} + +/* + * GENERIC_GPIO primitives. + */ +static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip, + unsigned pin) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_dir_p012(group, pin, 1); + + return 0; +} + +static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip, + unsigned pin) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_dir_p3(group, pin, 1); + + return 0; +} + +static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip, + unsigned pin) +{ + return 0; +} + +static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + return __get_gpio_state_p012(group, pin); +} + +static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + return __get_gpio_state_p3(group, pin); +} + +static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + return __get_gpi_state_p3(group, pin); +} + +static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin, + int value) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_dir_p012(group, pin, 0); + + return 0; +} + +static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin, + int value) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_dir_p3(group, pin, 0); + + return 0; +} + +static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin, + int value) +{ + return 0; +} + +static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin, + int value) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_level_p012(group, pin, value); +} + +static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin, + int value) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpio_level_p3(group, pin, value); +} + +static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin, + int value) +{ + struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); + + __set_gpo_level_p3(group, pin, value); +} + +static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) +{ + if (pin < chip->ngpio) + return 0; + + return -EINVAL; +} + +static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { + { + .chip = { + .label = "gpio_p0", + .direction_input = lpc32xx_gpio_dir_input_p012, + .get = lpc32xx_gpio_get_value_p012, + .direction_output = lpc32xx_gpio_dir_output_p012, + .set = lpc32xx_gpio_set_value_p012, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPIO_P0_GRP, + .ngpio = LPC32XX_GPIO_P0_MAX, + .names = gpio_p0_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p0, + }, + { + .chip = { + .label = "gpio_p1", + .direction_input = lpc32xx_gpio_dir_input_p012, + .get = lpc32xx_gpio_get_value_p012, + .direction_output = lpc32xx_gpio_dir_output_p012, + .set = lpc32xx_gpio_set_value_p012, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPIO_P1_GRP, + .ngpio = LPC32XX_GPIO_P1_MAX, + .names = gpio_p1_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p1, + }, + { + .chip = { + .label = "gpio_p2", + .direction_input = lpc32xx_gpio_dir_input_p012, + .get = lpc32xx_gpio_get_value_p012, + .direction_output = lpc32xx_gpio_dir_output_p012, + .set = lpc32xx_gpio_set_value_p012, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPIO_P2_GRP, + .ngpio = LPC32XX_GPIO_P2_MAX, + .names = gpio_p2_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p2, + }, + { + .chip = { + .label = "gpio_p3", + .direction_input = lpc32xx_gpio_dir_input_p3, + .get = lpc32xx_gpio_get_value_p3, + .direction_output = lpc32xx_gpio_dir_output_p3, + .set = lpc32xx_gpio_set_value_p3, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPIO_P3_GRP, + .ngpio = LPC32XX_GPIO_P3_MAX, + .names = gpio_p3_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p3, + }, + { + .chip = { + .label = "gpi_p3", + .direction_input = lpc32xx_gpio_dir_in_always, + .get = lpc32xx_gpi_get_value, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPI_P3_GRP, + .ngpio = LPC32XX_GPI_P3_MAX, + .names = gpi_p3_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p3, + }, + { + .chip = { + .label = "gpo_p3", + .direction_output = lpc32xx_gpio_dir_out_always, + .set = lpc32xx_gpo_set_value, + .request = lpc32xx_gpio_request, + .base = LPC32XX_GPO_P3_GRP, + .ngpio = LPC32XX_GPO_P3_MAX, + .names = gpo_p3_names, + .can_sleep = 0, + }, + .gpio_grp = &gpio_grp_regs_p3, + }, +}; + +void __init lpc32xx_gpio_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) + gpiochip_add(&lpc32xx_gpiochip[i].chip); +} diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/board.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/board.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/board.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/board.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,77 @@ +/* + * arm/arch/mach-lpc32xx/include/mach/board.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef __ASM_ARCH_BOARD_H +#define __ASM_ARCH_BOARD_H + +#include "platform.h" +#include + +/* + * NAND platform configuration structure +*/ +typedef int (*en_wp)(int); +struct lpc32XX_nand_cfg +{ + u32 wdr_clks; + u32 wwidth; + u32 whold; + u32 wsetup; + u32 rdr_clks; + u32 rwidth; + u32 rhold; + u32 rsetup; + int use16bus; /* 0 = 8-bit, !0 = not support */ + en_wp enable_write_prot; + struct mtd_partition* (*partition_info)(int, int*); +}; + +/* + * Key scanner platform configuration structure + */ +struct lpc32XX_kscan_cfg { + u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */ + int *keymap; /* Pointer to key map for the scan matrix */ + u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */ + u32 scan_delay; /* Scan delay (based on 32KHz clock) */ +}; + +/* + * Network configuration structure + */ +struct lpc_net_cfg { + int phy_irq; /* PHY IRQ number, or -1 for polling */ + u32 phy_mask; /* PHY mask value */ +}; + +/* + * USB device configuration structure + */ +typedef void (*usc_chg_event)(int); +struct lpc32xx_usbd_cfg +{ + int vbus_drv_pol; /* 0=active low drive for VBUS via ISP1301 */ + usc_chg_event conn_chgb; /* Connection change event callback (optional) */ + usc_chg_event susp_chgb; /* Suspend/resume event callback (optional) */ + usc_chg_event rmwk_chgb; /* Enable/disable remote wakeup */ +}; + + +#endif /* __ASM_ARCH_BOARD_H */ + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/clkdev.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/clkdev.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/clkdev.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/clkdev.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/clkdev.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_CLKDEV_H +#define __ASM_ARCH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/debug-macro.S linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/debug-macro.S --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/debug-macro.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/debug-macro.S 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,61 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/debug-macro.S + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Debug output is hardcoded to standard UART 5 +*/ + +#if defined(CONFIG_SERIAL_HS_LPC32XX_CONSOLE) + .macro addruart,rx, tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =0x40014000 @ physical + ldrne \rx, =0xF4014000 @ virtual +1003: + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0] + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #0x0] + ldr \rd, [\rx, #0x4] + cmp \rd, #0 + bne 1002b + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #0x0] + ldr \rd, [\rx, #0x4] + cmp \rd, #0 + bne 1001b + .endm + +#else + .macro addruart,rx, tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =0x40090000 + ldrne \rx, =0xF4090000 + .endm + +#define UART_SHIFT 2 +#include +#endif + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/dmac.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/dmac.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/dmac.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/dmac.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,285 @@ +/* + * asm-arm/arch-lpc32xx/dmac.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_DMAC_H +#define __ASM_ARCH_DMAC_H + +/********************************************************************** +* DMA register offsets +**********************************************************************/ + +/* DMA controller register structures */ +#define DMA_INT_STAT(x) (x + 0x00) +#define DMA_INT_TC_STAT(x) (x + 0x04) +#define DMA_INT_TC_CLEAR(x) (x + 0x08) +#define DMA_INT_ERR_STAT(x) (x + 0x0C) +#define DMA_INT_ERR_CLEAR(x) (x + 0x10) +#define DMA_RAW_TC_STAT(x) (x + 0x14) +#define DMA_RAW_ERR_STAT(x) (x + 0x18) +#define DMA_CH_ENABLE(x) (x + 0x1C) +#define DMA_SW_BURST_REQ(x) (x + 0x20) +#define DMA_SW_SINGLE_REQ(x) (x + 0x24) +#define DMA_SW_LAST_BURST_REQ(x) (x + 0x28) +#define DMA_SW_LAST_SINGLE_REQ(x) (x + 0x2C) +#define DMA_CONFIG(x) (x + 0x30) +#define DMA_SYNC(x) (x + 0x34) + +/* DMA controller channel register structure */ +#define DMA_CH_OFFS(c) ((c * 0x20) + 0x100) +#define DMACH_SRC_ADDR(x, c) (x + DMA_CH_OFFS(c) + 0x00) +#define DMACH_DEST_ADDR(x, c) (x + DMA_CH_OFFS(c) + 0x04) +#define DMACH_LLI(x, c) (x + DMA_CH_OFFS(c) + 0x08) +#define DMACH_CONTROL(x, c) (x + DMA_CH_OFFS(c) + 0x0C) +#define DMACH_CONFIG_CH(x, c) (x + DMA_CH_OFFS(c) + 0x10) + +/* DMA linked list structure */ +#define DMA_LL_SRC(x) (x + 0x0) +#define DMA_LL_DEST(x) (x + 0x4) +#define DMA_LL_NEXT_LLI(x) (x + 0x8) +#define DMA_LL_NEXT_CTRL(x) (x + 0xC) + +#define DMA_LL_SIZE 16 + +/********************************************************************** +* int_stat, int_tc_stat, int_tc_clear, int_err_stat, raw_tc_stat, +* raw_err_stat, and chan_enable register definitions +**********************************************************************/ +/* Macro for determining a bit position for a channel */ +#define DMAC_GET_CHAN_POS(chan) (0x1 << ((chan) & 0x7)) + +/********************************************************************** +* sw_burst_req, sw_single_req, sw_last_burst_req, sw_last_single_req, +* and sync register definitions +**********************************************************************/ +/* Peripheral DMA bit position for I2S0 DMA0 */ +#define DMA_PER_I2S0_DMA0 _BIT(0) + +/* Peripheral DMA bit position for NAND FLASH (same as 12) */ +#define DMA_PER_NAND1 _BIT(1) + +/* Peripheral DMA bit position for I2S1 DMA0 */ +#define DMA_PER_I2S1_DMA0 _BIT(2) + +/* Peripheral DMA bit position for SPI2 (RX and TX) */ +#define DMA_PER_SPI2_TXRX _BIT(3) + +/* Peripheral DMA bit position for SSP1 (RX) */ +#define DMA_PER_SSP1_RX _BIT(3) + +/* Peripheral DMA bit position for SD card */ +#define DMA_PER_SDCARD _BIT(4) + +/* Peripheral DMA bit position for HSUART1 TX */ +#define DMA_PER_HSUART1_TX _BIT(5) + +/* Peripheral DMA bit position for HSUART1 RX */ +#define DMA_PER_HSUART1_RX _BIT(6) + +/* Peripheral DMA bit position for HSUART2 TX */ +#define DMA_PER_HSUART2_TX _BIT(7) + +/* Peripheral DMA bit position for HSUART2 RX */ +#define DMA_PER_HSUART2_RX _BIT(8) + +/* Peripheral DMA bit position for HSUART7 TX */ +#define DMA_PER_HSUART7_TX _BIT(9) + +/* Peripheral DMA bit position for HSUART7 RX */ +#define DMA_PER_HSUART7_RX _BIT(10) + +/* Peripheral DMA bit position for I2S1 DMA1 */ +#define DMA_PER_I2S1_DMA1 _BIT(10) + +/* Peripheral DMA bit position for SPI1 (RX and TX) */ +#define DMA_PER_SPI1_TXRX _BIT(11) + +/* Peripheral DMA bit position for SSP1 (TX) */ +#define DMA_PER_SSP1_TX _BIT(11) + +/* Peripheral DMA bit position for NAND FLASH (same as 1) */ +#define DMA_PER_NAND2 _BIT(12) + +/* Peripheral DMA bit position for I2S0 DMA1 */ +#define DMA_PER_I2S0_DMA1 _BIT(13) + +/* Peripheral DMA bit position for SSP0 (RX) */ +#define DMA_PER_SSP0_RX _BIT(14) + +/* Peripheral DMA bit position for SSP0 (TX) */ +#define DMA_PER_SSP0_TX _BIT(15) + +/********************************************************************** +* config register definitions +**********************************************************************/ +/* Bit for enabling big endian mode on AHB 1 */ +#define DMAC_BIG_ENDIAN_AHB1 _BIT(2) + +/* Bit for enabling big endian mode on AHB 0 */ +#define DMAC_BIG_ENDIAN_AHB0 _BIT(1) + +/* Bit for enabling the DMA controller */ +#define DMAC_CTRL_ENABLE _BIT(0) + +/********************************************************************** +* lli register definitions +**********************************************************************/ +/* Bit for selecting AHB0 (0) or AHB1 (1) */ +#define DMAC_CHAN_LLI_SEL_AHB1 _BIT(0) + +/********************************************************************** +* control register definitions +**********************************************************************/ +/* Bit for enabling a channel terminal count interrupt */ +#define DMAC_CHAN_INT_TC_EN _BIT(31) + +/* Bit for indicating address is cacheable */ +#define DMAC_CHAN_PROT3 _BIT(30) + +/* Bit for indicating address is bufferable */ +#define DMAC_CHAN_PROT2 _BIT(29) + +/* Bit for indicating address is privelaged mode (1) or user + mode (0) */ +#define DMAC_CHAN_PROT1 _BIT(28) + +/* Bit for enabling automatic destination increment */ +#define DMAC_CHAN_DEST_AUTOINC _BIT(27) + +/* Bit for enabling automatic source increment */ +#define DMAC_CHAN_SRC_AUTOINC _BIT(26) + +/* Bit for using AHB1 master for destination transfer */ +#define DMAC_CHAN_DEST_AHB1 _BIT(25) + +/* Bit for using AHB1 master for source transfer */ +#define DMAC_CHAN_SRC_AHB1 _BIT(24) + +/* Destination data width selection defines */ +#define DMAC_CHAN_DEST_WIDTH_8 0x0 +#define DMAC_CHAN_DEST_WIDTH_16 _BIT(21) +#define DMAC_CHAN_DEST_WIDTH_32 _BIT(22) + +/* Source data width selection defines */ +#define DMAC_CHAN_SRC_WIDTH_8 0x0 +#define DMAC_CHAN_SRC_WIDTH_16 _BIT(18) +#define DMAC_CHAN_SRC_WIDTH_32 _BIT(19) + +/* Destination data burst size defines (in transfer width) */ +#define DMAC_CHAN_DEST_BURST_1 0 +#define DMAC_CHAN_DEST_BURST_4 _BIT(15) +#define DMAC_CHAN_DEST_BURST_8 _BIT(16) +#define DMAC_CHAN_DEST_BURST_16 (_BIT(16) | _BIT(15)) +#define DMAC_CHAN_DEST_BURST_32 _BIT(17) +#define DMAC_CHAN_DEST_BURST_64 (_BIT(17) | _BIT(15)) +#define DMAC_CHAN_DEST_BURST_128 (_BIT(17) | _BIT(16)) +#define DMAC_CHAN_DEST_BURST_256 (_BIT(17) | _BIT(16) | _BIT(15)) + +/* Macro for direct loading of destination burst size field */ +#define DMAC_CHAN_DEST_BURST_LOAD(n) (((n) & 0x7) << 15) + +/* Source data burst size defines (in transfer width) */ +#define DMAC_CHAN_SRC_BURST_1 0 +#define DMAC_CHAN_SRC_BURST_4 _BIT(12) +#define DMAC_CHAN_SRC_BURST_8 _BIT(13) +#define DMAC_CHAN_SRC_BURST_16 (_BIT(13) | _BIT(12)) +#define DMAC_CHAN_SRC_BURST_32 _BIT(14) +#define DMAC_CHAN_SRC_BURST_64 (_BIT(14) | _BIT(12)) +#define DMAC_CHAN_SRC_BURST_128 (_BIT(14) | _BIT(13)) +#define DMAC_CHAN_SRC_BURST_256 (_BIT(14) | _BIT(13) | _BIT(12)) + +/* Macro for direct loading of source burst size field */ +#define DMAC_CHAN_SRC_BURST_LOAD(n) (((n) & 0x7) << 12) + +/* Macro for loading transfer size */ +#define DMAC_CHAN_TRANSFER_SIZE(n) ((n) & 0xFFF) + +/********************************************************************** +* config_ch register definitions +**********************************************************************/ +/* Bit for halting a DMA transfer */ +#define DMAC_CHAN_HALT _BIT(18) + +/* Bit for checking active status of the DMA channel */ +#define DMAC_CHAN_ACTIVE _BIT(17) + +/* Bit for enabling locked transfers */ +#define DMAC_CHAN_LOCK _BIT(16) + +/* Terminal count interrupt mask bit */ +#define DMAC_CHAN_ITC _BIT(15) + +/* Interrupt error mask bit */ +#define DMAC_CHAN_IE _BIT(14) + +/* Defines for flow control with DMA as the controller */ +#define DMAC_CHAN_FLOW_D_M2M (0x0 << 11) +#define DMAC_CHAN_FLOW_D_M2P (0x1 << 11) +#define DMAC_CHAN_FLOW_D_P2M (0x2 << 11) +#define DMAC_CHAN_FLOW_D_SP2DP (0x3 << 11) + +/* Defines for flow control with destination peripheral as the + controller */ +#define DMAC_CHAN_FLOW_DP_SP2DP (0x4 << 11) + +/* Defines for flow control with peripheral as the controller */ +#define DMAC_CHAN_FLOW_P_M2P (0x5 << 11) +#define DMAC_CHAN_FLOW_P_P2M (0x6 << 11) + +/* Defines for flow control with source peripheral as the + controller */ +#define DMAC_CHAN_FLOW_SP_SP2DP (0x7 << 11) + +/* Macro for loading destination peripheral */ +#define DMAC_DEST_PERIP(n) (((n) & 0x1F) << 6) + +/* Macro for loading source peripheral */ +#define DMAC_SRC_PERIP(n) (((n) & 0x1F) << 1) + +/* Channel enable bit */ +#define DMAC_CHAN_ENABLE _BIT(0) + +/********************************************************************** +* config_ch register definitions (source and destination +* peripheral ID numbers). These can be used with the DMAC_DEST_PERIP +* and DMAC_SRC_PERIP macros. +**********************************************************************/ +#define DMA_PERID_I2S0_DMA0 0 +#define DMA_PERID_NAND1 1 +#define DMA_PERID_I2S1_DMA0 2 +#define DMA_PERID_SPI2_TXRX 3 +#define DMA_PERID_SSP1_RX 3 +#define DMA_PERID_SDCARD 4 +#define DMA_PERID_HSUART1_TX 5 +#define DMA_PERID_HSUART1_RX 6 +#define DMA_PERID_HSUART2_TX 7 +#define DMA_PERID_HSUART2_RX 8 +#define DMA_PERID_HSUART7_TX 9 +#define DMA_PERID_HSUART7_RX 10 +#define DMA_PERID_I2S1_DMA1 10 +#define DMA_PERID_SPI1_TXRX 11 +#define DMA_PERID_SSP1_TX 11 +#define DMA_PERID_NAND2 12 +#define DMA_PERID_I2S0_DMA1 13 +#define DMA_PERID_SSP0_RX 14 +#define DMA_PERID_SSP0_TX 15 + +#endif /* __ASM_ARCH_DMAC_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/dma.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/dma.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/dma.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/dma.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,111 @@ +/* + * asm-arm/arch-lpc32xx/dma.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H + +#include + +#define MAX_DMA_CHANNELS 8 + +#define DMA_CH_SDCARD_TX 0 +#define DMA_CH_SDCARD_RX 1 +#define DMA_CH_I2S_TX 2 +#define DMA_CH_I2S_RX 3 +#define DMA_CH_SLCNAND 4 + +enum { + DMA_INT_UNKNOWN = 0, + DMA_ERR_INT = 1, + DMA_TC_INT = 2, +}; + +/* + * DMA channel control structure + */ +struct dma_config { + int ch; /* Channel # to use */ + int tc_inten; /* !0 = Enable TC interrupts for this channel */ + int err_inten; /* !0 = Enable error interrupts for this channel */ + int src_size; /* Source xfer size - must be 1, 2, or 4 */ + int src_inc; /* !0 = Enable source address increment */ + int src_ahb1; /* !0 = Use AHB1 for source transfer */ + int src_bsize; /* Source burst size (ie, DMAC_CHAN_SRC_BURST_xxx) */ + u32 src_prph; /* Source peripheral (ie, DMA_PERID_xxxx) */ + int dst_size; /* Destination xfer size - must be 1, 2, or 4 */ + int dst_inc; /* !0 = Enable destination address increment */ + int dst_ahb1; /* !0 = Use AHB1 for destination transfer */ + int dst_bsize; /* Destination burst size (ie, DMAC_CHAN_DEST_BURST_xxx) */ + u32 dst_prph; /* Destination peripheral (ie, DMA_PERID_xxxx) */ + u32 flowctrl; /* Flow control (ie, DMAC_CHAN_FLOW_xxxxxx) */ +}; + +/* + * Channel enable and disable functions + */ +extern int lpc32xx_dma_ch_enable(int ch); +extern int lpc32xx_dma_ch_disable(int ch); + +/* + * Channel allocation and deallocation functions + */ +extern int lpc32xx_dma_ch_get(struct dma_config *dmachcfg, + char *name, + void *irq_handler, + void *data); +extern int lpc32xx_dma_ch_put(int ch); +extern int lpc32xx_dma_ch_pause_unpause(int ch, int pause); + +/* + * Setup or start an unbound DMA transfer + */ +extern int lpc32xx_dma_start_pflow_xfer(int ch, + void *src, + void *dst, + int enable); + +/* + * DMA linked list support + */ +extern u32 lpc32xx_dma_alloc_llist(int ch, + int entries); +extern void lpc32xx_dma_dealloc_llist(int ch); +extern u32 lpc32xx_dma_llist_v_to_p(int ch, + u32 vlist); +extern u32 lpc32xx_dma_llist_p_to_v(int ch, + u32 plist); +extern u32 lpc32xx_dma_get_llist_head(int ch); +extern void lpc32xx_dma_flush_llist(int ch); +extern u32 lpc32xx_dma_queue_llist_entry(int ch, + void *src, + void *dst, + int size); +extern u32 lpc32xx_get_free_llist_entry(int ch); +extern u32 lpc32xx_dma_queue_llist(int ch, + void *src, + void *dst, + int size, + u32 ctrl); +extern int lpc32xx_dma_start_xfer(int chan, u32 config); +extern void lpc32xx_dma_force_burst(int ch, int src); + +#endif /* _ASM_ARCH_DMA_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/entry-macro.S linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/entry-macro.S --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/entry-macro.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/entry-macro.S 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,47 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/entry-macro.S + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#define LPC32XX_INTC_MASKED_STATUS_OFS 0x8 + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =IO_ADDRESS(LPC32XX_MIC_BASE) + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + +/* + * Return IRQ number in irqnr. Also return processor Z flag status in CPSR + * as set if an interrupt is pending. + */ + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, [\base, #LPC32XX_INTC_MASKED_STATUS_OFS] + clz \irqnr, \irqstat + rsb \irqnr, \irqnr, #31 + teq \irqstat, #0 + .endm + + .macro irq_prio_table + .endm + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/gpio.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/gpio.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/gpio.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/gpio.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,74 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/gpio.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +#include + +/* + * Note! + * Muxed GP pins need to be setup to the GP state in the board level + * code prior to using this driver. + * GPI pins : 28xP3 group + * GPO pins : 24xP3 group + * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group + */ + +#define LPC32XX_GPIO_P0_MAX 8 +#define LPC32XX_GPIO_P1_MAX 24 +#define LPC32XX_GPIO_P2_MAX 13 +#define LPC32XX_GPIO_P3_MAX 6 +#define LPC32XX_GPI_P3_MAX 28 +#define LPC32XX_GPO_P3_MAX 24 + +#define LPC32XX_GPIO_P0_GRP 0 +#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX) +#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX) +#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX) +#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX) +#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX) + +/* + * A specific GPIO can be selected with this macro + * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) + * See the LPC32x0 User's guide for GPIO group numbers + */ +#define LPC32XX_GPIO(x, y) ((x) + (y)) + +static inline int gpio_get_value(unsigned gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return __gpio_to_irq(gpio); +} + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/hardware.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/hardware.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/hardware.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/hardware.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,34 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/hardware.h + * + * Copyright (c) 2005 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * Start of virtual addresses for IO devices + */ +#define IO_BASE 0xF0000000 + +/* + * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0 + */ +#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\ + IO_BASE) + +#define io_p2v(x) ((void __iomem *) (unsigned long) IO_ADDRESS(x)) +#define io_v2p(x) ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff)) + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/i2c.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/i2c.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/i2c.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/i2c.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,63 @@ +/* + * PNX4008-specific tweaks for I2C IP3204 block + * + * Author: Vitaly Wool + * + * 2005 (c) MontaVista Software, Inc. 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. + */ + +#ifndef __ASM_ARCH_I2C_H +#define __ASM_ARCH_I2C_H + +enum { + mstatus_tdi = 0x00000001, + mstatus_afi = 0x00000002, + mstatus_nai = 0x00000004, + mstatus_drmi = 0x00000008, + mstatus_active = 0x00000020, + mstatus_scl = 0x00000040, + mstatus_sda = 0x00000080, + mstatus_rff = 0x00000100, + mstatus_rfe = 0x00000200, + mstatus_tff = 0x00000400, + mstatus_tfe = 0x00000800, +}; + +enum { + mcntrl_tdie = 0x00000001, + mcntrl_afie = 0x00000002, + mcntrl_naie = 0x00000004, + mcntrl_drmie = 0x00000008, + mcntrl_daie = 0x00000020, + mcntrl_rffie = 0x00000040, + mcntrl_tffie = 0x00000080, + mcntrl_reset = 0x00000100, + mcntrl_cdbmode = 0x00000400, +}; + +enum { + rw_bit = 1 << 0, + start_bit = 1 << 8, + stop_bit = 1 << 9, +}; + +#define I2C_REG_RX(a) ((a)->ioaddr) /* Rx FIFO reg (RO) */ +#define I2C_REG_TX(a) ((a)->ioaddr) /* Tx FIFO reg (WO) */ +#define I2C_REG_STS(a) ((a)->ioaddr + 0x04) /* Status reg (RO) */ +#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08) /* Ctl reg */ +#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c) /* Clock divider low */ +#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10) /* Clock divider high */ +#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14) /* I2C address */ +#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18) /* Rx FIFO level (RO) */ +#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c) /* Tx FIFO level (RO) */ +#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20) /* Num of bytes Rx-ed (RO) */ +#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24) /* Num of bytes Tx-ed (RO) */ +#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28) /* Tx slave FIFO (RO) */ +#define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c) /* Tx slave FIFO level (RO) */ + +#define I2C_CHIP_NAME "PNX4008-I2C" + +#endif /* __ASM_ARCH_I2C_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/i2s.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/i2s.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/i2s.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/i2s.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,156 @@ +/* + * asm-arm/arch-lpc32xx/i2c.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_I2S_H +#define __ASM_ARCH_I2S_H + +/********************************************************************** +* I2S controller register offsets +**********************************************************************/ + +#define I2S_DAO(x) (x + 0x00) +#define I2S_DAI(x) (x + 0x04) +#define I2S_TX_FIFO(x) (x + 0x08) +#define I2S_RX_FIFO(x) (x + 0x0C) +#define I2S_STAT(x) (x + 0x10) +#define I2S_DMA0(x) (x + 0x14) +#define I2S_DMA1(x) (x + 0x18) +#define I2S_IRQ(x) (x + 0x1C) +#define I2S_TX_RATE(x) (x + 0x20) +#define I2S_RX_RATE(x) (x + 0x24) + +/********************************************************************** +* i2s_daO i2s_dai register definitions +**********************************************************************/ +#define I2S_WW8 _SBF(0,0) /* Word width is 8bit*/ +#define I2S_WW16 _SBF(0,1) /* Word width is 16bit*/ +#define I2S_WW32 _SBF(0,3) /* Word width is 32bit*/ +#define I2S_MONO _BIT(2) /* Mono */ +#define I2S_STOP _BIT(3) /* Stop, diables the access to FIFO, + mutes the channel */ +#define I2S_RESET _BIT(4) /* Reset the channel */ +#define I2S_WS_SEL _BIT(5) /* Channel Master(0) or slave(1) + mode select*/ +#define I2S_WS_HP(s) _SBF(6,s) /* Word select half period - 1 */ + +#define I2S_MUTE _BIT(15) /* Mute the channel, + Transmit channel only */ + +#define I2S_WW32_HP 0x1f /* Word select half period for 32bit + word width */ +#define I2S_WW16_HP 0x0f /* Word select half period for 16bit + word width */ +#define I2S_WW8_HP 0x7 /* Word select half period for 8bit + word width */ + +#define WSMASK_HP 0X7FC /* Mask for WS half period bits */ + +/********************************************************************** +* i2s_tx_fifo register definitions +**********************************************************************/ +#define I2S_FIFO_TX_WRITE(d) (d) + +/********************************************************************** +* i2s_rx_fifo register definitions +**********************************************************************/ +#define I2S_FIFO_RX_WRITE(d) (d) + +/********************************************************************** +* i2s_stat register definitions +**********************************************************************/ +#define I2S_IRQ_STAT _BIT(0) +#define I2S_DMA0_REQ _BIT(1) +#define I2S_DMA1_REQ _BIT(2) + +#define I2S_RX_STATE_MASK 0x0000ff00 +#define I2S_TX_STATE_MASK 0x00ff0000 + +/********************************************************************** +* i2s_dma0 Configuration register definitions +**********************************************************************/ +#define I2S_DMA0_RX_EN _BIT(0) /* Enable RX DMA1*/ +#define I2S_DMA0_TX_EN _BIT(1) /* Enable TX DMA1*/ +#define I2S_DMA0_RX_DEPTH(s) _SBF(8,s) /* Set the level for DMA1 + RX Request */ +#define I2S_DMA0_TX_DEPTH(s) _SBF(16,s) /* Set the level for DMA1 + TX Request */ + +/********************************************************************** +* i2s_dma1 Configuration register definitions +**********************************************************************/ +#define I2S_DMA1_RX_EN _BIT(0) /* Enable RX DMA1*/ +#define I2S_DMA1_TX_EN _BIT(1) /* Enable TX DMA1*/ +#define I2S_DMA1_RX_DEPTH(s) _SBF(8,s) /* Set the level for DMA1 + RX Request */ +#define I2S_DMA1_TX_DEPTH(s) _SBF(16,s) /* Set the level for DMA1 + TX Request */ + +/********************************************************************** +* i2s_irq register definitions +**********************************************************************/ +#define I2S_RX_IRQ_EN _BIT(0) /* Enable RX IRQ*/ +#define I2S_TX_IRQ_EN _BIT(1) /* Enable TX IRQ*/ +#define I2S_IRQ_RX_DEPTH(s) _SBF(8,s) /* valid values ar 0 to 7 */ +#define I2S_IRQ_TX_DEPTH(s) _SBF(16,s) /* valid values ar 0 to 7 */ + +/********************************************************************** +* define audio rates for i2s_tx_rate/i2s_rx_rate register definitions +**********************************************************************/ + +#define A96KHZ104MHZ8BIT 0x7ed // 7, 237 +#define A48KHZ104MHZ8BIT 0x3cb // 3, 203 +#define A44KHZ104MHZ8BIT 0x14a // 1, 74 +#define A32KHZ104MHZ8BIT 0x5fe // 5, 254 +#define A22KHZ104MHZ8BIT 0x194 // 1, 148 +#define A16KHZ104MHZ8BIT 0x1cb // 1, 203 + +#define A96KHZ104MHZ16BIT 0xeed // 14, 237 +#define A48KHZ104MHZ16BIT 0x7ED // 7, 237 +#define A44KHZ104MHZ16BIT 0x6dd // 6, 221 +#define A32KHZ104MHZ16BIT 0x5fe // 5, 254 +#define A22KHZ104MHZ16BIT 0x14a // 1, 74 +#define A16KHZ104MHZ16BIT 0x2cb // 2, 203 + +#define A96KHZ104MHZ32BIT 0x1ced// 28, 237 +#define A48KHZ104MHZ32BIT 0xeed // 14, 237 +#define A44KHZ104MHZ32BIT 0xdf0 // 13, 240 +#define A32KHZ104MHZ32BIT 0x57f // 5, 127 +#define A22KHZ104MHZ32BIT 0x125 // 1, 37 +#define A16KHZ104MHZ32BIT 0x5fe // 5, 254 + +/********************************************************************** +* i2s_tx_rate register definitions +**********************************************************************/ +#define I2S_SET_TX_RATE(d) (d) + +/********************************************************************** +* i2s_rx_rate register definitions +**********************************************************************/ +#define I2S_SET_RX_RATE(d) (d) + +/********************************************************************** +* i2s channel select +**********************************************************************/ +#define I2S_CH0 0 +#define I2S_CH1 1 + +#endif /* __ASM_ARCH_I2S_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/io.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/io.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/io.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/io.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,27 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/io.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/irqs.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/irqs.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/irqs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/irqs.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,117 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/irqs.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARM_ARCH_IRQS_H +#define __ASM_ARM_ARCH_IRQS_H + +#define LPC32XX_SIC1_IRQ(n) (32 + (n)) +#define LPC32XX_SIC2_IRQ(n) (64 + (n)) + +/* + * MIC interrupts + */ +#define IRQ_LPC32XX_SUB1IRQ 0 +#define IRQ_LPC32XX_SUB2IRQ 1 +#define IRQ_LPC32XX_PWM3 3 +#define IRQ_LPC32XX_PWM4 4 +#define IRQ_LPC32XX_HSTIMER 5 +#define IRQ_LPC32XX_WATCH 6 +#define IRQ_LPC32XX_UART_IIR3 7 +#define IRQ_LPC32XX_UART_IIR4 8 +#define IRQ_LPC32XX_UART_IIR5 9 +#define IRQ_LPC32XX_UART_IIR6 10 +#define IRQ_LPC32XX_FLASH 11 +#define IRQ_LPC32XX_SD1 13 +#define IRQ_LPC32XX_LCD 14 +#define IRQ_LPC32XX_SD0 15 +#define IRQ_LPC32XX_TIMER0 16 +#define IRQ_LPC32XX_TIMER1 17 +#define IRQ_LPC32XX_TIMER2 18 +#define IRQ_LPC32XX_TIMER3 19 +#define IRQ_LPC32XX_SSP0 20 +#define IRQ_LPC32XX_SSP1 21 +#define IRQ_LPC32XX_I2S0 22 +#define IRQ_LPC32XX_I2S1 23 +#define IRQ_LPC32XX_UART_IIR7 24 +#define IRQ_LPC32XX_UART_IIR2 25 +#define IRQ_LPC32XX_UART_IIR1 26 +#define IRQ_LPC32XX_MSTIMER 27 +#define IRQ_LPC32XX_DMA 28 +#define IRQ_LPC32XX_ETHERNET 29 +#define IRQ_LPC32XX_SUB1FIQ 30 +#define IRQ_LPC32XX_SUB2FIQ 31 + +/* + * SIC1 interrupts start at offset 32 + */ +#define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1) +#define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2) +#define IRQ_LPC32XX_GPI_11 LPC32XX_SIC1_IRQ(4) +#define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6) +#define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7) +#define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8) +#define IRQ_LPC32XX_SPI2 LPC32XX_SIC1_IRQ(12) +#define IRQ_LPC32XX_PLLUSB LPC32XX_SIC1_IRQ(13) +#define IRQ_LPC32XX_PLLHCLK LPC32XX_SIC1_IRQ(14) +#define IRQ_LPC32XX_PLL397 LPC32XX_SIC1_IRQ(17) +#define IRQ_LPC32XX_I2C_2 LPC32XX_SIC1_IRQ(18) +#define IRQ_LPC32XX_I2C_1 LPC32XX_SIC1_IRQ(19) +#define IRQ_LPC32XX_RTC LPC32XX_SIC1_IRQ(20) +#define IRQ_LPC32XX_KEY LPC32XX_SIC1_IRQ(22) +#define IRQ_LPC32XX_SPI1 LPC32XX_SIC1_IRQ(23) +#define IRQ_LPC32XX_SW LPC32XX_SIC1_IRQ(24) +#define IRQ_LPC32XX_USB_OTG_TIMER LPC32XX_SIC1_IRQ(25) +#define IRQ_LPC32XX_USB_OTG_ATX LPC32XX_SIC1_IRQ(26) +#define IRQ_LPC32XX_USB_HOST LPC32XX_SIC1_IRQ(27) +#define IRQ_LPC32XX_USB_DEV_DMA LPC32XX_SIC1_IRQ(28) +#define IRQ_LPC32XX_USB_DEV_LP LPC32XX_SIC1_IRQ(29) +#define IRQ_LPC32XX_USB_DEV_HP LPC32XX_SIC1_IRQ(30) +#define IRQ_LPC32XX_USB_I2C LPC32XX_SIC1_IRQ(31) + +/* + * SIC2 interrupts start at offset 64 + */ +#define IRQ_LPC32XX_GPIO_00 LPC32XX_SIC2_IRQ(0) +#define IRQ_LPC32XX_GPIO_01 LPC32XX_SIC2_IRQ(1) +#define IRQ_LPC32XX_GPIO_02 LPC32XX_SIC2_IRQ(2) +#define IRQ_LPC32XX_GPIO_03 LPC32XX_SIC2_IRQ(3) +#define IRQ_LPC32XX_GPIO_04 LPC32XX_SIC2_IRQ(4) +#define IRQ_LPC32XX_GPIO_05 LPC32XX_SIC2_IRQ(5) +#define IRQ_LPC32XX_SPI2_DATAIN LPC32XX_SIC2_IRQ(6) +#define IRQ_LPC32XX_U2_HCTS LPC32XX_SIC2_IRQ(7) +#define IRQ_LPC32XX_P0_P1_IRQ LPC32XX_SIC2_IRQ(8) +#define IRQ_LPC32XX_GPI_08 LPC32XX_SIC2_IRQ(9) +#define IRQ_LPC32XX_GPI_09 LPC32XX_SIC2_IRQ(10) +#define IRQ_LPC32XX_GPI_19 LPC32XX_SIC2_IRQ(11) +#define IRQ_LPC32XX_U7_HCTS LPC32XX_SIC2_IRQ(12) +#define IRQ_LPC32XX_GPI_07 LPC32XX_SIC2_IRQ(15) +#define IRQ_LPC32XX_SDIO LPC32XX_SIC2_IRQ(18) +#define IRQ_LPC32XX_U5_RX LPC32XX_SIC2_IRQ(19) +#define IRQ_LPC32XX_SPI1_DATAIN LPC32XX_SIC2_IRQ(20) +#define IRQ_LPC32XX_GPI_00 LPC32XX_SIC2_IRQ(22) +#define IRQ_LPC32XX_GPI_01 LPC32XX_SIC2_IRQ(23) +#define IRQ_LPC32XX_GPI_02 LPC32XX_SIC2_IRQ(24) +#define IRQ_LPC32XX_GPI_03 LPC32XX_SIC2_IRQ(25) +#define IRQ_LPC32XX_GPI_04 LPC32XX_SIC2_IRQ(26) +#define IRQ_LPC32XX_GPI_05 LPC32XX_SIC2_IRQ(27) +#define IRQ_LPC32XX_GPI_06 LPC32XX_SIC2_IRQ(28) +#define IRQ_LPC32XX_SYSCLK LPC32XX_SIC2_IRQ(31) + +#define NR_IRQS 96 + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/memory.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/memory.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/memory.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/memory.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,27 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/memory.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Physical DRAM offset of bank 0 + */ +#define PHYS_OFFSET UL(0x80000000) + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/platform.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/platform.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/platform.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/platform.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,694 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/platform.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_PLATFORM_H +#define __ASM_ARCH_PLATFORM_H + +#define _SBF(f, v) ((v) << (f)) +#define _BIT(n) _SBF(n, 1) + +/* + * AHB 0 physical base addresses + */ +#define LPC32XX_SLC_BASE 0x20020000 +#define LPC32XX_SSP0_BASE 0x20084000 +#define LPC32XX_SPI1_BASE 0x20088000 +#define LPC32XX_SSP1_BASE 0x2008C000 +#define LPC32XX_SPI2_BASE 0x20090000 +#define LPC32XX_I2S0_BASE 0x20094000 +#define LPC32XX_SD_BASE 0x20098000 +#define LPC32XX_I2S1_BASE 0x2009C000 +#define LPC32XX_MLC_BASE 0x200A8000 +#define LPC32XX_AHB0_START LPC32XX_SLC_BASE +#define LPC32XX_AHB0_SIZE 0x00089000 + +/* + * AHB 1 physical base addresses + */ +#define LPC32XX_DMA_BASE 0x31000000 +#define LPC32XX_USB_BASE 0x31020000 +#define LPC32XX_USBH_BASE 0x31020000 +#define LPC32XX_USB_OTG_BASE 0x31020000 +#define LPC32XX_OTG_I2C_BASE 0x31020300 +#define LPC32XX_LCD_BASE 0x31040000 +#define LPC32XX_ETHERNET_BASE 0x31060000 +#define LPC32XX_EMC_BASE 0x31080000 +#define LPC32XX_ETB_CFG_BASE 0x310C0000 +#define LPC32XX_ETB_DATA_BASE 0x310E0000 +#define LPC32XX_AHB1_START LPC32XX_DMA_BASE +#define LPC32XX_AHB1_SIZE 0x000E1000 + +/* + * FAB physical base addresses + */ +#define LPC32XX_CLK_PM_BASE 0x40004000 +#define LPC32XX_MIC_BASE 0x40008000 +#define LPC32XX_SIC1_BASE 0x4000C000 +#define LPC32XX_SIC2_BASE 0x40010000 +#define LPC32XX_HS_UART1_BASE 0x40014000 +#define LPC32XX_HS_UART2_BASE 0x40018000 +#define LPC32XX_HS_UART7_BASE 0x4001C000 +#define LPC32XX_RTC_BASE 0x40024000 +#define LPC32XX_RTC_RAM_BASE 0x40024080 +#define LPC32XX_GPIO_BASE 0x40028000 +#define LPC32XX_PWM3_BASE 0x4002C000 +#define LPC32XX_PWM4_BASE 0x40030000 +#define LPC32XX_MSTIM_BASE 0x40034000 +#define LPC32XX_HSTIM_BASE 0x40038000 +#define LPC32XX_WDTIM_BASE 0x4003C000 +#define LPC32XX_DEBUG_CTRL_BASE 0x40040000 +#define LPC32XX_TIMER0_BASE 0x40044000 +#define LPC32XX_ADC_BASE 0x40048000 +#define LPC32XX_TIMER1_BASE 0x4004C000 +#define LPC32XX_KSCAN_BASE 0x40050000 +#define LPC32XX_UART_CTRL_BASE 0x40054000 +#define LPC32XX_TIMER2_BASE 0x40058000 +#define LPC32XX_PWM1_BASE 0x4005C000 +#define LPC32XX_PWM2_BASE 0x4005C004 +#define LPC32XX_TIMER3_BASE 0x40060000 + +/* + * APB physical base addresses + */ +#define LPC32XX_UART3_BASE 0x40080000 +#define LPC32XX_UART4_BASE 0x40088000 +#define LPC32XX_UART5_BASE 0x40090000 +#define LPC32XX_UART6_BASE 0x40098000 +#define LPC32XX_I2C1_BASE 0x400A0000 +#define LPC32XX_I2C2_BASE 0x400A8000 + +/* + * FAB and APB base and sizing + */ +#define LPC32XX_FABAPB_START LPC32XX_CLK_PM_BASE +#define LPC32XX_FABAPB_SIZE 0x000A5000 + +/* + * Internal memory bases and sizes + */ +#define LPC32XX_IRAM_BASE 0x08000000 +#define LPC32XX_IROM_BASE 0x0C000000 + +/* + * External Static Memory Bank Address Space Bases + */ +#define LPC32XX_EMC_CS0_BASE 0xE0000000 +#define LPC32XX_EMC_CS1_BASE 0xE1000000 +#define LPC32XX_EMC_CS2_BASE 0xE2000000 +#define LPC32XX_EMC_CS3_BASE 0xE3000000 + +/* + * External SDRAM Memory Bank Address Space Bases + */ +#define LPC32XX_EMC_DYCS0_BASE 0x80000000 +#define LPC32XX_EMC_DYCS1_BASE 0xA0000000 + +/* + * Clock and crystal information + */ +#define LPC32XX_MAIN_OSC_FREQ 13000000 +#define LPC32XX_CLOCK_OSC_FREQ 32768 + +/* + * Clock and Power control register offsets + */ +#define _PMREG(x) io_p2v(LPC32XX_CLK_PM_BASE +\ + (x)) +#define LPC32XX_CLKPWR_DEBUG_CTRL _PMREG(0x000) +#define LPC32XX_CLKPWR_BOOTMAP _PMREG(0x014) +#define LPC32XX_CLKPWR_P01_ER _PMREG(0x018) +#define LPC32XX_CLKPWR_USBCLK_PDIV _PMREG(0x01C) +#define LPC32XX_CLKPWR_INT_ER _PMREG(0x020) +#define LPC32XX_CLKPWR_INT_RS _PMREG(0x024) +#define LPC32XX_CLKPWR_INT_SR _PMREG(0x028) +#define LPC32XX_CLKPWR_INT_AP _PMREG(0x02C) +#define LPC32XX_CLKPWR_PIN_ER _PMREG(0x030) +#define LPC32XX_CLKPWR_PIN_RS _PMREG(0x034) +#define LPC32XX_CLKPWR_PIN_SR _PMREG(0x038) +#define LPC32XX_CLKPWR_PIN_AP _PMREG(0x03C) +#define LPC32XX_CLKPWR_HCLK_DIV _PMREG(0x040) +#define LPC32XX_CLKPWR_PWR_CTRL _PMREG(0x044) +#define LPC32XX_CLKPWR_PLL397_CTRL _PMREG(0x048) +#define LPC32XX_CLKPWR_MAIN_OSC_CTRL _PMREG(0x04C) +#define LPC32XX_CLKPWR_SYSCLK_CTRL _PMREG(0x050) +#define LPC32XX_CLKPWR_LCDCLK_CTRL _PMREG(0x054) +#define LPC32XX_CLKPWR_HCLKPLL_CTRL _PMREG(0x058) +#define LPC32XX_CLKPWR_ADC_CLK_CTRL_1 _PMREG(0x060) +#define LPC32XX_CLKPWR_USB_CTRL _PMREG(0x064) +#define LPC32XX_CLKPWR_SDRAMCLK_CTRL _PMREG(0x068) +#define LPC32XX_CLKPWR_DDR_LAP_NOM _PMREG(0x06C) +#define LPC32XX_CLKPWR_DDR_LAP_COUNT _PMREG(0x070) +#define LPC32XX_CLKPWR_DDR_LAP_DELAY _PMREG(0x074) +#define LPC32XX_CLKPWR_SSP_CLK_CTRL _PMREG(0x078) +#define LPC32XX_CLKPWR_I2S_CLK_CTRL _PMREG(0x07C) +#define LPC32XX_CLKPWR_MS_CTRL _PMREG(0x080) +#define LPC32XX_CLKPWR_MACCLK_CTRL _PMREG(0x090) +#define LPC32XX_CLKPWR_TEST_CLK_SEL _PMREG(0x0A4) +#define LPC32XX_CLKPWR_SFW_INT _PMREG(0x0A8) +#define LPC32XX_CLKPWR_I2C_CLK_CTRL _PMREG(0x0AC) +#define LPC32XX_CLKPWR_KEY_CLK_CTRL _PMREG(0x0B0) +#define LPC32XX_CLKPWR_ADC_CLK_CTRL _PMREG(0x0B4) +#define LPC32XX_CLKPWR_PWM_CLK_CTRL _PMREG(0x0B8) +#define LPC32XX_CLKPWR_TIMER_CLK_CTRL _PMREG(0x0BC) +#define LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1 _PMREG(0x0C0) +#define LPC32XX_CLKPWR_SPI_CLK_CTRL _PMREG(0x0C4) +#define LPC32XX_CLKPWR_NAND_CLK_CTRL _PMREG(0x0C8) +#define LPC32XX_CLKPWR_UART3_CLK_CTRL _PMREG(0x0D0) +#define LPC32XX_CLKPWR_UART4_CLK_CTRL _PMREG(0x0D4) +#define LPC32XX_CLKPWR_UART5_CLK_CTRL _PMREG(0x0D8) +#define LPC32XX_CLKPWR_UART6_CLK_CTRL _PMREG(0x0DC) +#define LPC32XX_CLKPWR_IRDA_CLK_CTRL _PMREG(0x0E0) +#define LPC32XX_CLKPWR_UART_CLK_CTRL _PMREG(0x0E4) +#define LPC32XX_CLKPWR_DMA_CLK_CTRL _PMREG(0x0E8) +#define LPC32XX_CLKPWR_AUTOCLOCK _PMREG(0x0EC) +#define LPC32XX_CLKPWR_DEVID(x) _PMREG(0x130 + (x)) + +/* + * clkpwr_debug_ctrl register definitions +*/ +#define LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT _BIT(4) + +/* + * clkpwr_bootmap register definitions + */ +#define LPC32XX_CLKPWR_BOOTMAP_SEL_BIT _BIT(1) + +/* + * clkpwr_start_gpio register bit definitions + */ +#define LPC32XX_CLKPWR_GPIOSRC_P1IO23_BIT _BIT(31) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO22_BIT _BIT(30) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO21_BIT _BIT(29) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO20_BIT _BIT(28) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO19_BIT _BIT(27) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO18_BIT _BIT(26) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO17_BIT _BIT(25) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO16_BIT _BIT(24) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO15_BIT _BIT(23) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO14_BIT _BIT(22) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO13_BIT _BIT(21) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO12_BIT _BIT(20) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO11_BIT _BIT(19) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO10_BIT _BIT(18) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO9_BIT _BIT(17) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO8_BIT _BIT(16) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO7_BIT _BIT(15) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO6_BIT _BIT(14) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO5_BIT _BIT(13) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO4_BIT _BIT(12) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO3_BIT _BIT(11) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO2_BIT _BIT(10) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO1_BIT _BIT(9) +#define LPC32XX_CLKPWR_GPIOSRC_P1IO0_BIT _BIT(8) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO7_BIT _BIT(7) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO6_BIT _BIT(6) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO5_BIT _BIT(5) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO4_BIT _BIT(4) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO3_BIT _BIT(3) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO2_BIT _BIT(2) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO1_BIT _BIT(1) +#define LPC32XX_CLKPWR_GPIOSRC_P0IO0_BIT _BIT(0) + +/* + * clkpwr_usbclk_pdiv register definitions + */ +#define LPC32XX_CLKPWR_USBPDIV_PLL_MASK 0xF + +/* + * clkpwr_start_int, clkpwr_start_raw_sts_int, clkpwr_start_sts_int, + * clkpwr_start_pol_int, register bit definitions + */ +#define LPC32XX_CLKPWR_INTSRC_ADC_BIT _BIT(31) +#define LPC32XX_CLKPWR_INTSRC_TS_P_BIT _BIT(30) +#define LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT _BIT(29) +#define LPC32XX_CLKPWR_INTSRC_USBAHNEEDCLK_BIT _BIT(26) +#define LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT _BIT(25) +#define LPC32XX_CLKPWR_INTSRC_RTC_BIT _BIT(24) +#define LPC32XX_CLKPWR_INTSRC_USBNEEDCLK_BIT _BIT(23) +#define LPC32XX_CLKPWR_INTSRC_USB_BIT _BIT(22) +#define LPC32XX_CLKPWR_INTSRC_I2C_BIT _BIT(21) +#define LPC32XX_CLKPWR_INTSRC_USBOTGTIMER_BIT _BIT(20) +#define LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT _BIT(19) +#define LPC32XX_CLKPWR_INTSRC_KEY_BIT _BIT(16) +#define LPC32XX_CLKPWR_INTSRC_MAC_BIT _BIT(7) +#define LPC32XX_CLKPWR_INTSRC_P0P1_BIT _BIT(6) +#define LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT _BIT(5) +#define LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT _BIT(4) +#define LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT _BIT(3) +#define LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT _BIT(2) +#define LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT _BIT(1) +#define LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT _BIT(0) + +/* + * clkpwr_start_pin, clkpwr_start_raw_sts_pin, clkpwr_start_sts_pin, + * clkpwr_start_pol_pin register bit definitions + */ +#define LPC32XX_CLKPWR_EXTSRC_U7_RX_BIT _BIT(31) +#define LPC32XX_CLKPWR_EXTSRC_U7_HCTS_BIT _BIT(30) +#define LPC32XX_CLKPWR_EXTSRC_U6_IRRX_BIT _BIT(28) +#define LPC32XX_CLKPWR_EXTSRC_U5_RX_BIT _BIT(26) +#define LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT _BIT(25) +#define LPC32XX_CLKPWR_EXTSRC_U3_RX_BIT _BIT(24) +#define LPC32XX_CLKPWR_EXTSRC_U2_HCTS_BIT _BIT(23) +#define LPC32XX_CLKPWR_EXTSRC_U2_RX_BIT _BIT(22) +#define LPC32XX_CLKPWR_EXTSRC_U1_RX_BIT _BIT(21) +#define LPC32XX_CLKPWR_EXTSRC_MSDIO_INT_BIT _BIT(18) +#define LPC32XX_CLKPWR_EXTSRC_MSDIO_SRT_BIT _BIT(17) +#define LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT _BIT(16) +#define LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT _BIT(15) +#define LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT _BIT(14) +#define LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT _BIT(13) +#define LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT _BIT(12) +#define LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT _BIT(11) +#define LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT _BIT(10) +#define LPC32XX_CLKPWR_EXTSRC_SYSCLKEN_BIT _BIT(9) +#define LPC32XX_CLKPWR_EXTSRC_SPI1_DATIN_BIT _BIT(8) +#define LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT _BIT(7) +#define LPC32XX_CLKPWR_EXTSRC_SPI2_DATIN_BIT _BIT(6) +#define LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT _BIT(5) +#define LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT _BIT(4) +#define LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT _BIT(3) + +/* + * clkpwr_hclk_div register definitions + */ +#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_STOP (0x0 << 7) +#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_NORM (0x1 << 7) +#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_HALF (0x2 << 7) +#define LPC32XX_CLKPWR_HCLKDIV_PCLK_DIV(n) (((n) & 0x1F) << 2) +#define LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(n) ((n) & 0x3) + +/* + * clkpwr_pwr_ctrl register definitions + */ +#define LPC32XX_CLKPWR_CTRL_FORCE_PCLK _BIT(10) +#define LPC32XX_CLKPWR_SDRAM_SELF_RFSH _BIT(9) +#define LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH _BIT(8) +#define LPC32XX_CLKPWR_AUTO_SDRAM_SELF_RFSH _BIT(7) +#define LPC32XX_CLKPWR_HIGHCORE_STATE_BIT _BIT(5) +#define LPC32XX_CLKPWR_SYSCLKEN_STATE_BIT _BIT(4) +#define LPC32XX_CLKPWR_SYSCLKEN_GPIO_EN _BIT(3) +#define LPC32XX_CLKPWR_SELECT_RUN_MODE _BIT(2) +#define LPC32XX_CLKPWR_HIGHCORE_GPIO_EN _BIT(1) +#define LPC32XX_CLKPWR_STOP_MODE_CTRL _BIT(0) + +/* + * clkpwr_pll397_ctrl register definitions + */ +#define LPC32XX_CLKPWR_PLL397_MSLOCK_STS _BIT(10) +#define LPC32XX_CLKPWR_PLL397_BYPASS _BIT(9) +#define LPC32XX_CLKPWR_PLL397_BIAS_NORM 0x000 +#define LPC32XX_CLKPWR_PLL397_BIAS_N12_5 0x040 +#define LPC32XX_CLKPWR_PLL397_BIAS_N25 0x080 +#define LPC32XX_CLKPWR_PLL397_BIAS_N37_5 0x0C0 +#define LPC32XX_CLKPWR_PLL397_BIAS_P12_5 0x100 +#define LPC32XX_CLKPWR_PLL397_BIAS_P25 0x140 +#define LPC32XX_CLKPWR_PLL397_BIAS_P37_5 0x180 +#define LPC32XX_CLKPWR_PLL397_BIAS_P50 0x1C0 +#define LPC32XX_CLKPWR_PLL397_BIAS_MASK 0x1C0 +#define LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS _BIT(1) +#define LPC32XX_CLKPWR_SYSCTRL_PLL397_STS _BIT(0) + +/* + * clkpwr_main_osc_ctrl register definitions + */ +#define LPC32XX_CLKPWR_MOSC_ADD_CAP(n) (((n) & 0x7F) << 2) +#define LPC32XX_CLKPWR_MOSC_CAP_MASK (0x7F << 2) +#define LPC32XX_CLKPWR_TEST_MODE _BIT(1) +#define LPC32XX_CLKPWR_MOSC_DISABLE _BIT(0) + +/* + * clkpwr_sysclk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_SYSCTRL_BP_TRIG(n) (((n) & 0x3FF) << 2) +#define LPC32XX_CLKPWR_SYSCTRL_BP_MASK (0x3FF << 2) +#define LPC32XX_CLKPWR_SYSCTRL_USEPLL397 _BIT(1) +#define LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX _BIT(0) + +/* + * clkpwr_lcdclk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT12 0x000 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16 0x040 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT15 0x080 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT24 0x0C0 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN4M 0x100 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN8C 0x140 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN4M 0x180 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN8C 0x1C0 +#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK 0x01C0 +#define LPC32XX_CLKPWR_LCDCTRL_CLK_EN 0x020 +#define LPC32XX_CLKPWR_LCDCTRL_SET_PSCALE(n) ((n - 1) & 0x1F) +#define LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK 0x001F + +/* + * clkpwr_hclkpll_ctrl register definitions + */ +#define LPC32XX_CLKPWR_HCLKPLL_POWER_UP _BIT(16) +#define LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS _BIT(15) +#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS _BIT(14) +#define LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK _BIT(13) +#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(n) (((n) & 0x3) << 11) +#define LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(n) (((n) & 0x3) << 9) +#define LPC32XX_CLKPWR_HCLKPLL_PLLM(n) (((n) & 0xFF) << 1) +#define LPC32XX_CLKPWR_HCLKPLL_PLL_STS _BIT(0) + +/* + * clkpwr_adc_clk_ctrl_1 register definitions + */ +#define LPC32XX_CLKPWR_ADCCTRL1_RTDIV(n) (((n) & 0xFF) << 0) +#define LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL _BIT(8) + +/* + * clkpwr_usb_ctrl register definitions + */ +#define LPC32XX_CLKPWR_USBCTRL_HCLK_EN _BIT(24) +#define LPC32XX_CLKPWR_USBCTRL_USBI2C_EN _BIT(23) +#define LPC32XX_CLKPWR_USBCTRL_USBDVND_EN _BIT(22) +#define LPC32XX_CLKPWR_USBCTRL_USBHSTND_EN _BIT(21) +#define LPC32XX_CLKPWR_USBCTRL_PU_ADD (0x0 << 19) +#define LPC32XX_CLKPWR_USBCTRL_BUS_KEEPER (0x1 << 19) +#define LPC32XX_CLKPWR_USBCTRL_PD_ADD (0x3 << 19) +#define LPC32XX_CLKPWR_USBCTRL_CLK_EN2 _BIT(18) +#define LPC32XX_CLKPWR_USBCTRL_CLK_EN1 _BIT(17) +#define LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP _BIT(16) +#define LPC32XX_CLKPWR_USBCTRL_CCO_BYPASS _BIT(15) +#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_BYPASS _BIT(14) +#define LPC32XX_CLKPWR_USBCTRL_FDBK_SEL_FCLK _BIT(13) +#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_2POW(n) (((n) & 0x3) << 11) +#define LPC32XX_CLKPWR_USBCTRL_PREDIV_PLUS1(n) (((n) & 0x3) << 9) +#define LPC32XX_CLKPWR_USBCTRL_FDBK_PLUS1(n) (((n) & 0xFF) << 1) +#define LPC32XX_CLKPWR_USBCTRL_PLL_STS _BIT(0) + +/* + * clkpwr_sdramclk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_CLK _BIT(22) +#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW _BIT(21) +#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_DAT _BIT(20) +#define LPC32XX_CLKPWR_SDRCLK_SW_DDR_RESET _BIT(19) +#define LPC32XX_CLKPWR_SDRCLK_HCLK_DLY(n) (((n) & 0x1F) << 14) +#define LPC32XX_CLKPWR_SDRCLK_DLY_ADDR_STS _BIT(13) +#define LPC32XX_CLKPWR_SDRCLK_SENS_FACT(n) (((n) & 0x7) << 10) +#define LPC32XX_CLKPWR_SDRCLK_USE_CAL _BIT(9) +#define LPC32XX_CLKPWR_SDRCLK_DO_CAL _BIT(8) +#define LPC32XX_CLKPWR_SDRCLK_CAL_ON_RTC _BIT(7) +#define LPC32XX_CLKPWR_SDRCLK_DQS_DLY(n) (((n) & 0x1F) << 2) +#define LPC32XX_CLKPWR_SDRCLK_USE_DDR _BIT(1) +#define LPC32XX_CLKPWR_SDRCLK_CLK_DIS _BIT(0) + +/* + * clkpwr_ssp_blk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1RX _BIT(5) +#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1TX _BIT(4) +#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0RX _BIT(3) +#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0TX _BIT(2) +#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN _BIT(1) +#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN _BIT(0) + +/* + * clkpwr_i2s_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_I2SCTRL_I2S1_RX_FOR_TX _BIT(6) +#define LPC32XX_CLKPWR_I2SCTRL_I2S1_TX_FOR_RX _BIT(5) +#define LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA _BIT(4) +#define LPC32XX_CLKPWR_I2SCTRL_I2S0_RX_FOR_TX _BIT(3) +#define LPC32XX_CLKPWR_I2SCTRL_I2S0_TX_FOR_RX _BIT(2) +#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN _BIT(1) +#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN _BIT(0) + +/* + * clkpwr_ms_ctrl register definitions + */ +#define LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS _BIT(10) +#define LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN _BIT(9) +#define LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS _BIT(8) +#define LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS _BIT(7) +#define LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS _BIT(6) +#define LPC32XX_CLKPWR_MSCARD_SDCARD_EN _BIT(5) +#define LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(n) ((n) & 0xF) + +/* + * clkpwr_macclk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_MACCTRL_NO_ENET_PIS 0x00 +#define LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS 0x08 +#define LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS 0x18 +#define LPC32XX_CLKPWR_MACCTRL_PINS_MSK 0x18 +#define LPC32XX_CLKPWR_MACCTRL_DMACLK_EN _BIT(2) +#define LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN _BIT(1) +#define LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN _BIT(0) + +/* + * clkpwr_test_clk_sel register definitions + */ +#define LPC32XX_CLKPWR_TESTCLK1_SEL_PERCLK (0x0 << 5) +#define LPC32XX_CLKPWR_TESTCLK1_SEL_RTC (0x1 << 5) +#define LPC32XX_CLKPWR_TESTCLK1_SEL_MOSC (0x2 << 5) +#define LPC32XX_CLKPWR_TESTCLK1_SEL_MASK (0x3 << 5) +#define LPC32XX_CLKPWR_TESTCLK_TESTCLK1_EN _BIT(4) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_HCLK (0x0 << 1) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_PERCLK (0x1 << 1) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_USBCLK (0x2 << 1) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC (0x5 << 1) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_PLL397 (0x7 << 1) +#define LPC32XX_CLKPWR_TESTCLK2_SEL_MASK (0x7 << 1) +#define LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN _BIT(0) + +/* + * clkpwr_sw_int register definitions + */ +#define LPC32XX_CLKPWR_SW_INT(n) (_BIT(0) | (((n) & 0x7F) << 1)) +#define LPC32XX_CLKPWR_SW_GET_ARG(n) (((n) & 0xFE) >> 1) + +/* + * clkpwr_i2c_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE _BIT(4) +#define LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE _BIT(3) +#define LPC32XX_CLKPWR_I2CCLK_I2C1HI_DRIVE _BIT(2) +#define LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN _BIT(1) +#define LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN _BIT(0) + +/* + * clkpwr_key_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN 0x1 + +/* + * clkpwr_adc_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN 0x1 + +/* + * clkpwr_pwm_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(n) (((n) & 0xF) << 8) +#define LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(n) (((n) & 0xF) << 4) +#define LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK 0x8 +#define LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN 0x4 +#define LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK 0x2 +#define LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN 0x1 + +/* + * clkpwr_timer_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_PWMCLK_HSTIMER_EN 0x2 +#define LPC32XX_CLKPWR_PWMCLK_WDOG_EN 0x1 + +/* + * clkpwr_timers_pwms_clk_ctrl_1 register definitions + */ +#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN 0x20 +#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN 0x10 +#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN 0x08 +#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN 0x04 +#define LPC32XX_CLKPWR_TMRPWMCLK_PWM4_EN 0x02 +#define LPC32XX_CLKPWR_TMRPWMCLK_PWM3_EN 0x01 + +/* + * clkpwr_spi_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_SPICLK_SET_SPI2DATIO 0x80 +#define LPC32XX_CLKPWR_SPICLK_SET_SPI2CLK 0x40 +#define LPC32XX_CLKPWR_SPICLK_USE_SPI2 0x20 +#define LPC32XX_CLKPWR_SPICLK_SPI2CLK_EN 0x10 +#define LPC32XX_CLKPWR_SPICLK_SET_SPI1DATIO 0x08 +#define LPC32XX_CLKPWR_SPICLK_SET_SPI1CLK 0x04 +#define LPC32XX_CLKPWR_SPICLK_USE_SPI1 0x02 +#define LPC32XX_CLKPWR_SPICLK_SPI1CLK_EN 0x01 + +/* + * clkpwr_nand_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC 0x20 +#define LPC32XX_CLKPWR_NANDCLK_DMA_RNB 0x10 +#define LPC32XX_CLKPWR_NANDCLK_DMA_INT 0x08 +#define LPC32XX_CLKPWR_NANDCLK_SEL_SLC 0x04 +#define LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN 0x02 +#define LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN 0x01 + +/* + * clkpwr_uart3_clk_ctrl, clkpwr_uart4_clk_ctrl, clkpwr_uart5_clk_ctrl + * and clkpwr_uart6_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_UART_Y_DIV(y) ((y) & 0xFF) +#define LPC32XX_CLKPWR_UART_X_DIV(x) (((x) & 0xFF) << 8) +#define LPC32XX_CLKPWR_UART_USE_HCLK _BIT(16) + +/* + * clkpwr_irda_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_IRDA_Y_DIV(y) ((y) & 0xFF) +#define LPC32XX_CLKPWR_IRDA_X_DIV(x) (((x) & 0xFF) << 8) + +/* + * clkpwr_uart_clk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN _BIT(3) +#define LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN _BIT(2) +#define LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN _BIT(1) +#define LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN _BIT(0) + +/* + * clkpwr_dmaclk_ctrl register definitions + */ +#define LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN 0x1 + +/* + * clkpwr_autoclock register definitions + */ +#define LPC32XX_CLKPWR_AUTOCLK_USB_EN 0x40 +#define LPC32XX_CLKPWR_AUTOCLK_IRAM_EN 0x02 +#define LPC32XX_CLKPWR_AUTOCLK_IROM_EN 0x01 + +/* + * Interrupt controller register offsets + */ +#define LPC32XX_INTC_MASK(x) io_p2v((x) + 0x00) +#define LPC32XX_INTC_RAW_STAT(x) io_p2v((x) + 0x04) +#define LPC32XX_INTC_STAT(x) io_p2v((x) + 0x08) +#define LPC32XX_INTC_POLAR(x) io_p2v((x) + 0x0C) +#define LPC32XX_INTC_ACT_TYPE(x) io_p2v((x) + 0x10) +#define LPC32XX_INTC_TYPE(x) io_p2v((x) + 0x14) + +/* + * Timer/counter register offsets + */ +#define LPC32XX_TIMER_IR(x) io_p2v((x) + 0x00) +#define LPC32XX_TIMER_TCR(x) io_p2v((x) + 0x04) +#define LPC32XX_TIMER_TC(x) io_p2v((x) + 0x08) +#define LPC32XX_TIMER_PR(x) io_p2v((x) + 0x0C) +#define LPC32XX_TIMER_PC(x) io_p2v((x) + 0x10) +#define LPC32XX_TIMER_MCR(x) io_p2v((x) + 0x14) +#define LPC32XX_TIMER_MR0(x) io_p2v((x) + 0x18) +#define LPC32XX_TIMER_MR1(x) io_p2v((x) + 0x1C) +#define LPC32XX_TIMER_MR2(x) io_p2v((x) + 0x20) +#define LPC32XX_TIMER_MR3(x) io_p2v((x) + 0x24) +#define LPC32XX_TIMER_CCR(x) io_p2v((x) + 0x28) +#define LPC32XX_TIMER_CR0(x) io_p2v((x) + 0x2C) +#define LPC32XX_TIMER_CR1(x) io_p2v((x) + 0x30) +#define LPC32XX_TIMER_CR2(x) io_p2v((x) + 0x34) +#define LPC32XX_TIMER_CR3(x) io_p2v((x) + 0x38) +#define LPC32XX_TIMER_EMR(x) io_p2v((x) + 0x3C) +#define LPC32XX_TIMER_CTCR(x) io_p2v((x) + 0x70) + +/* + * ir register definitions + */ +#define LPC32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3)) +#define LPC32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3))) + +/* + * tcr register definitions + */ +#define LPC32XX_TIMER_CNTR_TCR_EN 0x1 +#define LPC32XX_TIMER_CNTR_TCR_RESET 0x2 + +/* + * mcr register definitions + */ +#define LPC32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3)) +#define LPC32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1)) +#define LPC32XX_TIMER_CNTR_MCR_STOP(n) (0x1 << (((n) * 3) + 2)) + +/* + * Standard UART register offsets + */ +#define LPC32XX_UART_DLL_FIFO(x) io_p2v((x) + 0x00) +#define LPC32XX_UART_DLM_IER(x) io_p2v((x) + 0x04) +#define LPC32XX_UART_IIR_FCR(x) io_p2v((x) + 0x08) +#define LPC32XX_UART_LCR(x) io_p2v((x) + 0x0C) +#define LPC32XX_UART_MODEM_CTRL(x) io_p2v((x) + 0x10) +#define LPC32XX_UART_LSR(x) io_p2v((x) + 0x14) +#define LPC32XX_UART_MODEM_STATUS(x) io_p2v((x) + 0x18) +#define LPC32XX_UART_RXLEV(x) io_p2v((x) + 0x1C) + +/* + * UART control structure offsets + */ +#define _UCREG(x) io_p2v(\ + LPC32XX_UART_CTRL_BASE + (x)) +#define LPC32XX_UARTCTL_CTRL _UCREG(0x00) +#define LPC32XX_UARTCTL_CLKMODE _UCREG(0x04) +#define LPC32XX_UARTCTL_CLOOP _UCREG(0x08) + +/* + * ctrl register definitions + */ +#define LPC32XX_UART_U3_MD_CTRL_EN _BIT(11) +#define LPC32XX_UART_IRRX6_INV_EN _BIT(10) +#define LPC32XX_UART_HDPX_EN _BIT(9) +#define LPC32XX_UART_UART6_IRDAMOD_BYPASS _BIT(5) +#define LPC32XX_RT_IRTX6_INV_EN _BIT(4) +#define LPC32XX_RT_IRTX6_INV_MIR_EN _BIT(3) +#define LPC32XX_RT_RX_IRPULSE_3_16_115K _BIT(2) +#define LPC32XX_RT_TX_IRPULSE_3_16_115K _BIT(1) +#define LPC32XX_UART_U5_ROUTE_TO_USB _BIT(0) + +/* + * clkmode register definitions + */ +#define LPC32XX_UART_ENABLED_CLOCKS(n) (((n) >> 16) & 0x7F) +#define LPC32XX_UART_ENABLED_CLOCK(n, u) (((n) >> (16 + (u))) & 0x1) +#define LPC32XX_UART_ENABLED_CLKS_ANY _BIT(14) +#define LPC32XX_UART_CLKMODE_OFF 0x0 +#define LPC32XX_UART_CLKMODE_ON 0x1 +#define LPC32XX_UART_CLKMODE_AUTO 0x2 +#define LPC32XX_UART_CLKMODE_MASK(u) (0x3 << ((((u) - 3) * 2) + 4)) +#define LPC32XX_UART_CLKMODE_LOAD(m, u) ((m) << ((((u) - 3) * 2) + 4)) + +/* + * GPIO Module Register offsets + */ +#define _GPREG(x) io_p2v(LPC32XX_GPIO_BASE + (x)) +#define LPC32XX_GPIO_P_MUX_SET _GPREG(0x100) +#define LPC32XX_GPIO_P_MUX_CLR _GPREG(0x104) +#define LPC32XX_GPIO_P_MUX_STATE _GPREG(0x108) +#define LPC32XX_GPIO_P3_MUX_SET _GPREG(0x110) +#define LPC32XX_GPIO_P3_MUX_CLR _GPREG(0x114) +#define LPC32XX_GPIO_P3_MUX_STATE _GPREG(0x118) +#define LPC32XX_GPIO_P0_MUX_SET _GPREG(0x120) +#define LPC32XX_GPIO_P0_MUX_CLR _GPREG(0x124) +#define LPC32XX_GPIO_P0_MUX_STATE _GPREG(0x128) +#define LPC32XX_GPIO_P1_MUX_SET _GPREG(0x130) +#define LPC32XX_GPIO_P1_MUX_CLR _GPREG(0x134) +#define LPC32XX_GPIO_P1_MUX_STATE _GPREG(0x138) + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/sdcard.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/sdcard.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/sdcard.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/sdcard.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,177 @@ +/* + * asm-arm/arch-lpc32xx/sdcard.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_SDCARD_H +#define __ASM_ARCH_SDCARD_H + +/********************************************************************** +* SD Card controller register offsets +**********************************************************************/ + +#define SD_POWER(x) (x + 0x00) +#define SD_CLOCK(x) (x + 0x04) +#define SD_ARG(x) (x + 0x08) +#define SD_CMD(x) (x + 0x10) +#define SD_RESPCMD(x) (x + 0x14) +#define SD_RESP(x) (x + 0x18) +#define SD_DTIMER(x) (x + 0x28) +#define SD_DLEN(x) (x + 0x2C) +#define SD_DCTRL(x) (x + 0x30) +#define SD_DCNT(x) (x + 0x34) +#define SD_STATUS(x) (x + 0x38) +#define SD_CLEAR(x) (x + 0x3C) +#define SD_MASK0(x) (x + 0x40) +#define SD_MASK1(x) (x + 0x44) +#define SD_FIFOCNT(x) (x + 0x4C) +#define SD_FIFO(x) (x + 0x80) + +/********************************************************************** +* sd_power register definitions +**********************************************************************/ +/* SD bit for enabling open drain mode (1) or pushpull mode (0) */ +#define SD_OPENDRAIN_EN _BIT(6) +/* SD power control mode: power off */ +#define SD_POWER_OFF_MODE 0x0 +/* SD power control mode: power up */ +#define SD_POWER_UP_MODE 0x2 +/* SD power control mode: power on */ +#define SD_POWER_ON_MODE 0x3 +/* SD power control mode mask */ +#define SD_POWER_MODE_MASK 0x3 + +/********************************************************************** +* sd_clock register definitions +**********************************************************************/ +/* SD bit for enabling side bus mode */ +#define SD_WIDEBUSMODE_EN _BIT(11) +/* SD bit for enabling SDCLK clock bypass */ +#define SD_SDCLK_BYPASS _BIT(10) +/* SD bit for enabling clock throttling during idle states */ +#define SD_SDCLK_PWRSAVE _BIT(9) +/* SD bit for enabling the SD clock */ +#define SD_SDCLK_EN _BIT(8) +/* SD clock divider bit mask */ +#define SD_CLKDIV_MASK 0xFF + +/********************************************************************** +* sd_cmd register definitions +**********************************************************************/ +/* SD bit for enabling command path state machine */ +#define SD_CPST_EN _BIT(10) +/* SD bit for wait for CMDPEND prior to sending command */ +#define SD_CMDPEND_WAIT _BIT(9) +/* SD bit for enabling card interrupt request (without timeout) */ +#define SD_INTERRUPT_EN _BIT(8) +/* SD bit for enabling 136-bit response support */ +#define SD_LONGRESP_EN _BIT(7) +/* SD bit for enabling response support */ +#define SD_RESPONSE _BIT(6) +/* SD command mask */ +#define SD_CMD_MASK 0x3F + +/********************************************************************** +* sd_dctrl register definitions +**********************************************************************/ +/* SD data transfer blocksize of 1 byte */ +#define SD_BLKSIZE_1BYTE 0x00 +/* SD data transfer blocksize of 2 bytes */ +#define SD_BLKSIZE_2BYTES 0x10 +/* SD data transfer blocksize of 4 bytes */ +#define SD_BLKSIZE_4BYTES 0x20 +/* SD data transfer blocksize of 8 bytes */ +#define SD_BLKSIZE_8BYTES 0x30 +/* SD data transfer blocksize of 16 bytes */ +#define SD_BLKSIZE_16BYTES 0x40 +/* SD data transfer blocksize of 32 bytes */ +#define SD_BLKSIZE_32BYTES 0x50 +/* SD data transfer blocksize of 64 bytes */ +#define SD_BLKSIZE_64BYTES 0x60 +/* SD data transfer blocksize of 128 bytes */ +#define SD_BLKSIZE_128BYTES 0x70 +/* SD data transfer blocksize of 256 bytes */ +#define SD_BLKSIZE_256BYTES 0x80 +/* SD data transfer blocksize of 512 bytes */ +#define SD_BLKSIZE_512BYTES 0x90 +/* SD data transfer blocksize of 1024 bytes */ +#define SD_BLKSIZE_1024BYTES 0xA0 +/* SD data transfer blocksize of 2048 bytes */ +#define SD_BLKSIZE_2048BYTES 0xB0 +/* SD bit for enabling DMA */ +#define SD_DMA_EN _BIT(3) +/* SD bit for enabling a stream transfer */ +#define SD_STREAM_EN _BIT(2) +/* SD direction bit (1 = receive, 0 = transmit) */ +#define SD_DIR_FROMCARD _BIT(1) +/* SD data transfer enable bit */ +#define SD_DATATRANSFER_EN _BIT(0) + +/********************************************************************** +* sd_status register definitions +* sd_clear register definitions (bits 0..10 only) +* sd_mask0, sd_mask1 register definitions +**********************************************************************/ +/* SD bit for data receive FIFO NOT empty status */ +#define SD_FIFO_RXDATA_AVAIL _BIT(21) +/* SD bit for data transmit FIFO NOT empty status */ +#define SD_FIFO_TXDATA_AVAIL _BIT(20) +/* SD bit for data receive FIFO empty status */ +#define SD_FIFO_RXDATA_EMPTY _BIT(19) +/* SD bit for data transmit FIFO empty status */ +#define SD_FIFO_TXDATA_EMPTY _BIT(18) +/* SD bit for data receive FIFO full status */ +#define SD_FIFO_RXDATA_FULL _BIT(17) +/* SD bit for data transmit FIFO full status */ +#define SD_FIFO_TXDATA_FULL _BIT(16) +/* SD bit for data receive FIFO half-full status */ +#define SD_FIFO_RXDATA_HFULL _BIT(15) +/* SD bit for data transmit FIFO half-empty status */ +#define SD_FIFO_TXDATA_HEMPTY _BIT(14) +/* SD bit for data receive in progress status */ +#define SD_RX_INPROGRESS _BIT(13) +/* SD bit for data transmit in progress status */ +#define SD_TX_INPROGRESS _BIT(12) +/* SD bit for command transfer in progress status */ +#define SD_CMD_INPROGRESS _BIT(11) +/* SD bit for data block send/received complete (CRC good) status */ +#define SD_DATABLK_END _BIT(10) +/* SD bit for start bit detection error status */ +#define SD_STARTBIT_ERR _BIT(9) +/* SD bit for data end (data counter is 0) status */ +#define SD_DATA_END _BIT(8) +/* SD bit for command sent status */ +#define SD_CMD_SENT _BIT(7) +/* SD bit for command response received (CRC good) status */ +#define SD_CMD_RESP_RECEIVED _BIT(6) +/* SD bit for data receive FIFO overflow status */ +#define SD_FIFO_RXDATA_OFLOW _BIT(5) +/* SD bit for data transmit FIFO underflow status */ +#define SD_FIFO_TXDATA_UFLOW _BIT(4) +/* SD bit for data timeout status */ +#define SD_DATA_TIMEOUT _BIT(3) +/* SD bit for command timeout status */ +#define SD_CMD_TIMEOUT _BIT(2) +/* SD bit for data CRC failure status */ +#define SD_DATA_CRC_FAIL _BIT(1) +/* SD bit for command CRC failure status */ +#define SD_CMD_CRC_FAIL _BIT(0) + +#endif /* __ASM_ARCH_SDCARD_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/slcnand.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/slcnand.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/slcnand.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/slcnand.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,103 @@ +/* + * asm-arm/arch-lpc32xx/slcnand.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_SLCNAND_H +#define __ASM_ARCH_SLCNAND_H + +/********************************************************************** +* SLC NAND controller register offsets +**********************************************************************/ + +#define SLC_DATA(x) (x + 0x000) +#define SLC_ADDR(x) (x + 0x004) +#define SLC_CMD(x) (x + 0x008) +#define SLC_STOP(x) (x + 0x00C) +#define SLC_CTRL(x) (x + 0x010) +#define SLC_CFG(x) (x + 0x014) +#define SLC_STAT(x) (x + 0x018) +#define SLC_INT_STAT(x) (x + 0x01C) +#define SLC_IEN(x) (x + 0x020) +#define SLC_ISR(x) (x + 0x024) +#define SLC_ICR(x) (x + 0x028) +#define SLC_TAC(x) (x + 0x02C) +#define SLC_TC(x) (x + 0x030) +#define SLC_ECC(x) (x + 0x034) +#define SLC_DMA_DATA(x) (x + 0x038) + +/********************************************************************** +* slc_ctrl register definitions +**********************************************************************/ +#define SLCCTRL_SW_RESET _BIT(2) /* Reset the NAND controller bit */ +#define SLCCTRL_ECC_CLEAR _BIT(1) /* Reset ECC bit */ +#define SLCCTRL_DMA_START _BIT(0) /* Start DMA channel bit */ + +/********************************************************************** +* slc_cfg register definitions +**********************************************************************/ +#define SLCCFG_CE_LOW _BIT(5) /* Force CE low bit */ +#define SLCCFG_DMA_ECC _BIT(4) /* Enable DMA ECC bit */ +#define SLCCFG_ECC_EN _BIT(3) /* ECC enable bit */ +#define SLCCFG_DMA_BURST _BIT(2) /* DMA burst bit */ +#define SLCCFG_DMA_DIR _BIT(1) /* DMA write(0)/read(1) bit */ +#define SLCCFG_WIDTH _BIT(0) /* External device width, 0=8bit */ + +/********************************************************************** +* slc_stat register definitions +**********************************************************************/ +#define SLCSTAT_DMA_FIFO _BIT(2) /* DMA FIFO has data bit */ +#define SLCSTAT_SLC_FIFO _BIT(1) /* SLC FIFO has data bit */ +#define SLCSTAT_NAND_READY _BIT(0) /* NAND device is ready bit */ + +/********************************************************************** +* slc_int_stat, slc_ien, slc_isr, and slc_icr register definitions +**********************************************************************/ +#define SLCSTAT_INT_TC _BIT(1) /* Transfer count bit */ +#define SLCSTAT_INT_RDY_EN _BIT(0) /* Ready interrupt bit */ + +/********************************************************************** +* slc_tac register definitions +**********************************************************************/ +/* Clock setting for RDY write sample wait time in 2*n clocks */ +#define SLCTAC_WDR(n) (((n) & 0xF) << 28) +/* Write pulse width in clocks cycles, 1 to 16 clocks */ +#define SLCTAC_WWIDTH(n) (((n) & 0xF) << 24) +/* Write hold time of control and data signals, 1 to 16 clocks */ +#define SLCTAC_WHOLD(n) (((n) & 0xF) << 20) +/* Write setup time of control and data signals, 1 to 16 clocks */ +#define SLCTAC_WSETUP(n) (((n) & 0xF) << 16) +/* Clock setting for RDY read sample wait time in 2*n clocks */ +#define SLCTAC_RDR(n) (((n) & 0xF) << 12) +/* Read pulse width in clocks cycles, 1 to 16 clocks */ +#define SLCTAC_RWIDTH(n) (((n) & 0xF) << 8) +/* Read hold time of control and data signals, 1 to 16 clocks */ +#define SLCTAC_RHOLD(n) (((n) & 0xF) << 4) +/* Read setup time of control and data signals, 1 to 16 clocks */ +#define SLCTAC_RSETUP(n) (((n) & 0xF) << 0) + +/********************************************************************** +* slc_ecc register definitions +**********************************************************************/ +/* ECC line party fetch macro */ +#define SLCECC_TO_LINEPAR(n) (((n) >> 6) & 0x7FFF) +#define SLCECC_TO_COLPAR(n) ((n) & 0x3F) + +#endif /* __ASM_ARCH_SLCNAND_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/system.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/system.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/system.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/system.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,52 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/system.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +static void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ + extern void lpc32xx_watchdog_reset(void); + + switch (mode) { + case 's': + case 'h': + printk(KERN_CRIT "RESET: Rebooting system\n"); + + /* Disable interrupts */ + local_irq_disable(); + + lpc32xx_watchdog_reset(); + break; + + default: + /* Do nothing */ + break; + } + + /* Wait for watchdog to reset system */ + while (1) + ; +} + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/timex.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/timex.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/timex.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/timex.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/timex.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +/* + * Rate in Hz of the main system oscillator. This value should match + * the value 'MAIN_OSC_FREQ' in platform.h + */ +#define CLOCK_TICK_RATE 13000000 + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/uncompress.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/uncompress.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/uncompress.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/uncompress.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,83 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/uncompress.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARM_ARCH_UNCOMPRESS_H +#define __ASM_ARM_ARCH_UNCOMPRESS_H + +#include + +#include +#include + +#if defined(CONFIG_SERIAL_HS_LPC32XX_CONSOLE) + +#define HSUART_FIFO (*(volatile unsigned char *)(LPC32XX_HS_UART1_BASE + 0x00)) +#define HSUART_LEVEL (*(volatile unsigned short *)(LPC32XX_HS_UART1_BASE + 0x04)) + +static inline void putc(int ch) +{ + /* Wait for transmit FIFO to empty */ + while ((HSUART_LEVEL & 0xFF00) != 0); + HSUART_FIFO = ch; +} + +static inline void flush(void) +{ + + /* Don't see a reset? */ + + /* Then just wait for transmition to complete */ + while ((HSUART_LEVEL & 0xFF00) != 0); +} + +#else +/* + * Uncompress output is hardcoded to standard UART 5 + */ + +#define UART_FIFO_CTL_TX_RESET (1 << 2) +#define UART_STATUS_TX_MT (1 << 6) + +#define _UARTREG(x) (void __iomem *)(LPC32XX_UART5_BASE + (x)) + +#define LPC32XX_UART_DLLFIFO_O 0x00 +#define LPC32XX_UART_IIRFCR_O 0x08 +#define LPC32XX_UART_LSR_O 0x14 + +static inline void putc(int ch) +{ + /* Wait for transmit FIFO to empty */ + while ((__raw_readl(_UARTREG(LPC32XX_UART_LSR_O)) & + UART_STATUS_TX_MT) == 0) + ; + + __raw_writel((u32) ch, _UARTREG(LPC32XX_UART_DLLFIFO_O)); +} + +static inline void flush(void) +{ + __raw_writel(__raw_readl(_UARTREG(LPC32XX_UART_IIRFCR_O)) | + UART_FIFO_CTL_TX_RESET, _UARTREG(LPC32XX_UART_IIRFCR_O)); +} +#endif + +/* NULL functions; we don't presently need them */ +#define arch_decomp_setup() +#define arch_decomp_wdog() + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/usbd.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/usbd.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/usbd.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/usbd.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,291 @@ +/* + * asm-arm/arch-lpc32xx/usbd.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_USBD_H +#define __ASM_ARCH_USBD_H + +/********************************************************************** +* USE device controller register offsets +**********************************************************************/ + +#define USBD_DEVINTST(x) (x + 0x200) +#define USBD_DEVINTEN(x) (x + 0x204) +#define USBD_DEVINTCLR(x) (x + 0x208) +#define USBD_DEVINTSET(x) (x + 0x20C) +#define USBD_CMDCODE(x) (x + 0x210) +#define USBD_CMDDATA(x) (x + 0x214) +#define USBD_RXDATA(x) (x + 0x218) +#define USBD_TXDATA(x) (x + 0x21C) +#define USBD_RXPLEN(x) (x + 0x220) +#define USBD_TXPLEN(x) (x + 0x224) +#define USBD_CTRL(x) (x + 0x228) +#define USBD_DEVINTPRI(x) (x + 0x22C) +#define USBD_EPINTST(x) (x + 0x230) +#define USBD_EPINTEN(x) (x + 0x234) +#define USBD_EPINTCLR(x) (x + 0x238) +#define USBD_EPINTSET(x) (x + 0x23C) +#define USBD_EPINTPRI(x) (x + 0x240) +#define USBD_REEP(x) (x + 0x244) +#define USBD_EPIND(x) (x + 0x248) +#define USBD_EPMAXPSIZE(x) (x + 0x24C) +/* DMA support registers only below */ +/* Set, clear, or get enabled state of the DMA request status. If + enabled, an IN or OUT token will start a DMA transfer for the EP */ +#define USBD_DMARST(x) (x + 0x250) +#define USBD_DMARCLR(x) (x + 0x254) +#define USBD_DMARSET(x) (x + 0x258) +/* DMA UDCA head pointer */ +#define USBD_UDCAH(x) (x + 0x280) +/* EP DMA status, enable, and disable. This is used to specifically + enabled or disable DMA for a specific EP */ +#define USBD_EPDMAST(x) (x + 0x284) +#define USBD_EPDMAEN(x) (x + 0x288) +#define USBD_EPDMADIS(x) (x + 0x28C) +/* DMA master interrupts enable and pending interrupts */ +#define USBD_DMAINTST(x) (x + 0x290) +#define USBD_DMAINTEN(x) (x + 0x294) +/* DMA end of transfer interrupt enable, disable, status */ +#define USBD_EOTINTST(x) (x + 0x2A0) +#define USBD_EOTINTCLR(x) (x + 0x2A4) +#define USBD_EOTINTSET(x) (x + 0x2A8) +/* New DD request interrupt enable, disable, status */ +#define USBD_NDDRTINTST(x) (x + 0x2AC) +#define USBD_NDDRTINTCLR(x) (x + 0x2B0) +#define USBD_NDDRTINTSET(x) (x + 0x2B4) +/* DMA error interrupt enable, disable, status */ +#define USBD_SYSERRTINTST(x) (x + 0x2B8) +#define USBD_SYSERRTINTCLR(x) (x + 0x2BC) +#define USBD_SYSERRTINTSET(x) (x + 0x2C0) + +/********************************************************************** +* USBD_DEVINTST/USBD_DEVINTEN/USBD_DEVINTCLR/USBD_DEVINTSET/ +* USBD_DEVINTPRI register definitions +**********************************************************************/ +#define USBD_ERR_INT (1 << 9) +#define USBD_EP_RLZED (1 << 8) +#define USBD_TXENDPKT (1 << 7) +#define USBD_RXENDPKT (1 << 6) +#define USBD_CDFULL (1 << 5) +#define USBD_CCEMPTY (1 << 4) +#define USBD_DEV_STAT (1 << 3) +#define USBD_EP_SLOW (1 << 2) +#define USBD_EP_FAST (1 << 1) +#define USBD_FRAME (1 << 0) + +/********************************************************************** +* USBD_EPINTST/USBD_EPINTEN/USBD_EPINTCLR/USBD_EPINTSET/ +* USBD_EPINTPRI register definitions +**********************************************************************/ +/* End point selection macro (RX) */ +#define USBD_RX_EP_SEL(e) (1 << ((e) << 1)) + +/* End point selection macro (TX) */ +#define USBD_TX_EP_SEL(e) (1 << (((e) << 1) + 1)) + +/********************************************************************** +* USBD_REEP/USBD_DMARST/USBD_DMARCLR/USBD_DMARSET/USBD_EPDMAST/ +* USBD_EPDMAEN/USBD_EPDMADIS/ +* USBD_NDDRTINTST/USBD_NDDRTINTCLR/USBD_NDDRTINTSET/ +* USBD_EOTINTST/USBD_EOTINTCLR/USBD_EOTINTSET/ +* USBD_SYSERRTINTST/USBD_SYSERRTINTCLR/USBD_SYSERRTINTSET +* register definitions +**********************************************************************/ +/* Endpoint selection macro */ +#define USBD_EP_SEL(e) (1 << (e)) + +/********************************************************************** +SBD_DMAINTST/USBD_DMAINTEN +**********************************************************************/ +#define USBD_SYS_ERR_INT (1 << 2) +#define USBD_NEW_DD_INT (1 << 1) +#define USBD_EOT_INT (1 << 0) + +/********************************************************************** +* USBD_RXPLEN register definitions +**********************************************************************/ +#define USBD_PKT_RDY (1 << 11) +#define USBD_DV (1 << 10) +#define USBD_PK_LEN_MASK 0x3FF + +/********************************************************************** +* USBD_CTRL register definitions +**********************************************************************/ +#define USBD_LOG_ENDPOINT(e) ((e) << 2) +#define USBD_WR_EN (1 << 1) +#define USBD_RD_EN (1 << 0) + +/********************************************************************** +* USBD_CMDCODE register definitions +**********************************************************************/ +#define USBD_CMD_CODE(c) ((c) << 16) +#define USBD_CMD_PHASE(p) ((p) << 8) + +/********************************************************************** +* USBD_DMARST/USBD_DMARCLR/USBD_DMARSET register definitions +**********************************************************************/ +#define USBD_DMAEP(e) (1 << (e)) + +/* DD (DMA Descriptor) structure, requires word alignment */ +struct lpc32xx_usbd_dd +{ + u32 *dd_next; + u32 dd_setup; + u32 dd_buffer_addr; + u32 dd_status; + u32 dd_iso_ps_mem_addr; +}; + +/* dd_setup bit defines */ +#define DD_SETUP_ATLE_DMA_MODE 0x01 +#define DD_SETUP_NEXT_DD_VALID 0x04 +#define DD_SETUP_ISO_EP 0x10 +#define DD_SETUP_PACKETLEN(n) (((n) & 0x7FF) << 5) +#define DD_SETUP_DMALENBYTES(n)(((n) & 0xFFFF) << 16) + +/* dd_status bit defines */ +#define DD_STATUS_DD_RETIRED 0x01 +#define DD_STATUS_STS_MASK 0x1E +#define DD_STATUS_STS_NS 0x00 /* Not serviced */ +#define DD_STATUS_STS_BS 0x02 /* Being serviced */ +#define DD_STATUS_STS_NC 0x04 /* Normal completion */ +#define DD_STATUS_STS_DUR 0x06 /* Data underrun (short packet) */ +#define DD_STATUS_STS_DOR 0x08 /* Data overrun */ +#define DD_STATUS_STS_SE 0x12 /* System error */ +#define DD_STATUS_PKT_VAL 0x20 /* Packet valid */ +#define DD_STATUS_LSB_EX 0x40 /* LS byte extracted (ATLE) */ +#define DD_STATUS_MSB_EX 0x80 /* MS byte extracted (ATLE) */ +#define DD_STATUS_MLEN(n) (((n) >> 8) & 0x3F) +#define DD_STATUS_CURDMACNT(n) (((n) >> 16) & 0xFFFF) + +/* + * + * Protocol engine bits below + * + */ +/* Device Interrupt Bit Definitions */ +#define FRAME_INT 0x00000001 +#define EP_FAST_INT 0x00000002 +#define EP_SLOW_INT 0x00000004 +#define DEV_STAT_INT 0x00000008 +#define CCEMTY_INT 0x00000010 +#define CDFULL_INT 0x00000020 +#define RxENDPKT_INT 0x00000040 +#define TxENDPKT_INT 0x00000080 +#define EP_RLZED_INT 0x00000100 +#define ERR_INT 0x00000200 + +/* Rx & Tx Packet Length Definitions */ +#define PKT_LNGTH_MASK 0x000003FF +#define PKT_DV 0x00000400 +#define PKT_RDY 0x00000800 + +/* USB Control Definitions */ +#define CTRL_RD_EN 0x00000001 +#define CTRL_WR_EN 0x00000002 + +/* Command Codes */ +#define CMD_SET_ADDR 0x00D00500 +#define CMD_CFG_DEV 0x00D80500 +#define CMD_SET_MODE 0x00F30500 +#define CMD_RD_FRAME 0x00F50500 +#define DAT_RD_FRAME 0x00F50200 +#define CMD_RD_TEST 0x00FD0500 +#define DAT_RD_TEST 0x00FD0200 +#define CMD_SET_DEV_STAT 0x00FE0500 +#define CMD_GET_DEV_STAT 0x00FE0500 +#define DAT_GET_DEV_STAT 0x00FE0200 +#define CMD_GET_ERR_CODE 0x00FF0500 +#define DAT_GET_ERR_CODE 0x00FF0200 +#define CMD_RD_ERR_STAT 0x00FB0500 +#define DAT_RD_ERR_STAT 0x00FB0200 +#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) +#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) +#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) +#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) +#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) +#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) +#define CMD_CLR_BUF 0x00F20500 +#define DAT_CLR_BUF 0x00F20200 +#define CMD_VALID_BUF 0x00FA0500 + +/* Device Address Register Definitions */ +#define DEV_ADDR_MASK 0x7F +#define DEV_EN 0x80 + +/* Device Configure Register Definitions */ +#define CONF_DVICE 0x01 + +/* Device Mode Register Definitions */ +#define AP_CLK 0x01 +#define INAK_CI 0x02 +#define INAK_CO 0x04 +#define INAK_II 0x08 +#define INAK_IO 0x10 +#define INAK_BI 0x20 +#define INAK_BO 0x40 + +/* Device Status Register Definitions */ +#define DEV_CON 0x01 +#define DEV_CON_CH 0x02 +#define DEV_SUS 0x04 +#define DEV_SUS_CH 0x08 +#define DEV_RST 0x10 + +/* Error Code Register Definitions */ +#define ERR_EC_MASK 0x0F +#define ERR_EA 0x10 + +/* Error Status Register Definitions */ +#define ERR_PID 0x01 +#define ERR_UEPKT 0x02 +#define ERR_DCRC 0x04 +#define ERR_TIMOUT 0x08 +#define ERR_EOP 0x10 +#define ERR_B_OVRN 0x20 +#define ERR_BTSTF 0x40 +#define ERR_TGL 0x80 + +/* Endpoint Select Register Definitions */ +#define EP_SEL_F 0x01 +#define EP_SEL_ST 0x02 +#define EP_SEL_STP 0x04 +#define EP_SEL_PO 0x08 +#define EP_SEL_EPN 0x10 +#define EP_SEL_B_1_FULL 0x20 +#define EP_SEL_B_2_FULL 0x40 + +/* Endpoint Status Register Definitions */ +#define EP_STAT_ST 0x01 +#define EP_STAT_DA 0x20 +#define EP_STAT_RF_MO 0x40 +#define EP_STAT_CND_ST 0x80 + +/* Clear Buffer Register Definitions */ +#define CLR_BUF_PO 0x01 + +/* DMA Interrupt Bit Definitions */ +#define EOT_INT 0x01 +#define NDD_REQ_INT 0x02 +#define SYS_ERR_INT 0x04 + + +#endif /* __ASM_ARCH_USBD_H */ diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/vmalloc.h linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/vmalloc.h --- linux-2.6.34/arch/arm/mach-lpc32xx/include/mach/vmalloc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/include/mach/vmalloc.h 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-lpc32xx/include/mach/vmalloc.h + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H + +#define VMALLOC_END 0xF0000000 + +#endif diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/irq.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/irq.c --- linux-2.6.34/arch/arm/mach-lpc32xx/irq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/irq.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,425 @@ +/* + * arch/arm/mach-lpc32xx/irq.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "common.h" + +/* + * Default value representing the Activation polarity of all internal + * interrupt sources + */ +#define MIC_APR_DEFAULT 0x3FF0EFE0 +#define SIC1_APR_DEFAULT 0xFBD27186 +#define SIC2_APR_DEFAULT 0x801810C0 + +/* + * Default value representing the Activation Type of all internal + * interrupt sources. All are level sensitive. + */ +#define MIC_ATR_DEFAULT 0x00000000 +#define SIC1_ATR_DEFAULT 0x00026000 +#define SIC2_ATR_DEFAULT 0x00000000 + +struct lpc32xx_event_group_regs { + void __iomem *enab_reg; + void __iomem *edge_reg; + void __iomem *maskstat_reg; + void __iomem *rawstat_reg; +}; + +static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = { + .enab_reg = LPC32XX_CLKPWR_INT_ER, + .edge_reg = LPC32XX_CLKPWR_INT_AP, + .maskstat_reg = LPC32XX_CLKPWR_INT_SR, + .rawstat_reg = LPC32XX_CLKPWR_INT_RS, +}; + +static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = { + .enab_reg = LPC32XX_CLKPWR_PIN_ER, + .edge_reg = LPC32XX_CLKPWR_PIN_AP, + .maskstat_reg = LPC32XX_CLKPWR_PIN_SR, + .rawstat_reg = LPC32XX_CLKPWR_PIN_RS, +}; + +struct lpc32xx_event_info { + const struct lpc32xx_event_group_regs *event_group; + u32 mask; +}; + +/* + * Maps an IRQ number to and event mask and register + */ +static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = { + [IRQ_LPC32XX_GPI_08] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT, + }, + [IRQ_LPC32XX_GPI_09] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT, + }, + [IRQ_LPC32XX_GPI_19] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT, + }, + [IRQ_LPC32XX_GPI_07] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT, + }, + [IRQ_LPC32XX_GPI_00] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT, + }, + [IRQ_LPC32XX_GPI_01] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT, + }, + [IRQ_LPC32XX_GPI_02] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT, + }, + [IRQ_LPC32XX_GPI_03] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT, + }, + [IRQ_LPC32XX_GPI_04] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT, + }, + [IRQ_LPC32XX_GPI_05] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT, + }, + [IRQ_LPC32XX_GPI_06] = { + .event_group = &lpc32xx_event_pin_regs, + .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT, + }, + [IRQ_LPC32XX_GPIO_00] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT, + }, + [IRQ_LPC32XX_GPIO_01] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT, + }, + [IRQ_LPC32XX_GPIO_02] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT, + }, + [IRQ_LPC32XX_GPIO_03] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT, + }, + [IRQ_LPC32XX_GPIO_04] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT, + }, + [IRQ_LPC32XX_GPIO_05] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT, + }, + [IRQ_LPC32XX_KEY] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT, + }, + [IRQ_LPC32XX_USB_OTG_ATX] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT, + }, + [IRQ_LPC32XX_USB_HOST] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT, + }, + [IRQ_LPC32XX_RTC] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT, + }, + [IRQ_LPC32XX_MSTIMER] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT, + }, + [IRQ_LPC32XX_TS_AUX] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT, + }, + [IRQ_LPC32XX_TS_P] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT, + }, + [IRQ_LPC32XX_TS_IRQ] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT, + }, +}; + +static void get_controller(unsigned int irq, unsigned int *base, + unsigned int *irqbit) +{ + if (irq < 32) { + *base = LPC32XX_MIC_BASE; + *irqbit = 1 << irq; + } else if (irq < 64) { + *base = LPC32XX_SIC1_BASE; + *irqbit = 1 << (irq - 32); + } else { + *base = LPC32XX_SIC2_BASE; + *irqbit = 1 << (irq - 64); + } +} + +static void lpc32xx_mask_irq(unsigned int irq) +{ + unsigned int reg, ctrl, mask; + + get_controller(irq, &ctrl, &mask); + + reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; + __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); +} + +static void lpc32xx_unmask_irq(unsigned int irq) +{ + unsigned int reg, ctrl, mask; + + get_controller(irq, &ctrl, &mask); + + reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; + __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); +} + +static void lpc32xx_ack_irq(unsigned int irq) +{ + unsigned int ctrl, mask; + + get_controller(irq, &ctrl, &mask); + + __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); + + /* Also need to clear pending wake event */ + if (lpc32xx_events[irq].mask != 0) + __raw_writel(lpc32xx_events[irq].mask, + lpc32xx_events[irq].event_group->rawstat_reg); +} + +static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, + int use_edge) +{ + unsigned int reg, ctrl, mask; + + get_controller(irq, &ctrl, &mask); + + /* Activation level, high or low */ + reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl)); + if (use_high_level) + reg |= mask; + else + reg &= ~mask; + __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl)); + + /* Activation type, edge or level */ + reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl)); + if (use_edge) + reg |= mask; + else + reg &= ~mask; + __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl)); + + /* Use same polarity for the wake events */ + if (lpc32xx_events[irq].mask != 0) { + reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg); + + if (use_high_level) + reg |= lpc32xx_events[irq].mask; + else + reg &= ~lpc32xx_events[irq].mask; + + __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg); + } +} + +static int lpc32xx_set_irq_type(unsigned int irq, unsigned int type) +{ + switch (type) { + case IRQ_TYPE_EDGE_RISING: + /* Rising edge sensitive */ + __lpc32xx_set_irq_type(irq, 1, 1); + break; + + case IRQ_TYPE_EDGE_FALLING: + /* Falling edge sensitive */ + __lpc32xx_set_irq_type(irq, 0, 1); + break; + + case IRQ_TYPE_LEVEL_LOW: + /* Low level sensitive */ + __lpc32xx_set_irq_type(irq, 0, 0); + break; + + case IRQ_TYPE_LEVEL_HIGH: + /* High level sensitive */ + __lpc32xx_set_irq_type(irq, 1, 0); + break; + + /* Other modes are not supported */ + default: + return -EINVAL; + } + + return 0; +} + +static int lpc32xx_irq_wake(unsigned int irqno, unsigned int state) +{ + unsigned long eventreg; + + if (lpc32xx_events[irqno].mask != 0) { + eventreg = __raw_readl(lpc32xx_events[irqno]. + event_group->enab_reg); + + if (state) + eventreg |= lpc32xx_events[irqno].mask; + else + eventreg &= ~lpc32xx_events[irqno].mask; + + __raw_writel(eventreg, + lpc32xx_events[irqno].event_group->enab_reg); + + return 0; + } + + return -ENODEV; +} + +static void __init lpc32xx_set_default_mappings(unsigned int apr, + unsigned int atr, unsigned int offset) +{ + unsigned int i; + + /* Set activation levels for each interrupt */ + i = 0; + while (i < 32) { + __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1), + ((atr >> i) & 0x1)); + i++; + } +} + +static struct irq_chip lpc32xx_irq_chip = { + .ack = lpc32xx_ack_irq, + .mask = lpc32xx_mask_irq, + .unmask = lpc32xx_unmask_irq, + .set_type = lpc32xx_set_irq_type, + .set_wake = lpc32xx_irq_wake +}; + +static void lpc32xx_sic1_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE)); + + while (ints != 0) { + int irqno = fls(ints) - 1; + + ints &= ~(1 << irqno); + + generic_handle_irq(LPC32XX_SIC1_IRQ(irqno)); + } +} + +static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE)); + + while (ints != 0) { + int irqno = fls(ints) - 1; + + ints &= ~(1 << irqno); + + generic_handle_irq(LPC32XX_SIC2_IRQ(irqno)); + } +} + +void __init lpc32xx_init_irq(void) +{ + unsigned int i; + + /* Setup MIC */ + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); + __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE)); + __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE)); + + /* Setup SIC1 */ + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); + __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE)); + __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE)); + + /* Setup SIC2 */ + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); + __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE)); + __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE)); + + /* Configure supported IRQ's */ + for (i = 0; i < NR_IRQS; i++) { + set_irq_chip(i, &lpc32xx_irq_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + + /* Set default mappings */ + lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0); + lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32); + lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64); + + /* mask all interrupts except SUBIRQ */ + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); + __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); + + /* MIC SUBIRQx interrupts will route handling to the chain handlers */ + set_irq_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler); + set_irq_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler); + + /* Initially disable all wake events */ + __raw_writel(0, LPC32XX_CLKPWR_P01_ER); + __raw_writel(0, LPC32XX_CLKPWR_INT_ER); + __raw_writel(0, LPC32XX_CLKPWR_PIN_ER); + + /* + * Default wake activation polarities, all pin sources are low edge + * triggered + */ + __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT | + LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT | + LPC32XX_CLKPWR_INTSRC_RTC_BIT, + LPC32XX_CLKPWR_INT_AP); + __raw_writel(0, LPC32XX_CLKPWR_PIN_AP); + + /* Clear latched wake event states */ + __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS), + LPC32XX_CLKPWR_PIN_RS); + __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), + LPC32XX_CLKPWR_INT_RS); +} diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/Kconfig linux-2.6.34-dev/arch/arm/mach-lpc32xx/Kconfig --- linux-2.6.34/arch/arm/mach-lpc32xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/Kconfig 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,140 @@ +if ARCH_LPC32XX + +choice + prompt "LPC32XX SoC based board implementations" + default MACH_PHY3250 + help + This menu selects the LPC3250 board to support for this build + + config MACH_PHY3250 + bool "Phytec 3250 development board" + help + Support for the Phytec 3250 development board + + config MACH_EA3250 + bool "Embedded Artists LPC3250 Developer's Kit" + help + Support for the Embedded Artists LPC3250 Developer's Kit + + config MACH_FDI3250 + bool "Future Designs LPC3250 Touch screen kit" + help + Support for the Future Designs LPC3250 Touch screen kit + + config MACH_STK3250 + bool "Hitex LPC3250 Stick" + help + Hitex LPC3250 Stick + +endchoice + +menu "Embedded Artists Display Selection" + depends on MACH_EA3250 + +config EA3250_QVGA_3_2_LCD + bool "3.2 inch QVGA LCD display (RGB565)" + help + Use 3.2 inch QVGA LCD display + +config EA3250_QVGA_2_8_OLED + bool "2.8 inch QVGA OLED display (RGB565)" + help + Use 2.8 inch QVGA OLED display + +endmenu + + +config SOM9DIMM3250_LCD_PANEL + bool "Enables support for SOM9DIMM-LPC3250 (FDI board) LCDs" + depends on MACH_FDI3250 + default TRUE + help + Say Y here to enable QVGA/VGA panel support + +choice + prompt "FDI LCD Display" + depends on SOM9DIMM3250_LCD_PANEL + default SOM9DIMM3250_LCD_OKAYA_VGA + help + Select type of LCD display to be used. + +config SOM9DIMM3250_LCD_OKAYA_VGA_35 + bool "OKAYA VGA LCD on 3-5 LCD CARRIER board" + help + Select this option if you are using an OKAYA RV640480T on a FDI 3-5 LCD CARRIER board + +config SOM9DIMM3250_LCD_TOSHIBA_QVGA_35 + bool "Toshiba QVGA LCD on 3-5 LCD CARRIER board" + help + Select this option if you are using a Toshiba LTA057A347F on a FDI 3-5 LCD CARRIER board + +endchoice + +menu "Standard UARTS" + +config ARCH_LPC32XX_UART3_SELECT + bool "Add support for standard UART3" + help + Adds support for standard UART 3 when the 8250 serial support + is enabled. + +config ARCH_LPC32XX_UART4_SELECT + bool "Add support for standard UART4" + help + Adds support for standard UART 4 when the 8250 serial support + is enabled. + +config ARCH_LPC32XX_UART5_SELECT + bool "Add support for standard UART5" + default y + help + Adds support for standard UART 5 when the 8250 serial support + is enabled. + +config ARCH_LPC32XX_UART6_SELECT + bool "Add support for standard UART6" + help + Adds support for standard UART 6 when the 8250 serial support + is enabled. + +endmenu + +menu "High speed UARTS" + +config ARCH_LPC32XX_HSUART1_SELECT + bool "Add support for high speed UART1" + help + Enables high speed UART1 as a TTYSx device + +config ARCH_LPC32XX_HSUART2_SELECT + bool "Add support for high speed UART2" + help + Enables high speed UART2 as a TTYSx device + +config ARCH_LPC32XX_HSUART7_SELECT + bool "Add support for high speed UART7" + help + Enables high speed UART7 as a TTYSx device + +endmenu + +menu "LPC32XX chip components" + +config ARCH_LPC32XX_IRAM_FOR_NET + bool "Use IRAM for network buffers" + help + If the total combined required buffer sizes is larger than the + size of IRAM, then SDRAM will be used instead. + +config ARCH_LPC32XX_MII_SUPPORT + bool "Check to enable MII support or leave disabled for RMII support" + default FALSE + help + Say Y here to enable MII support, or N to RMII support. Regardless of + which support is selected, the ethernet interface driver needs to be + selected in the device driver networking section. + +endmenu + +endif + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/Makefile linux-2.6.34-dev/arch/arm/mach-lpc32xx/Makefile --- linux-2.6.34/arch/arm/mach-lpc32xx/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/Makefile 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y := timer.o irq.o common.o serial.o clock.o +obj-y += dma.o gpiolib.o pm.o suspend.o +obj-$(CONFIG_MACH_PHY3250) += phy3250.o +obj-$(CONFIG_MACH_EA3250) += ea3250.o +obj-$(CONFIG_MACH_FDI3250) += fdi3250.o +obj-$(CONFIG_MACH_STK3250) += stick3250.o + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/Makefile.boot linux-2.6.34-dev/arch/arm/mach-lpc32xx/Makefile.boot --- linux-2.6.34/arch/arm/mach-lpc32xx/Makefile.boot 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/Makefile.boot 2010-10-15 14:10:00.108524084 +0100 @@ -0,0 +1,4 @@ + zreladdr-y := 0x80008000 +params_phys-y := 0x80000100 +initrd_phys-y := 0x82000000 + diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/phy3250.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/phy3250.c --- linux-2.6.34/arch/arm/mach-lpc32xx/phy3250.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/phy3250.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,718 @@ +/* + * arch/arm/mach-lpc32xx/phy3250.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "common.h" + +/* + * Mapped GPIOLIB GPIOs + */ +#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) +#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) +#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) +#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1) +#define NAND_WP_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 19) +#define MMC_PWR_ENABLE_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5) +#define MMC_CD_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 1) +#define MMC_WP_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 0) + +/* + * AMBA LCD controller + */ +static struct clcd_panel conn_lcd_panel = { + .mode = { + .name = "QVGA portrait", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 191828, + .left_margin = 22, + .right_margin = 11, + .upper_margin = 2, + .lower_margin = 1, + .hsync_len = 5, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = (TIM2_IVS | TIM2_IHS), + .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) | + CNTL_LCDBPP16_565), + .bpp = 16, +}; +#define PANEL_SIZE (3 * SZ_64K) + +static int lpc32xx_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, + PANEL_SIZE, &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = PANEL_SIZE; + fb->panel = &conn_lcd_panel; + + if (gpio_request(LCD_POWER_GPIO, "LCD power")) + printk(KERN_ERR "Error requesting gpio %u", + LCD_POWER_GPIO); + else if (gpio_direction_output(LCD_POWER_GPIO, 1)) + printk(KERN_ERR "Error setting gpio %u to output", + LCD_POWER_GPIO); + + if (gpio_request(BKL_POWER_GPIO, "LCD backlight power")) + printk(KERN_ERR "Error requesting gpio %u", + BKL_POWER_GPIO); + else if (gpio_direction_output(BKL_POWER_GPIO, 1)) + printk(KERN_ERR "Error setting gpio %u to output", + BKL_POWER_GPIO); + + return 0; +} + +static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void lpc32xx_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +/* + * On some early LCD modules (1307.0), the backlight logic is inverted. + * For those board variants, swap the disable and enable states for + * BKL_POWER_GPIO. +*/ +static void clcd_disable(struct clcd_fb *fb) +{ + gpio_set_value(BKL_POWER_GPIO, 0); + gpio_set_value(LCD_POWER_GPIO, 0); +} + +static void clcd_enable(struct clcd_fb *fb) +{ + gpio_set_value(BKL_POWER_GPIO, 1); + gpio_set_value(LCD_POWER_GPIO, 1); +} + +static struct clcd_board lpc32xx_clcd_data = { + .name = "Phytec LCD", + .check = clcdfb_check, + .decode = clcdfb_decode, + .disable = clcd_disable, + .enable = clcd_enable, + .setup = lpc32xx_clcd_setup, + .mmap = lpc32xx_clcd_mmap, + .remove = lpc32xx_clcd_remove, +}; + +static struct amba_device lpc32xx_clcd_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:clcd", + .platform_data = &lpc32xx_clcd_data, + }, + .res = { + .start = LPC32XX_LCD_BASE, + .end = (LPC32XX_LCD_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_LCD, NO_IRQ}, +}; + +/* + * AMBA SSP (SPI) + */ +static void phy3250_spi_cs_set(u32 control) +{ + gpio_set_value(SPI0_CS_GPIO, (int) control); +} + +static struct pl022_config_chip spi0_chip_info = { + .lbm = LOOPBACK_DISABLED, + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .endian_tx = SSP_TX_LSB, + .endian_rx = SSP_RX_LSB, + .data_size = SSP_DATA_BITS_8, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, + .clk_phase = SSP_CLK_FIRST_EDGE, + .clk_pol = SSP_CLK_POL_IDLE_LOW, + .ctrl_len = SSP_BITS_8, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = phy3250_spi_cs_set, +}; + +static struct pl022_ssp_controller lpc32xx_ssp0_data = { + .bus_id = 0, + .num_chipselect = 1, + .enable_dma = 0, +}; + +static struct amba_device lpc32xx_ssp0_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:ssp0", + .platform_data = &lpc32xx_ssp0_data, + }, + .res = { + .start = LPC32XX_SSP0_BASE, + .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, +}; + +/* AT25 driver registration */ +static int __init phy3250_spi_board_register(void) +{ +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + static struct spi_board_info info[] = { + { + .modalias = "spidev", + .max_speed_hz = 5000000, + .bus_num = 0, + .chip_select = 0, + .controller_data = &spi0_chip_info, + }, + }; + +#else + static struct spi_eeprom eeprom = { + .name = "at25256a", + .byte_len = 0x8000, + .page_size = 64, + .flags = EE_ADDR2, + }; + + static struct spi_board_info info[] = { + { + .modalias = "at25", + .max_speed_hz = 5000000, + .bus_num = 0, + .chip_select = 0, + .platform_data = &eeprom, + .controller_data = &spi0_chip_info, + }, + }; +#endif + return spi_register_board_info(info, ARRAY_SIZE(info)); +} +arch_initcall(phy3250_spi_board_register); + +/* + * Platform Data for UDA1380 Audiocodec. + * As there are no GPIOs for codec power & reset pins, + * dummy GPIO numbers are used. + */ +static struct uda1380_platform_data uda1380_info = { + .gpio_power = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,10), + .gpio_reset = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,2), + .dac_clk = UDA1380_DAC_CLK_WSPLL, +}; + +static struct i2c_board_info __initdata phy3250_i2c_board_info[] = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, + { + I2C_BOARD_INFO("uda1380", 0x18), + .platform_data = &uda1380_info, + }, +}; + +static struct gpio_led phy_leds[] = { + { + .name = "led0", + .gpio = LED_GPIO, + .active_low = 1, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data led_data = { + .leds = phy_leds, + .num_leds = ARRAY_SIZE(phy_leds), +}; + +static struct platform_device lpc32xx_gpio_led_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &led_data, +}; + +/* + * Board specific key scanner driver data + */ +#define PHY3250_KMATRIX_SIZE 1 +static int lpc32xx_keymaps[] = { + KEY_1, /* 1, 1 */ +}; + +static struct lpc32XX_kscan_cfg lpc32xx_kscancfg = { + .matrix_sz = PHY3250_KMATRIX_SIZE, + .keymap = lpc32xx_keymaps, + /* About a 30Hz scan rate based on a 32KHz clock */ + .deb_clks = 3, + .scan_delay = 34, +}; + +static struct resource kscan_resources[] = { + [0] = { + .start = LPC32XX_KSCAN_BASE, + .end = LPC32XX_KSCAN_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LPC32XX_KEY, + .end = IRQ_LPC32XX_KEY, + .flags = IORESOURCE_IRQ, + }, + +}; + +static struct platform_device lpc32xx_kscan_device = { + .name = "lpc32xx_keys", + .id = 0, + .dev = { + .platform_data = &lpc32xx_kscancfg, + }, + .num_resources = ARRAY_SIZE(kscan_resources), + .resource = kscan_resources, +}; + +#if defined (CONFIG_MMC_ARMMMCI) +static u32 mmc_translate_vdd(struct device *dev, unsigned int vdd) +{ + /* Only on and off are supported */ + if (vdd != 0) + gpio_set_value(MMC_PWR_ENABLE_GPIO,1); + else + gpio_set_value(MMC_PWR_ENABLE_GPIO,0); + + return 0; +} + +/* + * Board specific MMC driver data + */ +struct mmci_platform_data lpc32xx_plat_data = { + .ocr_mask = MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33|MMC_VDD_33_34, + .translate_vdd = mmc_translate_vdd, + .capabilities = MMC_CAP_4_BIT_DATA, + .gpio_wp = MMC_WP_GPIO, + .gpio_cd = MMC_CD_GPIO, +}; + +/* + * SD card controller resources + */ +struct amba_device lpc32xx_mmc_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:mmc0", + .platform_data = &lpc32xx_plat_data, + }, + .res = { + .start = LPC32XX_SD_BASE, + .end = (LPC32XX_SD_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_SD0, IRQ_LPC32XX_SD1}, +}; +#endif + + +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) +/* + * Board specific NAND setup data + */ +static int nandwp_enable(int enable) +{ + if (enable != 0) + gpio_set_value(NAND_WP_GPIO,0); + else + gpio_set_value(NAND_WP_GPIO,1); + + return 1; +} +#define BLK_SIZE (512 * 32) +static struct mtd_partition __initdata phy3250_nand_partition[] = { + { + .name = "phy3250-boot", + .offset = 0, + .size = (BLK_SIZE * 25) + }, + { + .name = "phy3250-uboot", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 100) + }, + { + .name = "phy3250-ubt-prms", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 4) + }, + { + .name = "phy3250-kernel", + .offset = MTDPART_OFS_APPEND, + .size = (BLK_SIZE * 256) + }, + { + .name = "phy3250-rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; +static struct mtd_partition * __init phy3250_nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(phy3250_nand_partition); + return phy3250_nand_partition; +} +struct lpc32XX_nand_cfg lpc32xx_nandcfg = +{ + .wdr_clks = 3, + .wwidth = 28571428, + .whold = 100000000, + .wsetup = 66666666, + .rdr_clks = 3, + .rwidth = 28571428, + .rhold = 100000000, + .rsetup = 66666666, + .use16bus = 0, + .enable_write_prot = nandwp_enable, + .partition_info = phy3250_nand_partitions, +}; + +/* + * SLC NAND resources + */ +static struct resource slc_nand_resources[] = { + [0] = { + .start = LPC32XX_SLC_BASE, + .end = LPC32XX_SLC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_FLASH, + .end = IRQ_LPC32XX_FLASH, + .flags = IORESOURCE_IRQ, + }, + +}; +static u64 lpc32xx_slc_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_slc_nand_device = { + .name = "lpc32xx-nand", + .id = 0, + .dev = { + .platform_data = &lpc32xx_nandcfg, + .dma_mask = &lpc32xx_slc_dma_mask, + .coherent_dma_mask = ~0UL, + }, + .num_resources = ARRAY_SIZE(slc_nand_resources), + .resource = slc_nand_resources, +}; +#endif + +/* + * Network Support + */ +static struct lpc_net_cfg lpc32xx_netdata = +{ + .phy_irq = -1, + .phy_mask = 0xFFFFFFF0, +}; + +static struct resource net_resources[] = { + [0] = { + .start = LPC32XX_ETHERNET_BASE, + .end = LPC32XX_ETHERNET_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_ETHERNET, + .end = IRQ_LPC32XX_ETHERNET, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_net_device = { + .name = "lpc-net", + .id = 0, + .dev = { + .dma_mask = &lpc32xx_mac_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &lpc32xx_netdata, + }, + .num_resources = ARRAY_SIZE(net_resources), + .resource = net_resources, +}; + +static struct platform_device *phy3250_devs[] __initdata = { + &lpc32xx_i2c0_device, + &lpc32xx_i2c1_device, + &lpc32xx_i2c2_device, + &lpc32xx_watchdog_device, + &lpc32xx_gpio_led_device, + &lpc32xx_rtc_device, + &lpc32xx_tsc_device, + &lpc32xx_kscan_device, + &lpc32xx_net_device, +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) + &lpc32xx_slc_nand_device, +#endif +#if defined(CONFIG_USB_OHCI_HCD) + &lpc32xx_ohci_device, +#endif +#if defined(CONFIG_USB_GADGET_LPC32XX) + &lpc32xx_usbd_device, +#endif +}; + +static struct amba_device *amba_devs[] __initdata = { + &lpc32xx_clcd_device, + &lpc32xx_ssp0_device, +#if defined(CONFIG_MMC_ARMMMCI) + &lpc32xx_mmc_device, +#endif +}; + +/* + * Board specific functions + */ +static void __init phy3250_board_init(void) +{ + u32 tmp; + int i; + + lpc32xx_gpio_init(); + + /* Register GPIOs used on this board */ + if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) + printk(KERN_ERR "Error requesting gpio %u", + SPI0_CS_GPIO); + else if (gpio_direction_output(SPI0_CS_GPIO, 1)) + printk(KERN_ERR "Error setting gpio %u to output", + SPI0_CS_GPIO); + + if (gpio_request(MMC_PWR_ENABLE_GPIO, "mmc_power_en")) + printk(KERN_ERR "Error requesting gpio %u", + MMC_PWR_ENABLE_GPIO); + else if (gpio_direction_output(MMC_PWR_ENABLE_GPIO, 1)) + printk(KERN_ERR "Error setting gpio %u to output", + MMC_PWR_ENABLE_GPIO); + + /* Setup network interface for RMII mode */ + tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); + + /* Setup SLC NAND controller muxing */ + __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, + LPC32XX_CLKPWR_NAND_CLK_CTRL); + + /* Setup LCD muxing to RGB565 */ + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) & + ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK | + LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK); + tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; + __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); + + /* Set up I2C pull levels */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); + tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | + LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE; + __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); + + /* Disable IrDA pulsing support on UART6 */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + + /* Enable DMA for I2S1 channel */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); + tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA; + __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL); + + lpc32xx_serial_init(); + + /* + * AMBA peripheral clocks need to be enabled prior to AMBA device + * detection or a data fault will occur, so enable the clocks + * here. However, we don't want to enable them if the peripheral + * isn't included in the image + */ +#if defined(CONFIG_MMC_ARMMMCI) + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); +#endif + +#ifdef CONFIG_FB_ARMCLCD + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), + LPC32XX_CLKPWR_LCDCLK_CTRL); +#endif +#ifdef CONFIG_SPI_PL022 + tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), + LPC32XX_CLKPWR_SSP_CLK_CTRL); +#endif + + platform_add_devices(phy3250_devs, ARRAY_SIZE(phy3250_devs)); + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + /* Test clock needed for UDA1380 initial init */ + __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | + LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, + LPC32XX_CLKPWR_TEST_CLK_SEL); + + i2c_register_board_info(0, phy3250_i2c_board_info, + ARRAY_SIZE(phy3250_i2c_board_info)); +} + +static int __init lpc32xx_display_uid(void) +{ + u32 uid[4]; + + lpc32xx_get_uid(uid); + + printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", + uid[3], uid[2], uid[1], uid[0]); + + return 1; +} +arch_initcall(lpc32xx_display_uid); + +/* + * Example code for setting up the BTN1 button (on GPI3) for system + * wakeup and IRQ support. This will allow the GPI3 input to wake + * up the system on a low edge. Edge based interrupts won't be + * registered in the interrupt controller when the system is asleep, + * although they will be registered in the event manager. For this, + * reason, a level based interrupt state is recommended for GPIOs when + * using IRQ and wakeup from GPI edge state. + * + */ +#define BTN1_GPIO LPC32XX_GPIO(LPC32XX_GPI_P3_GRP, 3) +static irqreturn_t phy3250_btn1_irq(int irq, void *dev) +{ + printk(KERN_INFO "GPIO IRQ!\n"); + + return IRQ_HANDLED; +} + +static int __init phy3250_button_setup(void) +{ + int ret; + + if (gpio_request(BTN1_GPIO, "Button 1")) { + printk(KERN_ERR "Error requesting gpio %u", BTN1_GPIO); + return 0; + } + + /* + * Wakeup/irq on low edge - the wakeup state will use the same + * state as the IRQ edge state. + */ + set_irq_type(IRQ_LPC32XX_GPI_03, IRQ_TYPE_EDGE_FALLING); + ret = request_irq(IRQ_LPC32XX_GPI_03, phy3250_btn1_irq, + IRQF_DISABLED, "gpio_btn1_irq", NULL); + if (ret < 0) { + printk(KERN_ERR "Can't request interrupt\n"); + return 0; + } + + enable_irq_wake(IRQ_LPC32XX_GPI_03); + + return 1; +} +device_initcall(phy3250_button_setup); + +MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller") + /* Maintainer: Kevin Wells, NXP Semiconductors */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = phy3250_board_init, +MACHINE_END + +/* For backwards compatibility with older bootloaders only */ +MACHINE_START(LPC3XXX, "Phytec 3250 board with the LPC3250 Microcontroller") + /* Maintainer: Kevin Wells, NXP Semiconductors */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = phy3250_board_init, +MACHINE_END diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/pm.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/pm.c --- linux-2.6.34/arch/arm/mach-lpc32xx/pm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/pm.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,146 @@ +/* + * arch/arm/mach-lpc32xx/pm.c + * + * Original authors: Vitaly Wool, Dmitry Chigirev + * Modified by Kevin Wells + * + * 2005 (c) MontaVista Software, Inc. 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. + */ + +/* + * LPC32XX CPU and system power management + * + * The LCP32XX has three CPU modes for controlling system power: run, + * direct-run, and halt modes. When switching between halt and run modes, + * the CPU transistions through direct-run mode. For Linux, direct-run + * mode is not used in normal operation. Halt mode is used when the + * system is fully suspended. + * + * Run mode: + * The ARM CPU clock (HCLK_PLL), HCLK bus clock, and PCLK bus clocks are + * derived from the HCLK PLL. The HCLK and PCLK bus rates are divided from + * the HCLK_PLL rate. Linux runs in this mode. + * + * Direct-run mode: + * The ARM CPU clock, HCLK bus clock, and PCLK bus clocks are driven from + * SYSCLK. SYSCLK is usually around 13MHz, but may vary based on SYSCLK + * source or the frequency of the main oscillator. In this mode, the + * HCLK_PLL can be safely enabled, changed, or disabled. + * + * Halt mode: + * SYSCLK is gated off and the CPU and system clocks are halted. + * Peripherals based on the 32KHz oscillator clock (ie, RTC, touch, + * key scanner, etc.) still operate if enabled. In this state, an enabled + * system event (ie, GPIO state change, RTC match, key press, etc.) will + * wake the system up back into direct-run mode. + * + * DRAM refresh + * DRAM clocking and refresh are slightly different for systems with DDR + * DRAM or regular SDRAM devices. If SDRAM is used in the system, the + * SDRAM will still be accessible in direct-run mode. In DDR based systems, + * a transistion to direct-run mode will stop all DDR accesses (no clocks). + * Because of this, the code to switch power modes and the code to enter + * and exit DRAM self-refresh modes must not be executed in DRAM. A small + * section of IRAM is used instead for this. + * + * Suspend is handled with the following logic: + * Backup a small area of IRAM used for the suspend code + * Copy suspend code to IRAM + * Transfer control to code in IRAM + * Places DRAMs in self-refresh mode + * Enter direct-run mode + * Save state of HCLK_PLL PLL + * Disable HCLK_PLL PLL + * Enter halt mode - CPU and buses will stop + * System enters direct-run mode when an enabled event occurs + * HCLK PLL state is restored + * Run mode is entered + * DRAMS are placed back into normal mode + * Code execution returns from IRAM + * IRAM code are used for suspend is restored + * Suspend mode is exited + */ + +#include +#include +#include + +#include + +#include +#include +#include "common.h" +#include "clock.h" + +#define TEMP_IRAM_AREA IO_ADDRESS(LPC32XX_IRAM_BASE) + +/* + * Both STANDBY and MEM suspend states are handled the same with no + * loss of CPU or memory state + */ +static int lpc32xx_pm_enter(suspend_state_t state) +{ + int (*lpc32xx_suspend_ptr) (void); + void *iram_swap_area; + + /* Allocate some space for temporary IRAM storage */ + iram_swap_area = kmalloc(lpc32xx_sys_suspend_sz, GFP_KERNEL); + if (!iram_swap_area) { + printk(KERN_ERR + "PM Suspend: cannot allocate memory to save portion " + "of SRAM\n"); + return -ENOMEM; + } + + /* Backup a small area of IRAM used for the suspend code */ + memcpy(iram_swap_area, (void *) TEMP_IRAM_AREA, + lpc32xx_sys_suspend_sz); + + /* + * Copy code to suspend system into IRAM. The suspend code + * needs to run from IRAM as DRAM may no longer be available + * when the PLL is stopped. + */ + memcpy((void *) TEMP_IRAM_AREA, &lpc32xx_sys_suspend, + lpc32xx_sys_suspend_sz); + flush_icache_range((unsigned long)TEMP_IRAM_AREA, + (unsigned long)(TEMP_IRAM_AREA) + lpc32xx_sys_suspend_sz); + + /* Transfer to suspend code in IRAM */ + lpc32xx_suspend_ptr = (void *) TEMP_IRAM_AREA; + flush_cache_all(); + (void) lpc32xx_suspend_ptr(); + + /* Restore original IRAM contents */ + memcpy((void *) TEMP_IRAM_AREA, iram_swap_area, + lpc32xx_sys_suspend_sz); + + kfree(iram_swap_area); + + return 0; +} + +static struct platform_suspend_ops lpc32xx_pm_ops = { + .valid = suspend_valid_only_mem, + .enter = lpc32xx_pm_enter, +}; + +#define EMC_DYN_MEM_CTRL_OFS 0x20 +#define EMC_SRMMC (1 << 3) +#define EMC_CTRL_REG io_p2v(LPC32XX_EMC_BASE + EMC_DYN_MEM_CTRL_OFS) +static int __init lpc32xx_pm_init(void) +{ + /* + * Setup SDRAM self-refresh clock to automatically disable o + * start of self-refresh. This only needs to be done once. + */ + __raw_writel(__raw_readl(EMC_CTRL_REG) | EMC_SRMMC, EMC_CTRL_REG); + + suspend_set_ops(&lpc32xx_pm_ops); + + return 0; +} +arch_initcall(lpc32xx_pm_init); diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/serial.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/serial.c --- linux-2.6.34/arch/arm/mach-lpc32xx/serial.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/serial.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,241 @@ +/* + * arch/arm/mach-lpc32xx/serial.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "common.h" + +#define LPC32XX_SUART_FIFO_SIZE 64 + +/* Standard 8250/16550 compatible serial ports */ +static struct plat_serial8250_port serial_std_platform_data[] = { +#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT + { + .membase = io_p2v(LPC32XX_UART5_BASE), + .mapbase = LPC32XX_UART5_BASE, + .irq = IRQ_LPC32XX_UART_IIR5, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | + UPF_SKIP_TEST, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT + { + .membase = io_p2v(LPC32XX_UART3_BASE), + .mapbase = LPC32XX_UART3_BASE, + .irq = IRQ_LPC32XX_UART_IIR3, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | + UPF_SKIP_TEST, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT + { + .membase = io_p2v(LPC32XX_UART4_BASE), + .mapbase = LPC32XX_UART4_BASE, + .irq = IRQ_LPC32XX_UART_IIR4, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | + UPF_SKIP_TEST, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT + { + .membase = io_p2v(LPC32XX_UART6_BASE), + .mapbase = LPC32XX_UART6_BASE, + .irq = IRQ_LPC32XX_UART_IIR6, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | + UPF_SKIP_TEST, + }, +#endif + { }, +}; + +struct uartinit { + char *uart_ck_name; + u32 ck_mode_mask; + void __iomem *pdiv_clk_reg; +}; + +static struct uartinit uartinit_data[] __initdata = { +#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT + { + .uart_ck_name = "uart5_ck", + .ck_mode_mask = + LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5), + .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT + { + .uart_ck_name = "uart3_ck", + .ck_mode_mask = + LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3), + .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT + { + .uart_ck_name = "uart4_ck", + .ck_mode_mask = + LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4), + .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT + { + .uart_ck_name = "uart6_ck", + .ck_mode_mask = + LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6), + .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, + }, +#endif +}; + +static struct platform_device serial_std_platform_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_std_platform_data, + }, +}; + +/* High speed serial ports */ +static struct uart_port serial_hspd_platform_data[] = { +#ifdef CONFIG_ARCH_LPC32XX_HSUART1_SELECT + { + .membase = io_p2v(LPC32XX_HS_UART1_BASE), + .mapbase = LPC32XX_HS_UART1_BASE, + .irq = IRQ_LPC32XX_UART_IIR1, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_HSUART2_SELECT + { + .membase = io_p2v(LPC32XX_HS_UART2_BASE), + .mapbase = LPC32XX_HS_UART2_BASE, + .irq = IRQ_LPC32XX_UART_IIR2, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF, + }, +#endif +#ifdef CONFIG_ARCH_LPC32XX_HSUART7_SELECT + { + .membase = io_p2v(LPC32XX_HS_UART7_BASE), + .mapbase = LPC32XX_HS_UART7_BASE, + .irq = IRQ_LPC32XX_UART_IIR7, + .uartclk = LPC32XX_MAIN_OSC_FREQ, + .regshift = 2, + .iotype = UPIO_MEM32, + .flags = UPF_BOOT_AUTOCONF, + }, +#endif + { }, +}; + +static struct platform_device serial_hspd_platform_device = { + .name = "lpc32xx_hsuart", + .id = 0, + .dev = { + .platform_data = serial_hspd_platform_data, + }, +}; + +static struct platform_device *lpc32xx_serial_devs[] __initdata = { + &serial_std_platform_device, + &serial_hspd_platform_device, +}; + +void __init lpc32xx_serial_init(void) +{ + u32 tmp, clkmodes = 0; + struct clk *clk; + unsigned int puart; + int i, j; + + /* UART clocks are off, let clock driver manage them */ + __raw_writel(0, LPC32XX_CLKPWR_UART_CLK_CTRL); + + for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) { + clk = clk_get(NULL, uartinit_data[i].uart_ck_name); + if (!IS_ERR(clk)) { + clk_enable(clk); + serial_std_platform_data[i].uartclk = + clk_get_rate(clk); + } + + /* Fall back on main osc rate if clock rate return fails */ + if (serial_std_platform_data[i].uartclk == 0) + serial_std_platform_data[i].uartclk = + LPC32XX_MAIN_OSC_FREQ; + + /* Setup UART clock modes for all UARTs, disable autoclock */ + clkmodes |= uartinit_data[i].ck_mode_mask; + + /* pre-UART clock divider set to 1 */ + __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg); + } + + /* This needs to be done after all UART clocks are setup */ + __raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE); + for (i = 0; i < ARRAY_SIZE(uartinit_data) - 1; i++) { + /* Force a flush of the RX FIFOs to work around a HW bug */ + puart = serial_std_platform_data[i].mapbase; + __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart)); + __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart)); + j = LPC32XX_SUART_FIFO_SIZE; + while (j--) + tmp = __raw_readl(LPC32XX_UART_DLL_FIFO(puart)); + __raw_writel(0, LPC32XX_UART_IIR_FCR(puart)); + } + + /* Setup of HSUART devices */ + for (i = 0; i < ARRAY_SIZE(serial_hspd_platform_data); i++) + serial_hspd_platform_data[i].line = i; + + /* Disable UART5->USB transparent mode or USB won't work */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + + platform_add_devices(lpc32xx_serial_devs, + ARRAY_SIZE(lpc32xx_serial_devs)); +} diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/stick3250.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/stick3250.c --- linux-2.6.34/arch/arm/mach-lpc32xx/stick3250.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/stick3250.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,401 @@ +/* + * arch/arm/mach-lpc32xx/dsi3250.c + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "common.h" + +#include + +/* + * Mapped GPIOLIB GPIOs + */ +#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5) +#define NAND_WP_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 19) +#define SSEL0_GPIO5 LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) + +/* + * Tick LED + */ +static struct gpio_led phy_leds[] = { + { + .name = "led0", + .gpio = LED_GPIO, + .active_low = 1, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data led_data = { + .leds = phy_leds, + .num_leds = ARRAY_SIZE(phy_leds), +}; + +static struct platform_device lpc32xx_gpio_led_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &led_data, +}; + +/* + * AMBA SSP (SPI) + */ +static struct pl022_ssp_controller lpc32xx_ssp0_data = { + .bus_id = 0, + .num_chipselect = 2, + .enable_dma = 0, +}; + +static struct amba_device lpc32xx_ssp0_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "dev:ssp0", + .platform_data = &lpc32xx_ssp0_data, + }, + .res = { + .start = LPC32XX_SSP0_BASE, + .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, +}; + +/* + * Touchscreen device + */ +/* Touch screen chip select function */ +static void ea3250_spi_cs_set(u32 control) +{ + gpio_set_value(SSEL0_GPIO5, (int) control); +} + +/* Touch screen SPI parameters */ +static struct pl022_config_chip spi0_chip_info = { + .lbm = LOOPBACK_DISABLED, + .com_mode = INTERRUPT_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_MASTER, + .slave_tx_disable = 0, + .endian_tx = SSP_TX_LSB, + .endian_rx = SSP_RX_LSB, + .data_size = SSP_DATA_BITS_8, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, + .clk_phase = SSP_CLK_FIRST_EDGE, + .clk_pol = SSP_CLK_POL_IDLE_LOW, + .ctrl_len = SSP_BITS_8, + .wait_state = SSP_MWIRE_WAIT_ZERO, + .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, + .cs_control = ea3250_spi_cs_set, +}; + +/* SPI devices registration */ +static int __init ea3250_spi_devices_register(void) +{ +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + static struct spi_board_info info[] = { + { + .modalias = "spidev", + .max_speed_hz = 2500000, + .bus_num = 0, + .chip_select = 0, + .controller_data = &spi0_chip_info, + }, + }; +#endif + + return spi_register_board_info(info, ARRAY_SIZE(info)); +} +arch_initcall(ea3250_spi_devices_register); + +/* AMBA based devices list */ +static struct amba_device *amba_devs[] __initdata = { + &lpc32xx_ssp0_device, +}; + +/* + * Register AMBA BUS Devices. + * Call AMBA device restration after SPI driver probe(), + * as LCD controller uses SPI driver for initialization + */ +static int __init ea3250_amba_devices_register(void) +{ + u32 i = 0; + + /* Add AMBA devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + return 0; +} +device_initcall_sync(ea3250_amba_devices_register); + +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) +/* + * * Board specific NAND setup data + * */ +static int nandwp_enable(int enable) +{ + if (enable != 0) + gpio_set_value(NAND_WP_GPIO,0); + else + gpio_set_value(NAND_WP_GPIO,1); + + return 1; +} +#define BLK_SIZE (2048 * 64) +static struct mtd_partition __initdata ea3250_nand_partition[] = { + { + .name = "kernel", + .offset = BLK_SIZE * 128, + .size = (BLK_SIZE * 32) + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + }, +}; +static struct mtd_partition * __init ea3250_nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ea3250_nand_partition); + return ea3250_nand_partition; +} +struct lpc32XX_nand_cfg lpc32xx_nandcfg = +{ + .wdr_clks = 14, + .wwidth = 260000000, + .whold = 104000000, + .wsetup = 200000000, + .rdr_clks = 14, + .rwidth = 34666666, + .rhold = 104000000, + .rsetup = 200000000, + .use16bus = 0, + .enable_write_prot = nandwp_enable, + .partition_info = ea3250_nand_partitions, +}; + +/* + * * SLC NAND resources + * */ +static struct resource slc_nand_resources[] = { + [0] = { + .start = LPC32XX_SLC_BASE, + .end = LPC32XX_SLC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_FLASH, + .end = IRQ_LPC32XX_FLASH, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_slc_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_slc_nand_device = { + .name = "lpc32xx-nand", + .id = 0, + .dev = { + .platform_data = &lpc32xx_nandcfg, + .dma_mask = &lpc32xx_slc_dma_mask, + .coherent_dma_mask = ~0UL, + + }, + .num_resources = ARRAY_SIZE(slc_nand_resources), + .resource = slc_nand_resources, +}; +#endif + +/* + * Network Support + */ +static struct lpc_net_cfg lpc32xx_netdata = +{ + .phy_irq = -1, + .phy_mask = 0xFFFFFFF0, +}; + +static struct resource net_resources[] = { + [0] = { + .start = LPC32XX_ETHERNET_BASE, + .end = LPC32XX_ETHERNET_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPC32XX_ETHERNET, + .end = IRQ_LPC32XX_ETHERNET, + .flags = IORESOURCE_IRQ, + }, + +}; + +static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; +static struct platform_device lpc32xx_net_device = { + .name = "lpc-net", + .id = 0, + .dev = { + .dma_mask = &lpc32xx_mac_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &lpc32xx_netdata, + }, + .num_resources = ARRAY_SIZE(net_resources), + .resource = net_resources, +}; + +/* + * I2C devices support + */ + +static struct platform_device* stick3250_devs[] __initdata = { + &lpc32xx_i2c0_device, + &lpc32xx_i2c1_device, + &lpc32xx_i2c2_device, + &lpc32xx_watchdog_device, + &lpc32xx_gpio_led_device, + &lpc32xx_rtc_device, + &lpc32xx_net_device, +#if defined(CONFIG_MTD_NAND_SLC_LPC32XX) + &lpc32xx_slc_nand_device, +#endif +#if defined(CONFIG_USB_OHCI_HCD) + &lpc32xx_ohci_device, +#endif +#if defined(CONFIG_USB_GADGET_LPC32XX) + &lpc32xx_usbd_device, +#endif +}; + +/* + * Board specific functions + */ +void __init stick3250_board_init(void) +{ + u32 tmp; + + /* Intiliase GPIO */ + lpc32xx_gpio_init(); + + /* Set SPI CS GPIO to output */ + gpio_request(SSEL0_GPIO5, "spi0 cs"); + gpio_direction_output(SSEL0_GPIO5, 1); + + /* Setup network interface for RMII mode */ + tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); + + /* Setup SLC NAND controller */ + __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, + LPC32XX_CLKPWR_NAND_CLK_CTRL); + + /* Initalise Serial device */ + lpc32xx_serial_init(); + + /* + * AMBA peripheral clocks need to be enabled prior to AMBA device + * detection or a data fault will occur, so enable the clocks + * here. However, we don't want to enable them if the peripheral + * isn't included in the image + */ + /* Initialise SSP clock */ + tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); + __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), + LPC32XX_CLKPWR_SSP_CLK_CTRL); + + /* Enable SD card clock so AMBA driver will work correctly. The + AMBA driver needs the clock before the SD card controller + driver initializes it. The clock will turn off once the driver + has been initialized. */ + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | + LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + + /* Disable UART5->USB transparent mode or USB won't work */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + + /* Add platform devcies */ + platform_add_devices(stick3250_devs, ARRAY_SIZE(stick3250_devs)); +} + +static int __init lpc32xx_display_uid(void) +{ + u32 uid[4]; + + lpc32xx_get_uid(uid); + + printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", + uid[3], uid[2], uid[1], uid[0]); + + return 1; +} +arch_initcall(lpc32xx_display_uid); + +MACHINE_START (FDI3250, "Hitex LPC3250 Stick") + /* Maintainer: Embedded Artists */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = stick3250_board_init, + MACHINE_END + +/* For backwards compatibility with older bootloaders only */ +MACHINE_START (LPC3XXX, "Hitex LPC3250 Stick") + /* Maintainer: Embedded Artists */ + .phys_io = LPC32XX_UART5_BASE, + .io_pg_offst = ((IO_ADDRESS(LPC32XX_UART5_BASE))>>18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = lpc32xx_map_io, + .init_irq = lpc32xx_init_irq, + .timer = &lpc32xx_timer, + .init_machine = stick3250_board_init, + MACHINE_END diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/suspend.S linux-2.6.34-dev/arch/arm/mach-lpc32xx/suspend.S --- linux-2.6.34/arch/arm/mach-lpc32xx/suspend.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/suspend.S 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,151 @@ +/* + * arch/arm/mach-lpc32xx/suspend.S + * + * Original authors: Dmitry Chigirev, Vitaly Wool + * Modified by Kevin Wells + * + * 2005 (c) MontaVista Software, Inc. 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 + +/* Using named register defines makes the code easier to follow */ +#define WORK1_REG r0 +#define WORK2_REG r1 +#define SAVED_HCLK_DIV_REG r2 +#define SAVED_HCLK_PLL_REG r3 +#define SAVED_DRAM_CLKCTRL_REG r4 +#define SAVED_PWR_CTRL_REG r5 +#define CLKPWRBASE_REG r6 +#define EMCBASE_REG r7 + +#define LPC32XX_EMC_STATUS_OFFS 0x04 +#define LPC32XX_EMC_STATUS_BUSY 0x1 +#define LPC32XX_EMC_STATUS_SELF_RFSH 0x4 + +#define LPC32XX_CLKPWR_PWR_CTRL_OFFS 0x44 +#define LPC32XX_CLKPWR_HCLK_DIV_OFFS 0x40 +#define LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS 0x58 + +#define CLKPWR_PCLK_DIV_MASK 0xFFFFFE7F + + .text + +ENTRY(lpc32xx_sys_suspend) + @ Save a copy of the used registers in IRAM, r0 is corrupted + adr r0, tmp_stack_end + stmfd r0!, {r3 - r7, sp, lr} + + @ Load a few common register addresses + adr WORK1_REG, reg_bases + ldr CLKPWRBASE_REG, [WORK1_REG, #0] + ldr EMCBASE_REG, [WORK1_REG, #4] + + ldr SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + orr WORK1_REG, SAVED_PWR_CTRL_REG, #LPC32XX_CLKPWR_SDRAM_SELF_RFSH + + @ Wait for SDRAM busy status to go busy and then idle + @ This guarantees a small windows where DRAM isn't busy +1: + ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS] + and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY + cmp WORK2_REG, #LPC32XX_EMC_STATUS_BUSY + bne 1b @ Branch while idle +2: + ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS] + and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY + cmp WORK2_REG, #LPC32XX_EMC_STATUS_BUSY + beq 2b @ Branch until idle + + @ Setup self-refresh with support for manual exit of + @ self-refresh mode + str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + orr WORK2_REG, WORK1_REG, #LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH + str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + + @ Wait for self-refresh acknowledge, clocks to the DRAM device + @ will automatically stop on start of self-refresh +3: + ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS] + and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH + cmp WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH + bne 3b @ Branch until self-refresh mode starts + + @ Enter direct-run mode from run mode + bic WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_SELECT_RUN_MODE + str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + + @ Safe disable of DRAM clock in EMC block, prevents DDR sync + @ issues on restart + ldr SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_HCLK_DIV_OFFS] + and WORK2_REG, SAVED_HCLK_DIV_REG, #CLKPWR_PCLK_DIV_MASK + str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLK_DIV_OFFS] + + @ Save HCLK PLL state and disable HCLK PLL + ldr SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS] + bic WORK2_REG, SAVED_HCLK_PLL_REG, #LPC32XX_CLKPWR_HCLKPLL_POWER_UP + str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS] + + @ Enter stop mode until an enabled event occurs + orr WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL + str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + .rept 9 + nop + .endr + + @ Clear stop status + bic WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL + + @ Restore original HCLK PLL value and wait for PLL lock + str SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS] +4: + ldr WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS] + and WORK2_REG, WORK2_REG, #LPC32XX_CLKPWR_HCLKPLL_PLL_STS + bne 4b + + @ Re-enter run mode with self-refresh flag cleared, but no DRAM + @ update yet. DRAM is still in self-refresh + str SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + + @ Restore original DRAM clock mode to restore DRAM clocks + str SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_HCLK_DIV_OFFS] + + @ Clear self-refresh mode + orr WORK1_REG, SAVED_PWR_CTRL_REG,\ + #LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH + str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + str SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\ + #LPC32XX_CLKPWR_PWR_CTRL_OFFS] + + @ Wait for EMC to clear self-refresh mode +5: + ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS] + and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH + bne 5b @ Branch until self-refresh has exited + + @ restore regs and return + adr r0, tmp_stack + ldmfd r0!, {r3 - r7, sp, pc} + +reg_bases: + .long IO_ADDRESS(LPC32XX_CLK_PM_BASE) + .long IO_ADDRESS(LPC32XX_EMC_BASE) + +tmp_stack: + .long 0, 0, 0, 0, 0, 0, 0 +tmp_stack_end: + +ENTRY(lpc32xx_sys_suspend_sz) + .word . - lpc32xx_sys_suspend diff -purN linux-2.6.34/arch/arm/mach-lpc32xx/timer.c linux-2.6.34-dev/arch/arm/mach-lpc32xx/timer.c --- linux-2.6.34/arch/arm/mach-lpc32xx/timer.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/mach-lpc32xx/timer.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,182 @@ +/* + * arch/arm/mach-lpc32xx/timer.c + * + * Author: Kevin Wells + * + * Copyright (C) 2009 - 2010 NXP Semiconductors + * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven + * Ed Schouten + * Laurens Timmermans + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "common.h" + +static cycle_t lpc32xx_clksrc_read(struct clocksource *cs) +{ + return (cycle_t)__raw_readl(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE)); +} + +static struct clocksource lpc32xx_clksrc = { + .name = "lpc32xx_clksrc", + .shift = 24, + .rating = 300, + .read = lpc32xx_clksrc_read, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int lpc32xx_clkevt_next_event(unsigned long delta, + struct clock_event_device *dev) +{ + __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, + LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, + LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + + return 0; +} + +static void lpc32xx_clkevt_mode(enum clock_event_mode mode, + struct clock_event_device *dev) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + WARN_ON(1); + break; + + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_SHUTDOWN: + /* + * Disable the timer. When using oneshot, we must also + * disable the timer to wait for the first call to + * set_next_event(). + */ + __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device lpc32xx_clkevt = { + .name = "lpc32xx_clkevt", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .rating = 300, + .set_next_event = lpc32xx_clkevt_next_event, + .set_mode = lpc32xx_clkevt_mode, +}; + +static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &lpc32xx_clkevt; + + /* Clear match */ + __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), + LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction lpc32xx_timer_irq = { + .name = "LPC32XX Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = lpc32xx_timer_interrupt, +}; + +/* + * The clock management driver isn't initialized at this point, so the + * clocks need to be enabled here manually and then tagged as used in + * the clock driver initialization + */ +static void __init lpc32xx_timer_init(void) +{ + u32 clkrate, pllreg; + + /* Enable timer clock */ + __raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN | + LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, + LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1); + + /* + * The clock driver isn't initialized at this point. So determine if + * the SYSCLK is driven from the PLL397 or main oscillator and then use + * it to compute the PLL frequency and the PCLK divider to get the base + * timer rates. This rate is needed to compute the tick rate. + */ + if (clk_is_sysclk_mainosc() != 0) + clkrate = LPC32XX_MAIN_OSC_FREQ; + else + clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ; + + /* Get ARM HCLKPLL register and convert it into a frequency */ + pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; + clkrate = clk_get_pllrate_from_reg(clkrate, pllreg); + + /* Get PCLK divider and divide ARM PLL clock by it to get timer rate */ + clkrate = clkrate / clk_get_pclk_div(); + + /* Initial timer setup */ + __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), + LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); + __raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) | + LPC32XX_TIMER_CNTR_MCR_STOP(0) | + LPC32XX_TIMER_CNTR_MCR_RESET(0), + LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE)); + + /* Setup tick interrupt */ + setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq); + + /* Setup the clockevent structure. */ + lpc32xx_clkevt.mult = div_sc(clkrate, NSEC_PER_SEC, + lpc32xx_clkevt.shift); + lpc32xx_clkevt.max_delta_ns = clockevent_delta2ns(-1, + &lpc32xx_clkevt); + lpc32xx_clkevt.min_delta_ns = clockevent_delta2ns(1, + &lpc32xx_clkevt) + 1; + lpc32xx_clkevt.cpumask = cpumask_of(0); + clockevents_register_device(&lpc32xx_clkevt); + + /* Use timer1 as clock source. */ + __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, + LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); + __raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE)); + __raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, + LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); + lpc32xx_clksrc.mult = clocksource_hz2mult(clkrate, + lpc32xx_clksrc.shift); + clocksource_register(&lpc32xx_clksrc); +} + +struct sys_timer lpc32xx_timer = { + .init = &lpc32xx_timer_init, +}; + diff -purN linux-2.6.34/arch/arm/Makefile linux-2.6.34-dev/arch/arm/Makefile --- linux-2.6.34/arch/arm/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/arch/arm/Makefile 2010-10-15 14:10:00.098525816 +0100 @@ -139,6 +139,7 @@ machine-$(CONFIG_ARCH_KS8695) := ks8695 machine-$(CONFIG_ARCH_L7200) := l7200 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_LOKI) := loki +machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx machine-$(CONFIG_ARCH_MMP) := mmp machine-$(CONFIG_ARCH_MSM) := msm machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 diff -purN linux-2.6.34/drivers/i2c/busses/Kconfig linux-2.6.34-dev/drivers/i2c/busses/Kconfig --- linux-2.6.34/drivers/i2c/busses/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/i2c/busses/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -477,7 +477,7 @@ config I2C_PASEMI config I2C_PNX tristate "I2C bus support for Philips PNX targets" - depends on ARCH_PNX4008 + depends on ARCH_PNX4008 || ARCH_LPC32XX help This driver supports the Philips IP3204 I2C IP block master and/or slave controller diff -purN linux-2.6.34/drivers/input/keyboard/Kconfig linux-2.6.34-dev/drivers/input/keyboard/Kconfig --- linux-2.6.34/drivers/input/keyboard/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/input/keyboard/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -273,6 +273,15 @@ config KEYBOARD_LOCOMO To compile this driver as a module, choose M here: the module will be called locomokbd. +config KEYBOARD_LPC32XX + tristate "LPC32XX matrix key scanner support" + depends on ARCH_LPC32XX + help + Say Y here if you want to use the LPC32XX keyscanner interface. + + To compile this driver as a module, choose M here: the + module will be called lpc32xx_keys. + config KEYBOARD_MAPLE tristate "Maple bus keyboard" depends on SH_DREAMCAST && MAPLE diff -purN linux-2.6.34/drivers/input/keyboard/lpc32xx_keys.c linux-2.6.34-dev/drivers/input/keyboard/lpc32xx_keys.c --- linux-2.6.34/drivers/input/keyboard/lpc32xx_keys.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/input/keyboard/lpc32xx_keys.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,293 @@ +/* + * linux/drivers/input/keyboard/lpc32xx-keys.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Key scanner register offsets + */ +#define LPC32XX_KS_DEB(x) ((x) + 0x00) +#define LPC32XX_KS_STATE_COND(x) ((x) + 0x04) +#define LPC32XX_KS_IRQ(x) ((x) + 0x08) +#define LPC32XX_KS_SCAN_CTL(x) ((x) + 0x0C) +#define LPC32XX_KS_FAST_TST(x) ((x) + 0x10) +#define LPC32XX_KS_MATRIX_DIM(x) ((x) + 0x14) +#define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + (y << 2)) + +#define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF) + +#define LPC32XX_KSCAN_SCOND_IN_IDLE 0x0 +#define LPC32XX_KSCAN_SCOND_IN_SCANONCE 0x1 +#define LPC32XX_KSCAN_SCOND_IN_IRQGEN 0x2 +#define LPC32XX_KSCAN_SCOND_IN_SCAN_MATRIX 0x3 + +#define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1 + +#define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF) + +#define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1 +#define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2 + +#define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF) + +struct lpc32xx_kscan_drv { + struct input_dev *input; + struct lpc32XX_kscan_cfg *kscancfg; + struct clk *clk; + void __iomem *kscan_base; + int irq; + u8 lastkeystates[8]; +}; + +static void lpc32xx_mod_states(struct lpc32xx_kscan_drv *kscandat, int off) +{ + u8 st, key; + int j, scancode, keycode; + + key = (u8) __raw_readl(LPC32XX_KS_DATA(kscandat->kscan_base, off)); + if (key != kscandat->lastkeystates[off]) { + for (j = 0; j < kscandat->kscancfg->matrix_sz; j++) { + st = key & (1 << j); + if (st != (kscandat->lastkeystates[off] & (1 << j))) { + /* Key state changed, signal an event */ + scancode = (int) (j * + kscandat->kscancfg->matrix_sz) + off; + keycode = + kscandat->kscancfg->keymap[scancode]; + input_report_key(kscandat->input, keycode, + (st != 0)); + } + } + + kscandat->lastkeystates[off] = key; + } +} + +static irqreturn_t lpc32xx_kscan_irq(int irq, void *dev_id) +{ + int i; + struct lpc32xx_kscan_drv *kscandat = + (struct lpc32xx_kscan_drv *) dev_id; + + for (i = 0; i < kscandat->kscancfg->matrix_sz; i++) + lpc32xx_mod_states(kscandat, i); + + __raw_writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); + + input_sync(kscandat->input); + + return IRQ_HANDLED; +} + +static int __devinit lpc32xx_kscan_probe(struct platform_device *pdev) +{ + struct lpc32xx_kscan_drv *kscandat; + struct resource *res; + int retval, i; + + kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); + if (unlikely(!kscandat)) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "failed to get platform I/O memory\n"); + retval = -EBUSY; + goto err_nores; + } + + res = request_mem_region(res->start, resource_size(res), pdev->name); + if (res == NULL) { + dev_err(&pdev->dev, "failed to request I/O memory\n"); + retval = -EBUSY; + goto err_nores; + } + + kscandat->kscan_base = ioremap(res->start, res->end - res->start + 1); + if (kscandat->kscan_base == NULL) { + dev_err(&pdev->dev, "failed to remap I/O memory\n"); + retval = -EBUSY; + goto err_noremap; + } + + /* Get the key scanner clock */ + kscandat->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(kscandat->clk)) { + dev_err(&pdev->dev, "failed to get clock\n"); + retval = -ENODEV; + goto err_noclk; + } + clk_enable(kscandat->clk); + + kscandat->irq = platform_get_irq(pdev, 0); + if ((kscandat->irq < 0) || (kscandat->irq >= NR_IRQS)) { + dev_err(&pdev->dev, "failed to get platform irq\n"); + retval = -EINVAL; + goto err_noirq; + } + retval = request_irq(kscandat->irq, lpc32xx_kscan_irq, + 0, pdev->name, kscandat); + if (retval) { + dev_err(&pdev->dev, "failed to request irq\n"); + goto err_noirq; + } + + kscandat->input = input_allocate_device(); + if (kscandat->input == NULL) { + dev_err(&pdev->dev, "failed to allocate device\n"); + retval = -ENOMEM; + goto err_noalloc; + } + + kscandat->kscancfg = (struct lpc32XX_kscan_cfg *) + pdev->dev.platform_data; + platform_set_drvdata(pdev, kscandat); + + /* Setup key input */ + kscandat->input->evbit[0] = BIT_MASK(EV_KEY); + kscandat->input->name = pdev->name; + kscandat->input->phys = "matrix-keys/input0"; + kscandat->input->dev.parent = &pdev->dev; + kscandat->input->id.vendor = 0x0001; + kscandat->input->id.product = 0x0001; + kscandat->input->id.version = 0x0100; + for (i = 0; i < kscandat->kscancfg->matrix_sz; i++) + __set_bit(kscandat->kscancfg->keymap[i], + kscandat->input->keybit); + + input_set_capability(kscandat->input, EV_MSC, MSC_SCAN); + + retval = input_register_device(kscandat->input); + if (retval) { + dev_err(&pdev->dev, "failed to register input device\n"); + goto err_notregistered; + } + + /* Configure the key scanner */ + __raw_writel(kscandat->kscancfg->deb_clks, + LPC32XX_KS_DEB(kscandat->kscan_base)); + __raw_writel(kscandat->kscancfg->scan_delay, + LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); + __raw_writel(LPC32XX_KSCAN_FTST_USE32K_CLK, + LPC32XX_KS_FAST_TST(kscandat->kscan_base)); + __raw_writel(kscandat->kscancfg->matrix_sz, + LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base)); + __raw_writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); + + return 0; + +err_notregistered: + input_free_device(kscandat->input); +err_noalloc: + free_irq(kscandat->irq, pdev); +err_noirq: + clk_put(kscandat->clk); +err_noclk: + iounmap(kscandat->kscan_base); +err_noremap: + release_mem_region(res->start, resource_size(res)); +err_nores: + kfree(kscandat); + + return retval; +} + +static int __devexit lpc32xx_kscan_remove(struct platform_device *pdev) +{ + struct resource *res; + struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); + + free_irq(kscandat->irq, pdev); + input_unregister_device(kscandat->input); + clk_put(kscandat->clk); + iounmap(kscandat->kscan_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + + kfree(kscandat); + + return 0; +} + +#ifdef CONFIG_PM +static int lpc32xx_kscan_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); + + /* Clear IRQ and disable clock */ + __raw_writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); + clk_disable(kscandat->clk); + + return 0; +} + +static int lpc32xx_kscan_resume(struct platform_device *pdev) +{ + struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); + + /* Enable clock and clear IRQ */ + clk_enable(kscandat->clk); + __raw_writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); + + return 0; +} +#else +#define lpc32xx_kscan_suspend NULL +#define lpc32xx_kscan_resume NULL +#endif + +static struct platform_driver lpc32xx_kscan_driver = { + .probe = lpc32xx_kscan_probe, + .remove = __devexit_p(lpc32xx_kscan_remove), + .suspend = lpc32xx_kscan_suspend, + .resume = lpc32xx_kscan_resume, + .driver = { + .name = "lpc32xx_keys", + } +}; + +static int __init lpc32xx_kscan_init(void) +{ + return platform_driver_register(&lpc32xx_kscan_driver); +} + +static void __exit lpc32xx_kscan_exit(void) +{ + platform_driver_unregister(&lpc32xx_kscan_driver); +} + +module_init(lpc32xx_kscan_init); +module_exit(lpc32xx_kscan_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kevin Wells "); +MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); diff -purN linux-2.6.34/drivers/input/keyboard/Makefile linux-2.6.34-dev/drivers/input/keyboard/Makefile --- linux-2.6.34/drivers/input/keyboard/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/input/keyboard/Makefile 2010-10-15 14:10:00.118524167 +0100 @@ -23,6 +23,7 @@ obj-$(CONFIG_KEYBOARD_HP7XX) += jornada obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o +obj-$(CONFIG_KEYBOARD_LPC32XX) += lpc32xx_keys.o obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o diff -purN linux-2.6.34/drivers/input/touchscreen/Kconfig linux-2.6.34-dev/drivers/input/touchscreen/Kconfig --- linux-2.6.34/drivers/input/touchscreen/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/input/touchscreen/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -205,6 +205,16 @@ config TOUCHSCREEN_WACOM_W8001 To compile this driver as a module, choose M here: the module will be called wacom_w8001. +config TOUCHSCREEN_LPC32XX + tristate "LPC32XX touchscreen controller" + depends on ARCH_LPC32XX + help + Say Y here if you have a LPC32XX device and want + to support the built-in touchscreen. + + To compile this driver as a module, choose M here: the + module will be called lpc32xx_ts. + config TOUCHSCREEN_MCS5000 tristate "MELFAS MCS-5000 touchscreen" depends on I2C diff -purN linux-2.6.34/drivers/input/touchscreen/lpc32xx_ts.c linux-2.6.34-dev/drivers/input/touchscreen/lpc32xx_ts.c --- linux-2.6.34/drivers/input/touchscreen/lpc32xx_ts.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/input/touchscreen/lpc32xx_ts.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,371 @@ +/* + * drivers/input/touchscreen/lpc32xx_tsc.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Touchscreen controller register offsets + */ +#define LPC32XX_TSC_STAT(x) ((x) + 0x00) +#define LPC32XX_TSC_SEL(x) ((x) + 0x04) +#define LPC32XX_TSC_CON(x) ((x) + 0x08) +#define LPC32XX_TSC_FIFO(x) ((x) + 0x0C) +#define LPC32XX_TSC_DTR(x) ((x) + 0x10) +#define LPC32XX_TSC_RTR(x) ((x) + 0x14) +#define LPC32XX_TSC_UTR(x) ((x) + 0x18) +#define LPC32XX_TSC_TTR(x) ((x) + 0x1C) +#define LPC32XX_TSC_DXP(x) ((x) + 0x20) +#define LPC32XX_TSC_MIN_X(x) ((x) + 0x24) +#define LPC32XX_TSC_MAX_X(x) ((x) + 0x28) +#define LPC32XX_TSC_MIN_Y(x) ((x) + 0x2C) +#define LPC32XX_TSC_MAX_Y(x) ((x) + 0x30) +#define LPC32XX_TSC_AUX_UTR(x) ((x) + 0x34) +#define LPC32XX_TSC_AUX_MIN(x) ((x) + 0x38) +#define LPC32XX_TSC_AUX_MAX(x) ((x) + 0x3C) + +#define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8) +#define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7) + +#define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11) +#define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - s) << 7) +#define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - s) << 4) +#define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2) +#define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0) + +#define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31) +#define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16) +#define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF) + +#define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF + +#define MOD_NAME "lpc32xx-ts" + +struct lpc32xx_tsc_t { + struct input_dev *dev; + void __iomem *tsc_base; + int irq; + struct clk *clk; + int suspended; +}; + +static void lpc32xx_fifo_clear(struct lpc32xx_tsc_t *lpc32xx_tsc_dat) +{ + while (!(__raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base)) & + LPC32XX_TSC_STAT_FIFO_EMPTY)) + __raw_readl(LPC32XX_TSC_FIFO(lpc32xx_tsc_dat->tsc_base)); +} + +static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) +{ + u32 tmp, rv[4], xs[4], ys[4]; + int idx; + struct lpc32xx_tsc_t *lpc32xx_tsc_dat = + (struct lpc32xx_tsc_t *) dev_id; + struct input_dev *input = lpc32xx_tsc_dat->dev; + + tmp = __raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base)); + + if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { + /* FIFO overflow - throw away samples */ + lpc32xx_fifo_clear(lpc32xx_tsc_dat); + return IRQ_HANDLED; + } + + idx = 0; + while ((idx < 4) && + (!(__raw_readl(LPC32XX_TSC_STAT(lpc32xx_tsc_dat->tsc_base)) & + LPC32XX_TSC_STAT_FIFO_EMPTY))) { + tmp = __raw_readl(LPC32XX_TSC_FIFO(lpc32xx_tsc_dat->tsc_base)); + xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - + LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); + ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - + LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); + rv[idx] = tmp; + idx++; + } + + /* Data is only valid if pen is still down */ + if ((!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL)) && (idx == 4)) { + input_report_abs(input, ABS_X, ((xs[1] + xs[2]) / 2)); + input_report_abs(input, ABS_Y, ((ys[1] + ys[2]) / 2)); + input_report_abs(input, ABS_PRESSURE, 1); + input_report_key(input, BTN_TOUCH, 1); + } else { + input_report_abs(input, ABS_PRESSURE, 0); + input_report_key(input, BTN_TOUCH, 0); + } + + input_sync(input); + + return IRQ_HANDLED; +} + +static void stop_tsc(struct lpc32xx_tsc_t *lpc32xx_tsc_dat) +{ + u32 tmp; + + /* Disable auto mode */ + tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); + tmp &= ~LPC32XX_TSC_ADCCON_AUTO_EN; + __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); +} + +static void setup_tsc(struct lpc32xx_tsc_t *lpc32xx_tsc_dat) +{ + u32 tmp; + + tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); + tmp &= ~LPC32XX_TSC_ADCCON_POWER_UP; + __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); + + /* Set the TSC FIFO depth to 4 samples @ 10-bits sample */ + tmp = (LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 | + LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) | + LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10)); + __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); + + __raw_writel(0x0284, LPC32XX_TSC_SEL(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x0000, LPC32XX_TSC_MIN_X(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x03FF, LPC32XX_TSC_MAX_X(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x0000, LPC32XX_TSC_MIN_Y(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x03FF, LPC32XX_TSC_MAX_Y(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x0000, LPC32XX_TSC_AUX_UTR(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x0000, LPC32XX_TSC_AUX_MIN(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x0000, LPC32XX_TSC_AUX_MAX(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x2, LPC32XX_TSC_RTR(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(446, LPC32XX_TSC_UTR(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x2, LPC32XX_TSC_DTR(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x10, LPC32XX_TSC_TTR(lpc32xx_tsc_dat->tsc_base)); + __raw_writel(0x4, LPC32XX_TSC_DXP(lpc32xx_tsc_dat->tsc_base)); + + /* + * Set sample rate to about 60Hz, this rate is based on the + * RTC clock, which should be a stable 32768Hz + */ + __raw_writel(88, LPC32XX_TSC_UTR(lpc32xx_tsc_dat->tsc_base)); + + lpc32xx_fifo_clear(lpc32xx_tsc_dat); + + tmp = __raw_readl(LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); + tmp |= LPC32XX_TSC_ADCCON_AUTO_EN; + __raw_writel(tmp, LPC32XX_TSC_CON(lpc32xx_tsc_dat->tsc_base)); +} + +static int __devinit lpc32xx_ts_probe(struct platform_device *pdev) +{ + struct lpc32xx_tsc_t *lpc32xx_tsc_dat = NULL; + struct resource *res; + int retval = -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get platform I/O memory\n"); + retval = -EBUSY; + goto errout; + } + + lpc32xx_tsc_dat = kzalloc(sizeof(struct lpc32xx_tsc_t), GFP_KERNEL); + if (unlikely(!lpc32xx_tsc_dat)) { + dev_err(&pdev->dev, "failed allocating memory\n"); + retval = -ENOMEM; + goto errout; + } + + lpc32xx_tsc_dat->tsc_base = ioremap(res->start, + res->end - res->start + 1); + if (!lpc32xx_tsc_dat->tsc_base) { + dev_err(&pdev->dev, "failed mapping memory\n"); + retval = -EBUSY; + goto errout; + } + + lpc32xx_tsc_dat->dev = input_allocate_device(); + if (!lpc32xx_tsc_dat->dev) { + dev_err(&pdev->dev, "failed allocating input device\n"); + retval = -ENOMEM; + goto errout; + } + + lpc32xx_tsc_dat->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(lpc32xx_tsc_dat->clk)) { + dev_err(&pdev->dev, "failed getting clock\n"); + goto errout; + } + clk_enable(lpc32xx_tsc_dat->clk); + + setup_tsc(lpc32xx_tsc_dat); + + lpc32xx_tsc_dat->irq = platform_get_irq(pdev, 0); + if ((lpc32xx_tsc_dat->irq < 0) || (lpc32xx_tsc_dat->irq >= NR_IRQS)) { + dev_err(&pdev->dev, "failed getting interrupt resource\n"); + retval = -EINVAL; + goto errout; + } + + retval = request_irq(lpc32xx_tsc_dat->irq, lpc32xx_ts_interrupt, + 0, MOD_NAME, lpc32xx_tsc_dat); + if (retval < 0) { + dev_err(&pdev->dev, "failed requesting interrupt\n"); + goto err_free_irq; + } + + platform_set_drvdata(pdev, lpc32xx_tsc_dat); + + lpc32xx_tsc_dat->dev->name = MOD_NAME; + lpc32xx_tsc_dat->dev->phys = "lpc32xx/input0"; + lpc32xx_tsc_dat->dev->id.bustype = BUS_HOST; + lpc32xx_tsc_dat->dev->id.vendor = 0x0001; + lpc32xx_tsc_dat->dev->id.product = 0x0002; + lpc32xx_tsc_dat->dev->id.version = 0x0100; + lpc32xx_tsc_dat->dev->dev.parent = &pdev->dev; + + lpc32xx_tsc_dat->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + lpc32xx_tsc_dat->dev->keybit[BIT_WORD(BTN_TOUCH)] = + BIT_MASK(BTN_TOUCH); + input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_X, 0, 1023, 0, 0); + input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_Y, 0, 1023, 0, 0); + input_set_abs_params(lpc32xx_tsc_dat->dev, ABS_PRESSURE, 0, 1, 0, 0); + + retval = input_register_device(lpc32xx_tsc_dat->dev); + if (retval) { + dev_err(&pdev->dev, "failed registering input device\n"); + goto err_free_irq; + } + + device_init_wakeup(&pdev->dev, 1); + + return 0; + +err_free_irq: + stop_tsc(lpc32xx_tsc_dat); + platform_set_drvdata(pdev, NULL); + free_irq(lpc32xx_tsc_dat->irq, lpc32xx_tsc_dat->dev); + +errout: + if (lpc32xx_tsc_dat) { + if (lpc32xx_tsc_dat->clk) { + clk_disable(lpc32xx_tsc_dat->clk); + clk_put(lpc32xx_tsc_dat->clk); + } + + if (lpc32xx_tsc_dat->dev) + input_free_device(lpc32xx_tsc_dat->dev); + + if (lpc32xx_tsc_dat->tsc_base) + iounmap(lpc32xx_tsc_dat->tsc_base); + + kfree(lpc32xx_tsc_dat); + } + + return retval; +} + +static int __devexit lpc32xx_ts_remove(struct platform_device *pdev) +{ + struct lpc32xx_tsc_t *lpc32xx_tsc_dat = platform_get_drvdata(pdev); + + stop_tsc(lpc32xx_tsc_dat); + free_irq(lpc32xx_tsc_dat->irq, lpc32xx_tsc_dat->dev); + platform_set_drvdata(pdev, NULL); + input_unregister_device(lpc32xx_tsc_dat->dev); + + if (lpc32xx_tsc_dat->clk) { + clk_disable(lpc32xx_tsc_dat->clk); + clk_put(lpc32xx_tsc_dat->clk); + } + + if (lpc32xx_tsc_dat->tsc_base) + iounmap(lpc32xx_tsc_dat->tsc_base); + + kfree(lpc32xx_tsc_dat); + + return 0; +} + +#if defined (CONFIG_PM) +static int lpc32xx_ts_suspend(struct device *dev) +{ + struct lpc32xx_tsc_t *lpc32xx_tsc_dat = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(lpc32xx_tsc_dat->irq); + else { + lpc32xx_tsc_dat->suspended = 1; + stop_tsc(lpc32xx_tsc_dat); + clk_disable(lpc32xx_tsc_dat->clk); + } + + return 0; +} + +static int lpc32xx_ts_resume(struct device *dev) +{ + struct lpc32xx_tsc_t *lpc32xx_tsc_dat = dev_get_drvdata(dev); + + if (lpc32xx_tsc_dat->suspended) { + clk_enable(lpc32xx_tsc_dat->clk); + setup_tsc(lpc32xx_tsc_dat); + lpc32xx_tsc_dat->suspended = 0; + } else + disable_irq_wake(lpc32xx_tsc_dat->irq); + + return 0; +} + +static const struct dev_pm_ops lpc32xx_ts_pm_ops = { + .suspend = lpc32xx_ts_suspend, + .resume = lpc32xx_ts_resume, +}; +#define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops) +#else +#define LPC32XX_TS_PM_OPS NULL +#endif + +static struct platform_driver lpc32xx_ts_driver = { + .probe = lpc32xx_ts_probe, + .remove = __devexit_p(lpc32xx_ts_remove), + .driver = { + .name = MOD_NAME, + .owner = THIS_MODULE, + .pm = LPC32XX_TS_PM_OPS, + }, +}; + +static int __init lpc32xx_ts_init(void) +{ + return platform_driver_register(&lpc32xx_ts_driver); +} + +static void __exit lpc32xx_ts_exit(void) +{ + platform_driver_unregister(&lpc32xx_ts_driver); +} + +module_init(lpc32xx_ts_init); +module_exit(lpc32xx_ts_exit); + +MODULE_AUTHOR("Kevin Wells #include #include +#include #include #include #include @@ -31,11 +33,246 @@ #include #include +#include +#include +#include +#include +#include + #include "mmci.h" #define DRIVER_NAME "mmci-pl18x" -static unsigned int fmax = 515633; +static unsigned int fmax = 26000000; /* 26MHz bit rate max */ + +#define DMA_BUFF_SIZE SZ_64K + +struct LPC32XX_SDDRV_DATA { + struct dma_config dmacfgtx; + struct dma_config dmacfgrx; + struct device *dev; + int lastch; + dma_addr_t dma_handle_tx; + void *dma_v_base; + int mapped; +}; +static struct LPC32XX_SDDRV_DATA lpc32xx_drvdat; + +#define MCI_WIDEBUS (1 << 11) +#undef MCI_IRQENABLE +#define MCI_IRQENABLE \ + (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ + MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ + MCI_CMDRESPENDMASK|MCI_CMDSENTMASK) + +static int mmc_dma_setup(void) +{ + u32 llptrrx, llptrtx; + int ret = 0; + + /* + * There is a quirk with the LPC32XX and SD burst DMA. DMA sg + * transfers where DMA is the flow controller will not transfer + * the last few bytes to or from the SD card controller and + * memory. For RX, the last few bytes in the SD transfer can be + * forced out with a software DMA burst request. For TX, this + * can't be done, so TX sg support cannot be supported. For TX, + * a temporary bouncing buffer is used if more than 1 sg segment + * is passed in the data request. The bouncing buffer will get a + * contiguous copy of the TX data and it will be used instead. + */ + + /* Allocate a chunk of memory for the DMA TX buffers */ + lpc32xx_drvdat.dma_v_base = dma_alloc_coherent(lpc32xx_drvdat.dev, + DMA_BUFF_SIZE, &lpc32xx_drvdat.dma_handle_tx, GFP_KERNEL); + if (lpc32xx_drvdat.dma_v_base == NULL) { + dev_err(lpc32xx_drvdat.dev, "error getting DMA region\n"); + ret = -ENOMEM; + goto dma_no_tx_buff; + } + dev_info(lpc32xx_drvdat.dev, "DMA buffer: phy:%p, virt:%p\n", + (void *) lpc32xx_drvdat.dma_handle_tx, lpc32xx_drvdat.dma_v_base); + + /* Setup TX DMA channel */ + lpc32xx_drvdat.dmacfgtx.ch = DMA_CH_SDCARD_TX; + lpc32xx_drvdat.dmacfgtx.tc_inten = 0; + lpc32xx_drvdat.dmacfgtx.err_inten = 0; + lpc32xx_drvdat.dmacfgtx.src_size = 4; + lpc32xx_drvdat.dmacfgtx.src_inc = 1; + lpc32xx_drvdat.dmacfgtx.src_ahb1 = 0; + lpc32xx_drvdat.dmacfgtx.src_bsize = DMAC_CHAN_SRC_BURST_8; + lpc32xx_drvdat.dmacfgtx.src_prph = DMAC_SRC_PERIP(DMA_PERID_SDCARD); + lpc32xx_drvdat.dmacfgtx.dst_size = 4; + lpc32xx_drvdat.dmacfgtx.dst_inc = 0; + lpc32xx_drvdat.dmacfgtx.dst_ahb1 = 0; + lpc32xx_drvdat.dmacfgtx.dst_bsize = DMAC_CHAN_DEST_BURST_8; + lpc32xx_drvdat.dmacfgtx.dst_prph = DMAC_DEST_PERIP(DMA_PERID_SDCARD); + lpc32xx_drvdat.dmacfgtx.flowctrl = DMAC_CHAN_FLOW_P_M2P; + if (lpc32xx_dma_ch_get(&lpc32xx_drvdat.dmacfgtx, "dma_sd_tx", NULL, NULL) < 0) + { + dev_err(lpc32xx_drvdat.dev, "Error setting up SD card TX DMA channel\n"); + ret = -ENODEV; + goto dma_no_txch; + } + + /* Allocate a linked list for DMA support */ + llptrtx = lpc32xx_dma_alloc_llist(lpc32xx_drvdat.dmacfgtx.ch, NR_SG * 2); + if (llptrtx == 0) { + dev_err(lpc32xx_drvdat.dev, "Error allocating list buffer (MMC TX)\n"); + ret = -ENOMEM; + goto dma_no_txlist; + } + + /* Setup RX DMA channel */ + lpc32xx_drvdat.dmacfgrx.ch = DMA_CH_SDCARD_RX; + lpc32xx_drvdat.dmacfgrx.tc_inten = 0; + lpc32xx_drvdat.dmacfgrx.err_inten = 0; + lpc32xx_drvdat.dmacfgrx.src_size = 4; + lpc32xx_drvdat.dmacfgrx.src_inc = 0; + lpc32xx_drvdat.dmacfgrx.src_ahb1 = 0; + lpc32xx_drvdat.dmacfgrx.src_bsize = DMAC_CHAN_SRC_BURST_8; + lpc32xx_drvdat.dmacfgrx.src_prph = DMAC_SRC_PERIP(DMA_PERID_SDCARD); + lpc32xx_drvdat.dmacfgrx.dst_size = 4; + lpc32xx_drvdat.dmacfgrx.dst_inc = 1; + lpc32xx_drvdat.dmacfgrx.dst_ahb1 = 0; + lpc32xx_drvdat.dmacfgrx.dst_bsize = DMAC_CHAN_DEST_BURST_8; + lpc32xx_drvdat.dmacfgrx.dst_prph = DMAC_DEST_PERIP(DMA_PERID_SDCARD); + lpc32xx_drvdat.dmacfgrx.flowctrl = DMAC_CHAN_FLOW_D_P2M; + if (lpc32xx_dma_ch_get(&lpc32xx_drvdat.dmacfgrx, "dma_sd_rx", NULL, NULL) < 0) + { + dev_err(lpc32xx_drvdat.dev, "Error setting up SD card RX DMA channel\n"); + ret = -ENODEV; + goto dma_no_rxch; + } + + /* Allocate a linked list for DMA support */ + llptrrx = lpc32xx_dma_alloc_llist(lpc32xx_drvdat.dmacfgrx.ch, NR_SG * 2); + if (llptrrx == 0) { + dev_err(lpc32xx_drvdat.dev, "Error allocating list buffer (MMC RX)\n"); + ret = -ENOMEM; + goto dma_no_rxlist; + } + + return 0; + +dma_no_rxlist: + lpc32xx_dma_ch_put(lpc32xx_drvdat.dmacfgrx.ch); + lpc32xx_drvdat.dmacfgrx.ch = -1; +dma_no_rxch: + lpc32xx_dma_dealloc_llist(lpc32xx_drvdat.dmacfgtx.ch); +dma_no_txlist: + lpc32xx_dma_ch_put(lpc32xx_drvdat.dmacfgtx.ch); + lpc32xx_drvdat.dmacfgtx.ch = -1; +dma_no_txch: + dma_free_coherent(lpc32xx_drvdat.dev, DMA_BUFF_SIZE, + lpc32xx_drvdat.dma_v_base, lpc32xx_drvdat.dma_handle_tx); +dma_no_tx_buff: + return ret; +} + +static void mmc_dma_dealloc(void) +{ + lpc32xx_dma_dealloc_llist(lpc32xx_drvdat.dmacfgrx.ch); + lpc32xx_dma_ch_put(lpc32xx_drvdat.dmacfgrx.ch); + lpc32xx_drvdat.dmacfgrx.ch = -1; + lpc32xx_dma_dealloc_llist(lpc32xx_drvdat.dmacfgtx.ch); + lpc32xx_dma_ch_put(lpc32xx_drvdat.dmacfgtx.ch); + lpc32xx_drvdat.dmacfgtx.ch = -1; + dma_free_coherent(lpc32xx_drvdat.dev, DMA_BUFF_SIZE, + lpc32xx_drvdat.dma_v_base, lpc32xx_drvdat.dma_handle_tx); +} + +/* Supports scatter/gather */ +static void mmc_dma_rx_start(struct mmci_host *host) +{ + unsigned int len; + int i, dma_len; + struct scatterlist *sg; + struct mmc_request *mrq = host->mrq; + struct mmc_data *reqdata = mrq->data; + void *dmaaddr; + u32 dmalen, dmaxferlen; + + sg = reqdata->sg; + len = reqdata->sg_len; + + dma_len = dma_map_sg(mmc_dev(host->mmc), reqdata->sg, reqdata->sg_len, DMA_FROM_DEVICE); + if (dma_len == 0) + return; + + /* Setup transfer */ + for (i = 0; i < len; i++) { + dmalen = (u32) sg_dma_len(&sg[i]); + dmaaddr = (void *) sg_dma_address(&sg[i]); + + /* Build a list with a max size if 15872 bytes per seg */ + while (dmalen > 0) { + dmaxferlen = dmalen; + if (dmaxferlen > 15872) + dmaxferlen = 15872; + + lpc32xx_dma_queue_llist_entry(lpc32xx_drvdat.lastch, + (void *) SD_FIFO(LPC32XX_SD_BASE), + dmaaddr, dmaxferlen); + + dmaaddr += dmaxferlen; + dmalen -= dmaxferlen; + } + } + +//printk("DMARX %d\n", len); + +} + +/* May need to reorganize buffer for scatter/gather */ +static void mmc_dma_tx_start(struct mmci_host *host) +{ + unsigned int len; + int dma_len; + struct scatterlist *sg; + struct mmc_request *mrq = host->mrq; + struct mmc_data *reqdata = mrq->data; + void *dmaaddr; + char *src_buffer, *dst_buffer; + unsigned long flags; + + sg = reqdata->sg; + len = reqdata->sg_len; + + /* Only 1 segment? */ + if (len == 1) { + dma_len = dma_map_sg(mmc_dev(host->mmc), reqdata->sg, + reqdata->sg_len, DMA_TO_DEVICE); + if (dma_len == 0) + return; + + dmaaddr = (void *) sg_dma_address(&sg[0]); + lpc32xx_drvdat.mapped = 1; + } + else { + /* Move data to contiguous buffer first, then transfer it */ + dst_buffer = (char *) lpc32xx_drvdat.dma_v_base; + do + { + /* + * Map the current scatter buffer, copy data, and unmap + */ + src_buffer = mmci_kmap_atomic(host, &flags) + host->sg_off; + memcpy(dst_buffer, src_buffer, host->sg_ptr->length); + dst_buffer += host->sg_ptr->length; + mmci_kunmap_atomic(host, src_buffer, &flags); + + if (!mmci_next_sg(host)) + break; + } while (1); + + lpc32xx_drvdat.mapped = 0; + dmaaddr = (void *) lpc32xx_drvdat.dma_handle_tx; + } + + lpc32xx_dma_start_pflow_xfer(DMA_CH_SDCARD_TX, dmaaddr, + (void *) SD_FIFO(LPC32XX_SD_BASE), 1); +} /* * This must be called with host->lock held @@ -58,7 +295,7 @@ static void mmci_set_clkreg(struct mmci_ clk |= MCI_FCEN; /* Bug fix in ST IP block */ clk |= MCI_CLK_ENABLE; /* This hasn't proven to be worthwhile */ - /* clk |= MCI_CLK_PWRSAVE; */ + clk |= MCI_CLK_PWRSAVE; } if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) @@ -98,7 +335,7 @@ static void mmci_stop_data(struct mmci_h static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) { - unsigned int datactrl, timeout, irqmask; + unsigned int datactrl, timeout, irqmask = 0; unsigned long long clks; void __iomem *base; int blksz_bits; @@ -119,32 +356,26 @@ static void mmci_start_data(struct mmci_ base = host->base; writel(timeout, base + MMCIDATATIMER); - writel(host->size, base + MMCIDATALENGTH); - - blksz_bits = ffs(data->blksz) - 1; - BUG_ON(1 << blksz_bits != data->blksz); - - datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; - if (data->flags & MMC_DATA_READ) { - datactrl |= MCI_DPSM_DIRECTION; - irqmask = MCI_RXFIFOHALFFULLMASK; - - /* - * If we have less than a FIFOSIZE of bytes to transfer, - * trigger a PIO interrupt as soon as any data is available. - */ - if (host->size < MCI_FIFOSIZE) - irqmask |= MCI_RXDATAAVLBLMASK; - } else { - /* - * We don't actually need to include "FIFO empty" here - * since its implicit in "FIFO half empty". - */ - irqmask = MCI_TXFIFOHALFEMPTYMASK; + writel((host->size * data->blocks), base + MMCIDATALENGTH); + blksz_bits = ffs(data->blksz) - 1; + BUG_ON(1 << blksz_bits != data->blksz); + + datactrl = MCI_DPSM_ENABLE | MCI_DPSM_DMAENABLE | blksz_bits << 4; + + if (data->flags & MMC_DATA_READ) { + datactrl |= MCI_DPSM_DIRECTION; + lpc32xx_drvdat.lastch = DMA_CH_SDCARD_RX; + mmc_dma_rx_start(host); + } + else { + lpc32xx_drvdat.lastch = DMA_CH_SDCARD_TX; + mmc_dma_tx_start(host); } - writel(datactrl, base + MMCIDATACTRL); - writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); + writel(datactrl, base + MMCIDATACTRL); + datactrl = readl(base + MMCIMASK0) & ~MCI_DATABLOCKENDMASK; + writel(datactrl | MCI_DATAENDMASK, base + MMCIMASK0); + writel(irqmask, base + MMCIMASK1); } @@ -180,8 +411,9 @@ static void mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { - if (status & MCI_DATABLOCKEND) { - host->data_xfered += data->blksz; + if (status & MCI_DATAEND) { + host->data_xfered += data->blksz * data->blocks; + #ifdef CONFIG_ARCH_U300 /* * On the U300 some signal or other is @@ -211,7 +443,20 @@ mmci_data_irq(struct mmci_host *host, st if (host->sg_len && data->flags & MMC_DATA_READ) flush_dcache_page(sg_page(host->sg_ptr)); } + if (status & MCI_DATAEND) { + if (data->flags & MMC_DATA_READ) { + lpc32xx_dma_force_burst(lpc32xx_drvdat.lastch, DMA_PERID_SDCARD); + lpc32xx_dma_flush_llist(lpc32xx_drvdat.lastch); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, DMA_FROM_DEVICE); + } + else { + lpc32xx_dma_ch_disable(lpc32xx_drvdat.lastch); + if (lpc32xx_drvdat.mapped) + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, DMA_TO_DEVICE); + } + mmci_stop_data(host); if (!data->stop) { @@ -245,9 +490,8 @@ mmci_cmd_irq(struct mmci_host *host, str if (host->data) mmci_stop_data(host); mmci_request_end(host, cmd->mrq); - } else if (!(cmd->data->flags & MMC_DATA_READ)) { + } else if (!(cmd->data->flags & MMC_DATA_READ)) mmci_start_data(host, cmd->data); - } } static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) @@ -409,7 +653,7 @@ static irqreturn_t mmci_irq(int irq, voi status = readl(host->base + MMCISTATUS); status &= readl(host->base + MMCIMASK0); - writel(status, host->base + MMCICLEAR); + writel((status | MCI_DATABLOCKEND), host->base + MMCICLEAR); dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); @@ -576,8 +820,7 @@ static int __devinit mmci_probe(struct a ret = amba_request_regions(dev, DRIVER_NAME); if (ret) - goto out; - + goto out; mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); if (!mmc) { ret = -ENOMEM; @@ -673,7 +916,12 @@ static int __devinit mmci_probe(struct a * Set the maximum segment size. Since we aren't doing DMA * (yet) we are only limited by the data length register. */ - mmc->max_seg_size = mmc->max_req_size; + /* + * The LPC32x0 DMA controller can handle up to a 16383 byte DMA + * transfer. We'll rely on the mmc core to make sure the passed + * size for a request is block aligned. + */ + mmc->max_seg_size = 65535; /* * Block size can be up to 2048 bytes, but must be a power of two. @@ -685,6 +933,13 @@ static int __devinit mmci_probe(struct a */ mmc->max_blk_count = mmc->max_req_size; + /* + * Setup DMA for the interface + */ + lpc32xx_drvdat.dev = &dev->dev; + if (mmc_dma_setup()) + goto err_dma_setup; + spin_lock_init(&host->lock); writel(0, host->base + MMCIMASK0); @@ -717,9 +972,7 @@ static int __devinit mmci_probe(struct a ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host); if (ret) goto irq0_free; - writel(MCI_IRQENABLE, host->base + MMCIMASK0); - amba_set_drvdata(dev, mmc); host->oldstat = mmci_get_cd(host->mmc); @@ -746,6 +999,8 @@ static int __devinit mmci_probe(struct a if (host->gpio_cd != -ENOSYS) gpio_free(host->gpio_cd); err_gpio_cd: + mmc_dma_dealloc(); + err_dma_setup: iounmap(host->base); clk_disable: clk_disable(host->clk); @@ -786,6 +1041,8 @@ static int __devexit mmci_remove(struct if (host->gpio_cd != -ENOSYS) gpio_free(host->gpio_cd); + mmc_dma_dealloc(); + iounmap(host->base); clk_disable(host->clk); clk_put(host->clk); diff -purN linux-2.6.34/drivers/mtd/nand/Kconfig linux-2.6.34-dev/drivers/mtd/nand/Kconfig --- linux-2.6.34/drivers/mtd/nand/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/mtd/nand/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -369,6 +369,13 @@ config MTD_NAND_PXA3xx This enables the driver for the NAND flash device found on PXA3xx processors +config MTD_NAND_SLC_LPC32XX + bool "Support for NAND Flash on the LPC32XX" + depends on ARCH_LPC32XX + help + Enables support for NAND Flash using the LPC32XX SLC NAND + controller. + config MTD_NAND_PXA3xx_BUILTIN bool "Use builtin definitions for some NAND chips (deprecated)" depends on MTD_NAND_PXA3xx diff -purN linux-2.6.34/drivers/mtd/nand/lpc32xx_nand.c linux-2.6.34-dev/drivers/mtd/nand/lpc32xx_nand.c --- linux-2.6.34/drivers/mtd/nand/lpc32xx_nand.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/mtd/nand/lpc32xx_nand.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,962 @@ +/* + * drivers/mtd/nand/lpc32xx_nand.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * LPC3250 has 3 bytes of ECC data but due to DMA + * word transfer limitation, we'll use 4 bytes + */ +#define NAND_ECC_LEN_PER_SUBPAGE 0x4 +#define NAND_ECC_SUBPAGE_LEN 256 + +#define NAND_LARGE_BLOCK_PAGE_SIZE 2048 +#define NAND_SMALL_BLOCK_PAGE_SIZE 512 + +#define NAND_ERASED_BLOCK_ECC_VALUE 0xFFFFFFFF + +static struct nand_ecclayout lpc32xx_nand_oob_16 = { + .eccbytes = 8, + .eccpos = {8, 9, 10, 11, 12, 13, 14, 15}, + .oobfree = { + {.offset = 0, + . length = 5}, + {.offset = 6, + . length = 2}} +}; + +static struct nand_ecclayout lpc32xx_nand_oob_64 = { + .eccbytes = 32, + .eccpos = { 8, 9, 10, 11, 12, 13, 14, 15, + 24, 25, 26, 27, 28, 29, 30, 31, + 40, 41, 42, 43, 44, 45, 46, 47, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { + {.offset = 2, + . length = 6}, + {.offset = 16, + . length = 8}, + {.offset = 32, + . length = 8}, + {.offset = 48, + . length = 8}} +}; + +struct lpc32xx_nand_host { + struct nand_chip nand_chip; + struct clk *clk; + struct mtd_info mtd; + void __iomem *io_base; + struct lpc32XX_nand_cfg *ncfg; + struct completion comp; + struct dma_config dmacfg; + int dmach; + uint32_t dma_xfer_status; + uint32_t llptr; + uint32_t dma_buf_len; + /* + * Physical addresses of ECC buffer,DMA data buffers,OOB data buffer + */ + dma_addr_t oob_buf_phy; + dma_addr_t ecc_calc_buf_phy; + dma_addr_t dma_buf_phy; + /* + * Virtual addresses of ECC buffer,DMA data buffers,OOB data buffer + */ + uint8_t *oob_buf; + uint8_t *ecc_calc_buf; + uint8_t * dma_buf; + /* Physical address of DMA base address */ + dma_addr_t io_base_phy; + uint8_t *erase_buf_data; +}; + +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", NULL }; +#endif + +static uint8_t nand_slc_bit_cnt16(uint16_t ch) +{ + ch = (ch & 0x5555) + ((ch & ~0x5555) >> 1); + ch = (ch & 0x3333) + ((ch & ~0x3333) >> 2); + ch = (ch & 0x0F0F) + ((ch & ~0x0F0F) >> 4); + return (ch + (ch >> 8)) & 0xFF; +} + +static uint8_t bit_cnt32(uint32_t val) +{ + return nand_slc_bit_cnt16(val & 0xFFFF) + + nand_slc_bit_cnt16(val >> 16); +} + +static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host) +{ + u32 clkrate, tmp; + + /* Reset SLC controller */ + __raw_writel(SLCCTRL_SW_RESET, SLC_CTRL(host->io_base)); + udelay(1000); + + /* Basic setup */ + __raw_writel(0, SLC_CFG(host->io_base)); + __raw_writel(0, SLC_IEN(host->io_base)); + __raw_writel((SLCSTAT_INT_TC | SLCSTAT_INT_RDY_EN), SLC_ICR(host->io_base)); + + /* Get base clock for SLC block */ + clkrate = clk_get_rate(host->clk); + if (clkrate == 0) + clkrate = 133000000; + + /* Compute clock setup values */ + tmp = SLCTAC_WDR(host->ncfg->wdr_clks) | + SLCTAC_WWIDTH(1 + (clkrate / host->ncfg->wwidth)) | + SLCTAC_WHOLD(1 + (clkrate / host->ncfg->whold)) | + SLCTAC_WSETUP(1 + (clkrate / host->ncfg->wsetup)) | + SLCTAC_RDR(host->ncfg->rdr_clks) | + SLCTAC_RWIDTH(1 + (clkrate / host->ncfg->rwidth)) | + SLCTAC_RHOLD(1 + (clkrate / host->ncfg->rhold)) | + SLCTAC_RSETUP(1 + (clkrate / host->ncfg->rsetup)); + __raw_writel(tmp, SLC_TAC(host->io_base)); +} + +/* + * Hardware specific access to control lines + */ +static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + u32 tmp; + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + + /* Does CE state need to be changed? */ + tmp = __raw_readl(SLC_CFG(host->io_base)); + if (ctrl & NAND_NCE) + tmp |= SLCCFG_CE_LOW; + else + tmp &= ~SLCCFG_CE_LOW; + __raw_writel(tmp, SLC_CFG(host->io_base)); + + if (cmd != NAND_CMD_NONE) { + if (ctrl & NAND_CLE) + __raw_writel(cmd, SLC_CMD(host->io_base)); + else + __raw_writel(cmd, SLC_ADDR(host->io_base)); + } +} + +/* + * Read the Device Ready pin. + */ +static int lpc32xx_nand_device_ready(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + int rdy = 0; + + if ((__raw_readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0) + rdy = 1; + + return rdy; +} + +/* + * Enable NAND write protect + */ +static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) +{ + if (host->ncfg->enable_write_prot != NULL) + /* Disable write protection */ + host->ncfg->enable_write_prot(1); +} + +/* + * Disable NAND write protect + */ +static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) +{ + if (host->ncfg->enable_write_prot != NULL) + /* Enable write protection */ + host->ncfg->enable_write_prot(0); +} + +static uint8_t lpc32xx_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + + return (uint8_t) __raw_readl(SLC_DATA(host->io_base)); +} + +static void lpc32xx_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + int i; + + for (i = 0; i < len; i++) + buf[i] = (uint8_t) __raw_readl(SLC_DATA(host->io_base)); +} + +static int lpc32xx_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + int i; + + for (i = 0; i < len; i++) { + if (buf[i] != (uint8_t) __raw_readl(SLC_DATA(host->io_base))) + return -EFAULT; + } + + return 0; +} + +static void lpc32xx_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + struct nand_chip *nand_chip = mtd->priv; + struct lpc32xx_nand_host *host = nand_chip->priv; + int i; + + for (i = 0; i < len; i++) + __raw_writel((u32) buf[i], SLC_DATA(host->io_base)); +} + +/* + * DMA ISR - occurs when DMA transfer complete. + */ +static void lpc3xxx_nand_dma_irq(int channel, int cause, + struct lpc32xx_nand_host *host) +{ + /* Flush DMA link list */ + lpc32xx_dma_flush_llist(host->dmach); + + host->dma_xfer_status = (cause & DMA_TC_INT)? 0: 1; + complete(&host->comp); +} + +/* + * Get DMA channel and allocate DMA descriptors memory. + * Prepare DMA descriptors link lists + */ +static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host, int num_entries) +{ + int ret = 0; + + host->dmach = DMA_CH_SLCNAND; + host->dmacfg.ch = DMA_CH_SLCNAND; + + /* + * All the DMA configuration parameters will + * be overwritten in lpc32xx_nand_dma_configure(). + */ + host->dmacfg.tc_inten = 1; + host->dmacfg.err_inten = 1; + host->dmacfg.src_size = 4; + host->dmacfg.src_inc = 1; + host->dmacfg.src_ahb1 = 1; + host->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4; + host->dmacfg.src_prph = 0; + host->dmacfg.dst_size = 4; + host->dmacfg.dst_inc = 0; + host->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4; + host->dmacfg.dst_ahb1 = 0; + host->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_NAND1); + host->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_M2P; + if (lpc32xx_dma_ch_get(&host->dmacfg, "dma_slcnand", + &lpc3xxx_nand_dma_irq, host) < 0) { + printk(KERN_ERR "Error setting up SLC NAND DMA channel\n"); + ret = -ENODEV; + goto dma_ch_err; + } + + /* + * Allocate Linked list of total DMA Descriptors. + * For Large Block: 17 descriptors = ((16 Data and ECC Read) + 1 Spare Area) + * For Small Block: 5 descriptors = ((4 Data and ECC Read) + 1 Spare Area) + */ + host->llptr = lpc32xx_dma_alloc_llist(host->dmach, num_entries); + if (host->llptr == 0) { + lpc32xx_dma_ch_put(host->dmach); + host->dmach = -1; + printk(KERN_ERR "Error allocating list buffer for SLC NAND\n"); + ret = -ENOMEM; + goto dma_alloc_err; + } + + return ret; +dma_alloc_err: + lpc32xx_dma_ch_put(host->dmach); +dma_ch_err: + return ret; +} + +/* + * Configure DMA descriptors and start DMA x'fer + */ +static void lpc32xx_nand_dma_configure(struct mtd_info *mtd, + dma_addr_t buffer, int size, int read) +{ + struct nand_chip *chip = mtd->priv; + struct lpc32xx_nand_host *host = chip->priv; + uint32_t page_divider = (size == NAND_LARGE_BLOCK_PAGE_SIZE) ? 8: 2; + uint32_t dmasrc, dmadst, ctrl, ecc_ctrl, oob_ctrl; + int i; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + /* + * CTRL descriptor entry for reading ECC + * Copy Multiple times to sync DMA with Flash Controller + */ + ecc_ctrl = (0x5 | + DMAC_CHAN_SRC_BURST_1 | + DMAC_CHAN_DEST_BURST_1 | + DMAC_CHAN_SRC_WIDTH_32 | + DMAC_CHAN_DEST_WIDTH_32 | + DMAC_CHAN_DEST_AHB1); + + /* CTRL descriptor entry for reading/writing data */ + ctrl = ((mtd->writesize / page_divider) / 4) | + DMAC_CHAN_SRC_BURST_4 | + DMAC_CHAN_DEST_BURST_4 | + DMAC_CHAN_SRC_WIDTH_32 | + DMAC_CHAN_DEST_WIDTH_32 | + DMAC_CHAN_DEST_AHB1; + + /* CTRL descriptor entry for reading/writing Spare Area */ + oob_ctrl = ((mtd->oobsize / 4) | + DMAC_CHAN_SRC_BURST_4 | + DMAC_CHAN_DEST_BURST_4 | + DMAC_CHAN_SRC_WIDTH_32 | + DMAC_CHAN_DEST_WIDTH_32 | + DMAC_CHAN_DEST_AHB1); + + if (read) { + dmasrc = (uint32_t) SLC_DMA_DATA(host->io_base_phy); + dmadst = (uint32_t) (buffer); + ctrl |= DMAC_CHAN_DEST_AUTOINC; + } else { + dmadst = (uint32_t) SLC_DMA_DATA(host->io_base_phy); + dmasrc = (uint32_t) (buffer); + ctrl |= DMAC_CHAN_SRC_AUTOINC; + } + + /* + * Write Operation Sequence for Small Block NAND + * ---------------------------------------------------------- + * 1. X'fer 256 bytes of data from Memory to Flash. + * 2. Copy generated ECC data from Register to Spare Area + * 3. X'fer next 256 bytes of data from Memory to Flash. + * 4. Copy generated ECC data from Register to Spare Area. + * 5. X'fer 16 byets of Spare area from Memory to Flash. + * + * Read Operation Sequence for Small Block NAND + * ---------------------------------------------------------- + * 1. X'fer 256 bytes of data from Flash to Memory. + * 2. Copy generated ECC data from Register to ECC calc Buffer. + * 3. X'fer next 256 bytes of data from Flash to Memory. + * 4. Copy generated ECC data from Register to ECC calc Buffer. + * 5. X'fer 16 bytes of Spare area from Flash to Memory. + * + * Write Operation Sequence for Large Block NAND + * ---------------------------------------------------------- + * 1. Steps(1-4) of Write Operations repeate for four times + * which generates 16 DMA descriptors to X'fer 2048 byets of + * data & 32 bytes of ECC data. + * 2. X'fer 64 bytes of Spare area from Memory to Flash. + * + * Read Operation Sequence for Large Block NAND + * ---------------------------------------------------------- + * 1. Steps(1-4) of Read Operations repeate for four times + * which generates 16 DMA descriptors to X'fer 2048 byets of + * data & 32 bytes of ECC data. + * 2. X'fer 64 bytes of Spare area from Flash to Memory. + */ + for (i = 0; i < size/256; i++) { + lpc32xx_dma_queue_llist(host->dmach, + (void *)(read ?(dmasrc) :(dmasrc + (i*256))), + (void *)(read ?(dmadst + (i*256)) :dmadst), + -1, ctrl); + lpc32xx_dma_queue_llist(host->dmach, + (void *)SLC_ECC(host->io_base_phy), + (void *)(read ?((uint32_t) host->ecc_calc_buf_phy + (i*4)): + ((uint32_t) host->oob_buf_phy + eccpos[i*4])), + -1, ecc_ctrl); + } + + if (read) { + dmasrc = (uint32_t) (uint32_t) SLC_DMA_DATA(host->io_base_phy); + dmadst = (uint32_t) (host->oob_buf_phy); + oob_ctrl |= DMAC_CHAN_DEST_AUTOINC; + } else { + dmadst = (uint32_t) (uint32_t) SLC_DMA_DATA(host->io_base_phy); + dmasrc = (uint32_t) (host->oob_buf_phy); + oob_ctrl |= DMAC_CHAN_SRC_AUTOINC; + } + + /* Read/ Write Spare Area Data To/From Flash */ + lpc32xx_dma_queue_llist(host->dmach, (void *)dmasrc, (void *)dmadst, -1, + oob_ctrl | DMAC_CHAN_INT_TC_EN); +} + +static void lpc32xx_nand_dma_xfer(struct mtd_info *mtd, u_char *buf, int len, int read) +{ + struct nand_chip *this = mtd->priv; + uint32_t config; + struct lpc32xx_nand_host *host = this->priv; + dma_addr_t buf_phy = (dma_addr_t) 0; + int dma_mapped = 0; + + /* Calculate the physical address of the Buffer */ + /* Check if memory not allocated by vmalloc */ + if (likely((void *) buf < high_memory)) { + buf_phy = dma_map_single(mtd->dev.parent, + buf, len, read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(mtd->dev.parent, buf_phy))) { + dev_err(mtd->dev.parent, "Unable to DMA map a buffer " + "of size %d\r\n", len); + dma_mapped = 0; + }else { + dma_mapped = 1; + } + } + + if (!dma_mapped) { + memcpy(host->dma_buf, buf, len); + buf_phy = host->dma_buf_phy; + } + + config = DMAC_CHAN_ITC | DMAC_CHAN_IE | + (read ? DMAC_CHAN_FLOW_D_P2M : DMAC_CHAN_FLOW_D_M2P) | + (read ? DMAC_DEST_PERIP(0) : DMAC_DEST_PERIP(DMA_PERID_NAND1)) | + (read ? DMAC_SRC_PERIP(DMA_PERID_NAND1) : DMAC_SRC_PERIP(0)) | + DMAC_CHAN_ENABLE; + + /* Prepare descriptors for read transfer */ + lpc32xx_nand_dma_configure(mtd, buf_phy, len, read); + + /* This should start the DMA transfers */ + lpc32xx_dma_start_xfer(host->dmach, config); + __raw_writel(__raw_readl(SLC_CTRL(host->io_base)) | SLCCTRL_DMA_START, + SLC_CTRL(host->io_base)); + + /* Wait for NAND to be ready */ + nand_wait_ready(mtd); + + /* Wait till DMA transfer is DONE! */ + wait_for_completion(&host->comp); + if (unlikely(host->dma_xfer_status != 0)) { + dev_err(mtd->dev.parent, "DMA transfer error!\r\n"); + WARN_ON(1); + } + + if (dma_mapped) + dma_unmap_single(mtd->dev.parent, buf_phy, len, + read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + + /* Stop DMA & HW ECC */ + __raw_writel(__raw_readl(SLC_CTRL(host->io_base)) & ~SLCCTRL_DMA_START, + SLC_CTRL(host->io_base)); + __raw_writel( __raw_readl(SLC_CFG(host->io_base)) & + ~(SLCCFG_DMA_BURST | SLCCFG_ECC_EN | + SLCCFG_DMA_ECC | SLCCFG_DMA_DIR), + SLC_CFG(host->io_base)); +} + +static int lpc32xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *calc_ecc) +{ + int ret = 0; + uint32_t tmp, err; + uint32_t *ecc_stored = (uint32_t*)read_ecc; + uint32_t *ecc_gen = (uint32_t*)calc_ecc; + + + err = *ecc_stored ^ *ecc_gen; + /* Only perform ECC processing if an error is detected */ + if (err) { + /* ECC Failure in i-th block */ + tmp = bit_cnt32(err); + if (tmp == 11) { + uint32_t byte = err >> 6; + uint32_t bit = 0; + bit = ((err & _BIT(1)) >> 1)|((err & _BIT(3)) >> 2)| + ((err & _BIT(5)) >> 3); + + /* Calculate Byte offset */ + byte = ((byte & _BIT(1)) >> 1)|((byte & _BIT(3)) >> 2)| + ((byte & _BIT(5)) >> 3)|((byte & _BIT(7)) >> 4)| + ((byte & _BIT(9)) >> 5)|((byte & _BIT(11)) >> 6)| + ((byte & _BIT(13)) >> 7)|((byte & _BIT(15)) >> 8); + + /* Do the correction */ + dat[byte] ^= _BIT(bit); + ret = 1; + }else { + /* Non-corrrectable */ + ret = -1; + } + } + return ret; +} + +/* Prepares SLC for transfers with H/W ECC enabled */ +static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode) +{ + struct nand_chip *this = mtd->priv; + struct lpc32xx_nand_host *host = this->priv; + + /* Clear ECC, start DMA */ + __raw_writel(SLCCTRL_ECC_CLEAR, SLC_CTRL(host->io_base)); + + if (mode == NAND_ECC_READ) { + __raw_writel( __raw_readl(SLC_CFG(host->io_base)) | + SLCCFG_DMA_DIR, SLC_CFG(host->io_base)); + } + else { /* NAND_ECC_WRITE */ + __raw_writel( __raw_readl(SLC_CFG(host->io_base)) & + ~SLCCFG_DMA_DIR, SLC_CFG(host->io_base)); + } + + __raw_writel( __raw_readl(SLC_CFG(host->io_base)) | + SLCCFG_DMA_BURST | SLCCFG_ECC_EN | SLCCFG_DMA_ECC, + SLC_CFG(host->io_base)); + + /* Set transfer count */ + __raw_writel(this->ecc.size + mtd->oobsize, SLC_TC(host->io_base)); +} + +/* Function to calculate inverted ECC from the ECC got from H/W */ +static int lpc32xx_ecc_calculate(struct mtd_info *mtd, const uint8_t *dat, + uint8_t *ecc_code) +{ + return 0; +} + +static void lpc32xx_nand_write_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf) +{ + struct nand_chip *this = mtd->priv; + struct lpc32xx_nand_host *host = this->priv; + int eccsize = chip->ecc.size; + + /* + * Skip writting page which has all 0xFF data as this will + * generate 0x0 value. + */ + if(memcmp(buf, host->erase_buf_data, mtd->writesize) == 0) + return; + + /* Enable H/W ECC & DMA */ + chip->ecc.hwctl(mtd, NAND_ECC_WRITE); + + /* Copy OOB data from kernel buffer to DMA memory */ + memcpy(host->oob_buf, chip->oob_poi,mtd->oobsize); + + /* Configure DMA Desriptor for NAND Write Operation */ + lpc32xx_nand_dma_xfer(mtd, (uint8_t *)buf, eccsize, 0); +} + +static int lpc32xx_nand_read_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, int page) +{ + struct nand_chip *this = mtd->priv; + struct lpc32xx_nand_host *host = this->priv; + int i, eccsize = chip->ecc.size; + int eccsteps = (mtd->writesize/NAND_ECC_SUBPAGE_LEN); + uint8_t *p = buf; + uint8_t *ecc_calc = chip->buffers->ecccalc; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + memset(host->ecc_calc_buf, 0x0, this->ecc.bytes); + + /* Enable HW ECC & DMA */ + chip->ecc.hwctl(mtd, NAND_ECC_READ); + + /* Configure DMA Desriptor for NAND Read Operation */ + lpc32xx_nand_dma_xfer(mtd, buf, eccsize, 1); + + /* Copy OOB data from DMA memory to kernel buffer */ + memcpy(chip->oob_poi, host->oob_buf, mtd->oobsize); + + /* Copy only ECC data which are stored into Flash */ + for (i = 0; i < chip->ecc.total; i++) { + ecc_code[i] = chip->oob_poi[eccpos[i]]; + ecc_calc[i] = host->ecc_calc_buf[i]; + } + + /* + * LPC3250 has 4 bytes of ECC data per 256 bytes of data block + * As eccsteps are calucated based on subpage size. + */ + for (i = 0; eccsteps; eccsteps--, i += NAND_ECC_LEN_PER_SUBPAGE, + p += NAND_ECC_SUBPAGE_LEN) { + int stat; + + /* + * Once block is erased, all the data including OOB data are 0xFF. + * ECC generator always generate zero value ECC for such page while, + * stored value is 0xFFFFFFFF. + */ + if(*((uint32_t *)&ecc_code[i]) == NAND_ERASED_BLOCK_ECC_VALUE) + continue; + + stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat == -1) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + } + return 0; +} + +/* + * Probe for NAND controller + */ +static int __init lpc32xx_nand_probe(struct platform_device *pdev) +{ + struct lpc32xx_nand_host *host; + struct mtd_info *mtd; + struct nand_chip *nand_chip; + struct resource *rc; + int res; + +#ifdef CONFIG_MTD_PARTITIONS + struct mtd_partition *partitions = NULL; + int num_partitions = 0; +#endif + + /* Allocate memory for the device structure (and zero it) */ + host = kzalloc(sizeof(struct lpc32xx_nand_host), GFP_KERNEL); + if (!host) { + dev_err(&pdev->dev,"lpc32xx_nand: failed to allocate device structure.\n"); + return -ENOMEM; + } + + rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (rc == NULL) { + dev_err(&pdev->dev,"No memory resource found for device!\r\n"); + res = -ENXIO; + goto err_exit1; + } + + host->io_base = ioremap(rc->start, rc->end - rc->start + 1); + if (host->io_base == NULL) { + dev_err(&pdev->dev,"lpc32xx_nand: ioremap failed\n"); + res = -EIO; + goto err_exit1; + } + + mtd = &host->mtd; + nand_chip = &host->nand_chip; + host->ncfg = pdev->dev.platform_data; + + nand_chip->priv = host; /* link the private data structures */ + mtd->priv = nand_chip; + mtd->owner = THIS_MODULE; + mtd->dev.parent = &pdev->dev; + + /* Get NAND clock */ + host->clk = clk_get(&pdev->dev, "nand_ck"); + if (IS_ERR(host->clk)) { + dev_err(&pdev->dev,"lpc32xx_nand: Clock failure\n"); + res = -ENOENT; + goto err_exit2; + } + clk_enable(host->clk); + + /* Set address of NAND IO lines */ + nand_chip->IO_ADDR_R = SLC_DATA(host->io_base); + nand_chip->IO_ADDR_W = SLC_DATA(host->io_base); + nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; + nand_chip->dev_ready = lpc32xx_nand_device_ready; + nand_chip->chip_delay = 20; /* 20us command delay time */ + nand_chip->read_byte = lpc32xx_read_byte; + nand_chip->read_buf = lpc32xx_read_buf; + nand_chip->verify_buf = lpc32xx_verify_buf; + nand_chip->write_buf = lpc32xx_write_buf; + + /* Init NAND controller */ + lpc32xx_nand_setup(host); + lpc32xx_wp_disable(host); + + platform_set_drvdata(pdev, host); + + /* + * Scan to find existance of the device and + * Get the type of NAND device SMALL block or LARGE block + */ + if (nand_scan_ident(mtd, 1)) { + res = -ENXIO; + goto err_exit3; + } + + nand_chip->ecc.mode = NAND_ECC_HW; + nand_chip->ecc.size = mtd->writesize; + nand_chip->ecc.bytes = (mtd->writesize / 256) * 4; + nand_chip->ecc.read_page_raw = lpc32xx_nand_read_page_hwecc; + nand_chip->ecc.read_page = lpc32xx_nand_read_page_hwecc; + nand_chip->ecc.write_page = lpc32xx_nand_write_page_hwecc; + + switch (mtd->oobsize) { + case 16: + nand_chip->ecc.layout = &lpc32xx_nand_oob_16; + break; + case 64: + nand_chip->ecc.layout = &lpc32xx_nand_oob_64; + break; + default: + dev_err(&pdev->dev, "No oob scheme defined for " + "oobsize %d\n", mtd->oobsize); + BUG(); + } + + /* H/W ECC specific functions */ + nand_chip->ecc.hwctl = lpc32xx_ecc_enable; + nand_chip->ecc.correct = lpc32xx_nand_correct_data; + nand_chip->ecc.calculate = lpc32xx_ecc_calculate; + + /* + * Fills out all the uninitialized function pointers with the defaults + * And scans for a bad block table if appropriate. + */ + if (nand_scan_tail(mtd)) { + res = -ENXIO; + goto err_exit3; + } + + /* Get free DMA channel and alloc DMA descriptor link list */ + res = lpc32xx_nand_dma_setup(host,((mtd->writesize/128) + 1)); + if(res) { + res = -EIO; + goto err_exit3; + } + + /* allocate DMA buffer */ + host->dma_buf_len = + (/* OOB size area for storing OOB data including ECC */ + mtd->oobsize + + /* Page Size area for storing Page RAW data */ + mtd->writesize + + /* ECC bytes area for storing Calculated ECC at the time reading page */ + nand_chip->ecc.bytes); + + host->oob_buf = dmam_alloc_coherent(&pdev->dev, host->dma_buf_len, + &host->oob_buf_phy, GFP_KERNEL); + if (host->oob_buf == NULL) { + dev_err(&pdev->dev, "Unable to allocate DMA memory!\r\n"); + res = -ENOMEM; + goto err_exit4; + } + + host->dma_buf = (uint8_t *)host->oob_buf + mtd->oobsize; + host->ecc_calc_buf = (uint8_t *)host->dma_buf + mtd->writesize; + + host->dma_buf_phy = host->oob_buf_phy + mtd->oobsize; + host->ecc_calc_buf_phy = host->dma_buf_phy + mtd->writesize; + + host->io_base_phy = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start; + + /* + * Allocate a page size buffer to check all 0xFF data + * at the time page writting. + */ + host->erase_buf_data = kmalloc(mtd->writesize, GFP_KERNEL); + if (!host->erase_buf_data) { + dev_err(&pdev->dev,"lpc32xx_nand: failed to allocate device structure.\n"); + return -ENOMEM; + goto err_exit5; + } + memset(host->erase_buf_data, 0xFF, mtd->writesize); + init_completion(&host->comp); + +#ifdef CONFIG_MTD_PARTITIONS +#ifdef CONFIG_MTD_CMDLINE_PARTS + mtd->name = "lpc32xx_nand"; + num_partitions = parse_mtd_partitions(mtd, part_probes, + &partitions, 0); +#endif + if ((num_partitions <= 0) && (host->ncfg->partition_info)) { + partitions = host->ncfg->partition_info(mtd->size, + &num_partitions); + } + + if ((!partitions) || (num_partitions == 0)) { + dev_err(&pdev->dev,"lpc32xx_nand: No parititions defined, or unsupported device.\n"); + res = ENXIO; + goto err_exit6; + } + + res = add_mtd_partitions(mtd, partitions, num_partitions); +#else + res = add_mtd_device(mtd); +#endif + if (!res) + return res; + + nand_release(mtd); +err_exit6: + kfree(host->erase_buf_data); +err_exit5: + dma_free_coherent(&pdev->dev, host->dma_buf_len, + host->oob_buf, host->oob_buf_phy); +err_exit4: + /* Free the DMA channel used by us */ + lpc32xx_dma_ch_disable(host->dmach); + lpc32xx_dma_dealloc_llist(host->dmach); + lpc32xx_dma_ch_put(host->dmach); + host->dmach = -1; +err_exit3: + clk_disable(host->clk); + clk_put(host->clk); + platform_set_drvdata(pdev, NULL); +err_exit2: + lpc32xx_wp_enable(host); + iounmap(host->io_base); +err_exit1: + kfree(host); + + return res; +} + +/* + * Remove NAND device. + */ +static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) +{ + u32 tmp; + struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); + struct mtd_info *mtd = &host->mtd; + + /* Free the DMA channel used by us */ + lpc32xx_dma_ch_disable(host->dmach); + lpc32xx_dma_dealloc_llist(host->dmach); + lpc32xx_dma_ch_put(host->dmach); + host->dmach = -1; + + dma_free_coherent(&pdev->dev, host->dma_buf_len, + host->oob_buf, host->oob_buf_phy); + nand_release(mtd); + + /* Force CE high */ + tmp = __raw_readl(SLC_CTRL(host->io_base)); + tmp &= ~SLCCFG_CE_LOW; + __raw_writel(tmp, SLC_CTRL(host->io_base)); + + lpc32xx_wp_enable(host); + clk_disable(host->clk); + clk_put(host->clk); + + iounmap(host->io_base); + + kfree(host->erase_buf_data); + kfree(host); + + return 0; +} + +#if defined (CONFIG_PM) +static int lpc32xx_nand_resume(struct platform_device *pdev) +{ + struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); + + /* Re-enable NAND clock */ + clk_enable(host->clk); + + /* Fresh init of NAND controller */ + lpc32xx_nand_setup(host); + + /* Disable write protect */ + lpc32xx_wp_disable(host); + + return 0; +} + +static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm) +{ + u32 tmp; + struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); + + /* Force CE high */ + tmp = __raw_readl(SLC_CTRL(host->io_base)); + tmp &= ~SLCCFG_CE_LOW; + __raw_writel(tmp, SLC_CTRL(host->io_base)); + + /* Enable write protect for safety */ + lpc32xx_wp_enable(host); + + /* Disable clock */ + clk_disable(host->clk); + + return 0; +} + +#else +#define lpc32xx_nand_resume NULL +#define lpc32xx_nand_suspend NULL +#endif + +static struct platform_driver lpc32xx_nand_driver = { + .probe = lpc32xx_nand_probe, + .remove = __devexit_p(lpc32xx_nand_remove), + .resume = lpc32xx_nand_resume, + .suspend = lpc32xx_nand_suspend, + .driver = { + .name = "lpc32xx-nand", + .owner = THIS_MODULE, + }, +}; + +static int __init lpc32xx_nand_init(void) +{ + return platform_driver_register(&lpc32xx_nand_driver); +} + +static void __exit lpc32xx_nand_exit(void) +{ + platform_driver_unregister(&lpc32xx_nand_driver); +} + +module_init(lpc32xx_nand_init); +module_exit(lpc32xx_nand_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kevin Wells(kevin.wells@nxp.com)"); +MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX SLC controller"); + diff -purN linux-2.6.34/drivers/mtd/nand/Makefile linux-2.6.34-dev/drivers/mtd/nand/Makefile --- linux-2.6.34/drivers/mtd/nand/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/mtd/nand/Makefile 2010-10-15 14:10:00.118524167 +0100 @@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o +obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_nand.o obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o diff -purN linux-2.6.34/drivers/net/Kconfig linux-2.6.34-dev/drivers/net/Kconfig --- linux-2.6.34/drivers/net/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/net/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -1984,6 +1984,14 @@ config BCM63XX_ENET This driver supports the ethernet MACs in the Broadcom 63xx MIPS chipset family (BCM63XX). +config LPC_ENET + tristate "NXP ethernet MAC on LPC devices" + depends on ARCH_LPC32XX + select PHYLIB + help + Say Y here if you want to use the NXP ethernet MAC included + on some NXP LPC devices. + source "drivers/net/fs_enet/Kconfig" source "drivers/net/octeon/Kconfig" diff -purN linux-2.6.34/drivers/net/lpc_eth.c linux-2.6.34-dev/drivers/net/lpc_eth.c --- linux-2.6.34/drivers/net/lpc_eth.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/net/lpc_eth.c 2010-10-15 14:10:00.118524167 +0100 @@ -0,0 +1,1327 @@ +/* + * drivers/net/lpc-eth.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#if defined(CONFIG_ARCH_LPC32XX_IRAM_FOR_NET) +#include +#endif +#include "lpc_eth.h" + +#define MODNAME "lpc-net" +#define DRV_VERSION "$Revision: 1.00 $" +#define PHYDEF_ADDR 0x00 + +#define ENET_MAXF_SIZE 1536 +#define ENET_RX_DESC 48 +#define ENET_TX_DESC 16 + +#if defined(CONFIG_ARCH_LPC32XX_IRAM_FOR_NET) +extern u32 lpc32xx_return_iram_size(void); +#endif + +// FIXME +// Dynamic buffer allocation as needed +// Check/fix ethtool support +// Better MAC address support +// Better DMA allocation support (dma pool) +// MII/RMII support (only supports RMII as of now) + +static int lpc_net_hard_start_xmit(struct sk_buff *skb, + struct net_device *ndev); + +/* + * Transmit timeout, default 2.5 seconds. + */ +static int watchdog = 2500; +module_param(watchdog, int, 0400); +MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); + +/* + * Default local config if board config is not defined + */ +static struct lpc_net_cfg __lpc_local_net_config = { + .phy_irq = -1, + .phy_mask = 0xFFFFFFF0, +}; + +/* + * Device driver data structure + */ +struct netdata_local { + struct platform_device *pdev; + struct net_device *ndev; + spinlock_t lock; + void __iomem *net_base; + unsigned long net_region_start; + unsigned long net_region_size; + u32 msg_enable; + struct sk_buff *skb[ENET_TX_DESC]; + unsigned int last_tx_idx; + unsigned int num_used_tx_buffs; + struct mii_bus *mii_bus; + struct phy_device *phy_dev; + struct clk *clk; + u32 dma_buff_base_p; + u32 dma_buff_base_v; + u32 dma_buff_size; + u32 tx_desc_v [ENET_TX_DESC]; + u32 tx_stat_v [ENET_TX_DESC]; + u32 tx_buff_v [ENET_TX_DESC]; + u32 rx_desc_v [ENET_RX_DESC]; + u32 rx_stat_v [ENET_RX_DESC]; + u32 rx_buff_v [ENET_RX_DESC]; + struct lpc_net_cfg *ncfg; + int link; + int speed; + int duplex; +}; + +/* + * MAC address is provided as a boot paramter (ethaddr) via u-boot + */ +static u8 mac_address[6] = {0}; + +static int __init ethaddr(char *str) +{ + char *s, *e; + int i; + + s = str; + for (i = 0; i < 6; ++i) { + mac_address[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + return 1; +} +__setup("ethaddr=", ethaddr); + +static int get_mac_addr(u8 *mac) +{ + int i; + + for (i = 0; i < 6; i++) { + mac[i] = mac_address[i]; + } + return 0; +} + +/* + * MAC support functions + */ +static void __lpc_set_mac(struct netdata_local *pldat, u8 *mac) +{ + u32 tmp; + + /* Set station address */ + tmp = (u32) mac[0] | ((u32) mac[1] << 8); + writel(tmp, LPC_ENET_SA2(pldat->net_base)); + tmp = (u32) mac[2] | ((u32) mac[3] << 8); + writel(tmp, LPC_ENET_SA1(pldat->net_base)); + tmp = (u32) mac[4] | ((u32) mac[5] << 8); + writel(tmp, LPC_ENET_SA0(pldat->net_base)); + + pr_debug("Ethernet MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +} + +static void __lpc_net_clock_enable(struct netdata_local *pldat, + int enable) +{ + if (enable) + clk_enable(pldat->clk); + else + clk_disable(pldat->clk); +} + +static void __lpc_params_setup(struct netdata_local *pldat) +{ + u32 tmp; + + if (pldat->duplex == DUPLEX_FULL) { + tmp = readl(LPC_ENET_MAC2(pldat->net_base)); + tmp |= LPC_MAC2_FULL_DUPLEX; + writel(tmp, LPC_ENET_MAC2(pldat->net_base)); + tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); + tmp |= LPC_COMMAND_FULLDUPLEX; + writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); + writel(LPC_IPGT_LOAD(0x15), LPC_ENET_IPGT(pldat->net_base)); + } else { + tmp = readl(LPC_ENET_MAC2(pldat->net_base)); + tmp &= ~LPC_MAC2_FULL_DUPLEX; + writel(tmp, LPC_ENET_MAC2(pldat->net_base)); + tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); + tmp &= ~LPC_COMMAND_FULLDUPLEX; + writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); + writel(LPC_IPGT_LOAD(0x12), LPC_ENET_IPGT(pldat->net_base)); + } + + if (pldat->speed == SPEED_100) + writel(LPC_SUPP_SPEED, LPC_ENET_SUPP(pldat->net_base)); + else + writel(0, LPC_ENET_SUPP(pldat->net_base)); +} + +static void __lpc_eth_reset(struct netdata_local *pldat) +{ + /* Reset all MAC logic */ + writel((LPC_MAC1_RESET_TX | LPC_MAC1_RESET_MCS_TX | LPC_MAC1_RESET_RX | + LPC_MAC1_RESET_MCS_RX | LPC_MAC1_SIMULATION_RESET | + LPC_MAC1_SOFT_RESET), LPC_ENET_MAC1(pldat->net_base)); + writel((LPC_COMMAND_REG_RESET | LPC_COMMAND_TXRESET | + LPC_COMMAND_RXRESET), LPC_ENET_COMMAND(pldat->net_base)); +} + +static int __lpc_mii_mngt_reset(struct netdata_local *pldat) +{ + /* Reset MII management hardware */ + writel(LPC_MCFG_RESET_MII_MGMT, LPC_ENET_MCFG(pldat->net_base)); + + /* Setup MII clock to slowest rate with a /28 divider */ + writel(LPC_MCFG_CLOCK_SELECT(LPC_MCFG_CLOCK_HOST_DIV_28), + LPC_ENET_MCFG(pldat->net_base)); + + return 0; +} + +static u32 __ptr_align(u32 pbuff) +{ + pbuff &= 0xFFFFFFF0; + pbuff += 0x10; + + return pbuff; +} + +static inline u32 __va_to_pa(u32 addr, struct netdata_local *pldat) +{ + u32 phaddr; + + phaddr = addr - pldat->dma_buff_base_v; + phaddr += pldat->dma_buff_base_p; + + return phaddr; +} + +/* Setup TX/RX descriptors */ +static void __lpc_txrx_desc_setup(struct netdata_local *pldat) +{ + u32 tbuff, *ptxstat; + int i; + struct txrx_desc_t *ptxrxdesc; + struct rx_status_t *prxstat; + + tbuff = __ptr_align(pldat->dma_buff_base_v); + + /* Setup TX descriptors, status, and buffers */ + for (i = 0; i < ENET_TX_DESC; i++) { + pldat->tx_desc_v [i] = tbuff; + tbuff += sizeof(struct txrx_desc_t); + } + for (i = 0; i < ENET_TX_DESC; i++) { + pldat->tx_stat_v [i] = tbuff; + tbuff += sizeof(u32); + } + tbuff = __ptr_align(tbuff); + for (i = 0; i < ENET_TX_DESC; i++) { + pldat->tx_buff_v [i] = tbuff; + tbuff += ENET_MAXF_SIZE; + } + + /* Setup RX descriptors, status, and buffers */ + for (i = 0; i < ENET_RX_DESC; i++) { + pldat->rx_desc_v [i] = tbuff; + tbuff += sizeof(struct txrx_desc_t); + } + tbuff = __ptr_align(tbuff); + for (i = 0; i < ENET_RX_DESC; i++) { + pldat->rx_stat_v [i] = tbuff; + tbuff += sizeof(struct rx_status_t); + } + tbuff = __ptr_align(tbuff); + for (i = 0; i < ENET_RX_DESC; i++) { + pldat->rx_buff_v [i] = tbuff; + tbuff += ENET_MAXF_SIZE; + } + + /* Map the TX descriptors to the TX buffers in hardware */ + for (i = 0; i < ENET_TX_DESC; i++) { + ptxstat = (u32 *) pldat->tx_stat_v [i]; + ptxrxdesc = (struct txrx_desc_t *) pldat->tx_desc_v [i]; + + ptxrxdesc->packet = __va_to_pa(pldat->tx_buff_v [i], pldat); + ptxrxdesc->control = 0; + *ptxstat = 0; + } + + /* Map the RX descriptors to the RX buffers in hardware */ + for (i = 0; i < ENET_RX_DESC; i++) { + prxstat = (struct rx_status_t *) pldat->rx_stat_v [i]; + ptxrxdesc = (struct txrx_desc_t *) pldat->rx_desc_v [i]; + + ptxrxdesc->packet = __va_to_pa(pldat->rx_buff_v [i], pldat); + ptxrxdesc->control = 0x80000000 | (ENET_MAXF_SIZE - 1); + prxstat->statusinfo = 0; + prxstat->statushashcrc = 0; + } + + /* Setup base addresses in hardware to point to buffers and + descriptors */ + writel((ENET_TX_DESC - 1), + LPC_ENET_TXDESCRIPTORNUMBER(pldat->net_base)); + writel(__va_to_pa(pldat->tx_desc_v [0], pldat), + LPC_ENET_TXDESCRIPTOR(pldat->net_base)); + writel(__va_to_pa(pldat->tx_stat_v [0], pldat), + LPC_ENET_TXSTATUS(pldat->net_base)); + writel((ENET_RX_DESC - 1), + LPC_ENET_RXDESCRIPTORNUMBER(pldat->net_base)); + writel(__va_to_pa(pldat->rx_desc_v [0], pldat), + LPC_ENET_RXDESCRIPTOR(pldat->net_base)); + writel(__va_to_pa(pldat->rx_stat_v [0], pldat), + LPC_ENET_RXSTATUS(pldat->net_base)); +} + +static void __lpc_eth_init(struct netdata_local *pldat) +{ + u32 tmp; + + /* Disable controller and reset */ + tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); + tmp &= ~LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; + writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); + tmp = readl(LPC_ENET_MAC1(pldat->net_base)); + tmp &= ~LPC_MAC1_RECV_ENABLE; + writel(tmp, LPC_ENET_MAC1(pldat->net_base)); + + /* Initial MAC setup */ + writel(LPC_MAC1_PASS_ALL_RX_FRAMES, LPC_ENET_MAC1(pldat->net_base)); + writel((LPC_MAC2_PAD_CRC_ENABLE | LPC_MAC2_CRC_ENABLE), + LPC_ENET_MAC2(pldat->net_base)); + writel(ENET_MAXF_SIZE, LPC_ENET_MAXF(pldat->net_base)); + + /* Collision window, gap */ + writel((LPC_CLRT_LOAD_RETRY_MAX(0xF) | + LPC_CLRT_LOAD_COLLISION_WINDOW(0x37)), + LPC_ENET_CLRT(pldat->net_base)); + writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base)); + +#if defined (CONFIG_ARCH_LPC32XX_MII_SUPPORT) + writel(LPC_COMMAND_PASSRUNTFRAME, LPC_ENET_COMMAND(pldat->net_base)); +#else + writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), + LPC_ENET_COMMAND(pldat->net_base)); + writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); +#endif + + __lpc_params_setup(pldat); + + /* Setup TX and RX descriptors */ + __lpc_txrx_desc_setup(pldat); + + /* Setup packet filtering */ + writel((LPC_RXFLTRW_ACCEPTUBROADCAST | LPC_RXFLTRW_ACCEPTPERFECT), + LPC_ENET_RXFILTER_CTRL(pldat->net_base)); + + /* Clear and enable interrupts */ + writel(0xFFFF, LPC_ENET_INTCLEAR(pldat->net_base)); + writel((LPC_MACINT_RXDONEINTEN | LPC_MACINT_TXDONEINTEN), + LPC_ENET_INTENABLE(pldat->net_base)); + + /* Get the next TX buffer output index */ + pldat->num_used_tx_buffs = 0; + pldat->last_tx_idx = + readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); + + /* Enable controller */ + tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); + tmp |= LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; + writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); + tmp = readl(LPC_ENET_MAC1(pldat->net_base)); + tmp |= LPC_MAC1_RECV_ENABLE; + writel(tmp, LPC_ENET_MAC1(pldat->net_base)); +} + +static void __lpc_net_shutdown(struct netdata_local *pldat) +{ + /* Reset ethernet and power down PHY */ + __lpc_eth_reset(pldat); + writel(0, LPC_ENET_MAC1(pldat->net_base)); + writel(0, LPC_ENET_MAC2(pldat->net_base)); +} + +/* + * MAC<--->PHY support functions + */ +static int lpc_mdio_read(struct mii_bus *bus, int phy_id, int phyreg) +{ + struct netdata_local *pldat = bus->priv; + unsigned long timeout = jiffies + ((HZ * 100) / 1000); /* 100mS */ + int lps; + + writel(((phy_id << 8) | phyreg), LPC_ENET_MADR(pldat->net_base)); + writel(LPC_MCMD_READ, LPC_ENET_MCMD(pldat->net_base)); + + /* Wait for unbusy status */ + while (readl(LPC_ENET_MIND(pldat->net_base)) & LPC_MIND_BUSY) { + if (jiffies > timeout) + return -EIO; + cpu_relax(); + } + + lps = (int) readl(LPC_ENET_MRDD(pldat->net_base)); + writel(0, LPC_ENET_MCMD(pldat->net_base)); + + return lps; +} + +static int lpc_mdio_write(struct mii_bus *bus, int phy_id, int phyreg, + u16 phydata) +{ + struct netdata_local *pldat = bus->priv; + unsigned long timeout = jiffies + ((HZ * 100) / 1000); /* 100mS */ + + writel(((phy_id << 8) | phyreg), LPC_ENET_MADR(pldat->net_base)); + writel(phydata, LPC_ENET_MWTD(pldat->net_base)); + + /* Wait for completion */ + while (readl(LPC_ENET_MIND(pldat->net_base)) & LPC_MIND_BUSY) { + if (jiffies > timeout) + return -EIO; + cpu_relax(); + } + + return 0; +} + +static int lpc_mdio_reset(struct mii_bus *bus) +{ + return __lpc_mii_mngt_reset((struct netdata_local *) bus->priv); +} + +static void lpc_handle_link_change(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct phy_device *phydev = pldat->phy_dev; + unsigned long flags; + + int status_change = 0; + + spin_lock_irqsave(&pldat->lock, flags); + + if (phydev->link) { + if ((pldat->speed != phydev->speed) || + (pldat->duplex != phydev->duplex)) { + pldat->speed = phydev->speed; + pldat->duplex = phydev->duplex; + status_change = 1; + } + } + + if (phydev->link != pldat->link) { + if (!phydev->link) { + pldat->speed = 0; + pldat->duplex = -1; + } + pldat->link = phydev->link; + + status_change = 1; + } + + spin_unlock_irqrestore(&pldat->lock, flags); + + if (status_change) + __lpc_params_setup(pldat); +} + +static int lpc_mii_probe(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct phy_device *phydev = NULL; + int phy_addr; + + /* find the first phy */ + for (phy_addr = 1; phy_addr < PHY_MAX_ADDR; phy_addr++) { + phydev = get_phy_device(pldat->mii_bus, phy_addr); + if (phydev != NULL) + break; + } + + if (!phydev) { + pr_err("%s: no PHY found\n", ndev->name); + return -ENODEV; + } + + /* Attach to the PHY */ +#if defined (CONFIG_ARCH_LPC32XX_MII_SUPPORT) + pr_info("%s: using MII interface\n", ndev->name); + phydev = phy_connect(ndev, dev_name(&phydev->dev), + &lpc_handle_link_change, 0, PHY_INTERFACE_MODE_MII); +#else + pr_info("%s: using RMII interface\n", ndev->name); + phydev = phy_connect(ndev, dev_name(&phydev->dev), + &lpc_handle_link_change, 0, PHY_INTERFACE_MODE_RMII); +#endif + + if (IS_ERR(phydev)) { + pr_err("%s: Could not attach to PHY\n", ndev->name); + return PTR_ERR(phydev); + } + + /* mask with MAC supported features */ + phydev->supported &= PHY_BASIC_FEATURES; + + phydev->advertising = phydev->supported; + + pldat->link = 0; + pldat->speed = 0; + pldat->duplex = -1; + pldat->phy_dev = phydev; + + return 0; +} + +static int lpc_mii_init(struct netdata_local *pldat) +{ + int err = -ENXIO, i; + + pldat->mii_bus = mdiobus_alloc(); + if (!pldat->mii_bus) { + err = -ENOMEM; + goto err_out; + } + + /* Setup MII mode */ +#if defined (CONFIG_ARCH_LPC32XX_MII_SUPPORT) + writel(LPC_COMMAND_PASSRUNTFRAME, LPC_ENET_COMMAND(pldat->net_base)); +#else + writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), + LPC_ENET_COMMAND(pldat->net_base)); + writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); +#endif + + pldat->mii_bus->name = "lpc_mii_bus"; + pldat->mii_bus->read = &lpc_mdio_read; + pldat->mii_bus->write = &lpc_mdio_write; + pldat->mii_bus->reset = &lpc_mdio_reset; + snprintf(pldat->mii_bus->id, MII_BUS_ID_SIZE, "%x", pldat->pdev->id); + pldat->mii_bus->priv = pldat; + pldat->mii_bus->parent = &pldat->pdev->dev; + pldat->mii_bus->phy_mask = 0xFFFFFFF0; + + if (pldat->ncfg) + pldat->mii_bus->phy_mask = pldat->ncfg->phy_mask; + + pldat->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (!pldat->mii_bus->irq) { + err = -ENOMEM; + goto err_out_1; + } + + for (i = 0; i < PHY_MAX_ADDR; i++) + pldat->mii_bus->irq[i] = PHY_POLL; + + platform_set_drvdata(pldat->ndev, pldat->mii_bus); + + if (mdiobus_register(pldat->mii_bus)) { + goto err_out_free_mdio_irq; + } + + if (lpc_mii_probe(pldat->ndev) != 0) { + goto err_out_unregister_bus; + } + + return 0; + +err_out_unregister_bus: + mdiobus_unregister(pldat->mii_bus); +err_out_free_mdio_irq: + kfree(pldat->mii_bus->irq); +err_out_1: + mdiobus_free(pldat->mii_bus); +err_out: + return err; +} + +static void __lpc_handle_xmit(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct sk_buff *skb; + unsigned int txcidx, *ptxstat, txstat; + + txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); + while (pldat->last_tx_idx != txcidx) + { + skb = (struct sk_buff *) pldat->skb[pldat->last_tx_idx]; + + /* A buffer is available, get buffer status */ + ptxstat = (unsigned int *) pldat->tx_stat_v[pldat->last_tx_idx]; + txstat = *ptxstat; + + /* Next buffer and decrement used buffer counter */ + pldat->num_used_tx_buffs--; + pldat->last_tx_idx++; + if (pldat->last_tx_idx >= ENET_TX_DESC) + pldat->last_tx_idx = 0; + + /* Update collision counter */ + ndev->stats.collisions += ((txstat >> 21) & 0xF); + + /* Any errors occurred? */ + if (txstat & 0x80000000) { + if (txstat & 0x20000000) { + /* FIFO underrun */ + ndev->stats.tx_fifo_errors++; + ndev->stats.tx_errors++; + } + if (txstat & 0x10000000) { + /* Late collision */ + ndev->stats.tx_aborted_errors++; + ndev->stats.tx_errors++; + } + if (txstat & 0x08000000) { + /* Excessive collision */ + ndev->stats.tx_aborted_errors++; + ndev->stats.tx_errors++; + } + if (txstat & 0x04000000) { + /* Defer limit */ + ndev->stats.tx_aborted_errors++; + ndev->stats.tx_errors++; + } + + /* Buffer transmit failed, requeue it */ + lpc_net_hard_start_xmit(skb, ndev); + } else { + /* Update stats */ + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; + + /* Free buffer */ + dev_kfree_skb_irq(skb); + } + + txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); + } + + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); +} + +static void __lpc_handle_recv(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct sk_buff *skb; + int rxconsidx, len, ethst; + struct rx_status_t *prxstat; + u8 *prdbuf; + + /* Get the current RX buffer indexes */ + rxconsidx = (int) readl(LPC_ENET_RXCONSUMEINDEX(pldat->net_base)); + while (rxconsidx != (int) readl(LPC_ENET_RXPRODUCEINDEX(pldat->net_base))) + { + /* Get pointer to receive status */ + prxstat = (struct rx_status_t *) pldat->rx_stat_v [rxconsidx]; + len = (prxstat->statusinfo & 0x7FF) + 1; + + /* Status error? */ + ethst = prxstat->statusinfo; + if ((ethst & 0xBF800000) == 0x84000000) + ethst &= ~0x80000000; + + if (ethst & 0x80000000) { + /* Check statuses */ + if (prxstat->statusinfo & (1 << 28)) { + /* Overrun error */ + ndev->stats.rx_fifo_errors++; + } else if (prxstat->statusinfo & (1 << 23)) { + /* CRC error */ + ndev->stats.rx_crc_errors++; + } else if (prxstat->statusinfo & (1 << 25)) { + /* Length error */ + ndev->stats.rx_length_errors++; + } else if (prxstat->statusinfo & 0x80000000) { + /* Other error */ + ndev->stats.rx_length_errors++; + } + ndev->stats.rx_errors++; + } else { + /* Packet is good */ + skb = dev_alloc_skb(len + 8); + if (!skb) + ndev->stats.rx_dropped++; + else { + skb_reserve(skb, 8); + prdbuf = skb_put(skb, (len - 0)); + + /* Copy packer from buffer */ + memcpy(prdbuf, (void *) pldat->rx_buff_v [rxconsidx], len); + + /* Pass to upper layer */ + skb->protocol = eth_type_trans(skb, ndev); + netif_rx(skb); + ndev->last_rx = jiffies; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += len; + } + } + + /* Increment consume index */ + rxconsidx = rxconsidx + 1; + if (rxconsidx >= ENET_RX_DESC) + rxconsidx = 0; + writel((u32) rxconsidx, LPC_ENET_RXCONSUMEINDEX(pldat->net_base)); + } +} + +static irqreturn_t __lpc_eth_interrupt(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct netdata_local *pldat = netdev_priv(ndev); + u32 tmp; + + spin_lock(&pldat->lock); + + /* Get the interrupt status */ + tmp = readl(LPC_ENET_INTSTATUS(pldat->net_base)); + + while (tmp) { + /* Clear interrupts */ + writel(tmp, LPC_ENET_INTCLEAR(pldat->net_base)); + + /* Transmit complete? */ + if (tmp & (LPC_MACINT_TXUNDERRUNINTEN | LPC_MACINT_TXERRORINTEN | + LPC_MACINT_TXFINISHEDINTEN | LPC_MACINT_TXDONEINTEN)) + __lpc_handle_xmit(ndev); + + /* Receive buffer available */ + if (tmp & (LPC_MACINT_RXOVERRUNINTEN | LPC_MACINT_RXERRORONINT | + LPC_MACINT_RXFINISHEDINTEN | LPC_MACINT_RXDONEINTEN)) + __lpc_handle_recv(ndev); + + /* Recheck the interrupt status */ + tmp = readl(LPC_ENET_INTSTATUS(pldat->net_base)); + } + + spin_unlock(&pldat->lock); + + return IRQ_HANDLED; +} + +static int lpc_net_close(struct net_device *ndev) +{ + unsigned long flags; + struct netdata_local *pldat = netdev_priv(ndev); + + if (netif_msg_ifdown(pldat)) + { + dev_dbg(&pldat->pdev->dev, "shutting down %s\n", ndev->name); + } + + netif_stop_queue(ndev); + + if (pldat->phy_dev) + { + phy_stop(pldat->phy_dev); + } + + spin_lock_irqsave(&pldat->lock, flags); + __lpc_eth_reset(pldat); + netif_carrier_off(ndev); + writel(0, LPC_ENET_MAC1(pldat->net_base)); + writel(0, LPC_ENET_MAC2(pldat->net_base)); + spin_unlock_irqrestore(&pldat->lock, flags); + + __lpc_net_clock_enable(pldat, 0); + + return 0; +} + +static int lpc_net_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + unsigned int len, txidx; + u32 *ptxstat; + struct txrx_desc_t *ptxrxdesc; + + len = skb->len; + + spin_lock_irq(&pldat->lock); + + if (pldat->num_used_tx_buffs >= (ENET_TX_DESC - 1)) { + /* This function should never be called when there are no + buffers, log the error */ + netif_stop_queue(ndev); + spin_unlock_irq(&pldat->lock); + dev_err(&pldat->pdev->dev, + "BUG! TX request when no free TX buffers!\n"); + return 1; + } + + /* Get the next TX descriptor index */ + txidx = readl(LPC_ENET_TXPRODUCEINDEX(pldat->net_base)); + + /* Setup control for the transfer */ + ptxstat = (u32 *) pldat->tx_stat_v [txidx]; + *ptxstat = 0; + ptxrxdesc = (struct txrx_desc_t *) pldat->tx_desc_v [txidx]; + ptxrxdesc->control = (len - 1) | 0xC0000000; + + /* Copy data to the DMA buffer */ + memcpy((void *) pldat->tx_buff_v [txidx], skb->data, len); + + /* Save the buffer and increment the buffer counter */ + pldat->skb[txidx] = skb; + pldat->num_used_tx_buffs++; + + /* Start transmit */ + txidx++; + if (txidx >= ENET_TX_DESC) + txidx = 0; + writel((u32) txidx, LPC_ENET_TXPRODUCEINDEX(pldat->net_base)); + + /* Stop queue if no more TX buffers */ + if (pldat->num_used_tx_buffs >= (ENET_TX_DESC - 1)) + netif_stop_queue(ndev); + + spin_unlock_irq(&pldat->lock); + ndev->trans_start = jiffies; + + return 0; +} + +static void lpc_net_timeout(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + + /* This should never happen and indicates a problem */ + dev_err(&pldat->pdev->dev, "BUG! TX timeout occurred!\n"); +} + +static int lpc_set_mac_address(struct net_device *ndev, void *p) +{ + struct sockaddr *addr = p; + struct netdata_local *pldat = netdev_priv(ndev); + unsigned long flags; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + memcpy(ndev->dev_addr, addr->sa_data, ETH_ALEN); + + spin_lock_irqsave(&pldat->lock, flags); + + /* Set station address */ + __lpc_set_mac(pldat, ndev->dev_addr); + + spin_unlock_irqrestore(&pldat->lock, flags); + + return 0; +} + +static void lpc_net_set_multicast_list(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct dev_mc_list *mcptr = ndev->mc_list; + int i, mc_cnt = ndev->mc_count; + u32 tmp32, hash_val, hashlo, hashhi; + unsigned long flags; + + spin_lock_irqsave(&pldat->lock, flags); + + /* Set station address */ + __lpc_set_mac(pldat, ndev->dev_addr); + + tmp32 = LPC_RXFLTRW_ACCEPTUBROADCAST | LPC_RXFLTRW_ACCEPTPERFECT; + + if (ndev->flags & IFF_PROMISC) + tmp32 |= LPC_RXFLTRW_ACCEPTUNICAST | LPC_RXFLTRW_ACCEPTUMULTICAST; + if (ndev->flags & IFF_ALLMULTI) + tmp32 |= LPC_RXFLTRW_ACCEPTUMULTICAST; + + if(mc_cnt) + tmp32 |= LPC_RXFLTRW_ACCEPTUMULTICASTHASH; + + writel(tmp32, LPC_ENET_RXFILTER_CTRL(pldat->net_base)); + + + /* Set initial hash table */ + hashlo = 0x0; + hashhi = 0x0; + + /* 64 bits : multicast address in hash table */ + for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { + hash_val = (ether_crc(6, mcptr->dmi_addr) >> 23) & 0x3F; + + if (hash_val >= 32) + hashhi |= 1 << (hash_val - 32); + else + hashlo |= 1 << hash_val; + } + + writel(hashlo, LPC_ENET_HASHFILTERL(pldat->net_base)); + writel(hashhi, LPC_ENET_HASHFILTERH(pldat->net_base)); + + spin_unlock_irqrestore(&pldat->lock, flags); +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void lpc_net_poll_controller(struct net_device *ndev) +{ + disable_irq(ndev->irq); + __lpc_eth_interrupt(dev->irq, ndev); + enable_irq(ndev->irq); +} +#endif + +static int lpc_net_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct phy_device *phydev = pldat->phy_dev; + + if (!netif_running(ndev)) + { + return -EINVAL; + } + + if (!phydev) + { + return -ENODEV; + } + + return phy_mii_ioctl(phydev, if_mii(req), cmd); +} + +static int lpc_net_open(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + + /* if the phy is not yet registered, retry later*/ + if (!pldat->phy_dev) + { + return -EAGAIN; + } + + if (netif_msg_ifup(pldat)) + { + dev_dbg(&pldat->pdev->dev, "enabling %s\n", ndev->name); + } + + if (!is_valid_ether_addr(ndev->dev_addr)) + { + return -EADDRNOTAVAIL; + } + + __lpc_net_clock_enable(pldat, 1); + + /* Reset and initialize */ + __lpc_eth_reset(pldat); + __lpc_eth_init(pldat); + + /* schedule a link state check */ + phy_start(pldat->phy_dev); + netif_start_queue(ndev); + + return 0; +} + +/* + * Ethtool ops + */ +static void lpc_net_ethtool_getdrvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, MODNAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, dev_name(ndev->dev.parent)); +} + +static u32 lpc_net_ethtool_getmsglevel(struct net_device *ndev) +{ + struct netdata_local *pldat = netdev_priv(ndev); + + return pldat->msg_enable; +} + +static void lpc_net_ethtool_setmsglevel(struct net_device *ndev, u32 level) +{ + struct netdata_local *pldat = netdev_priv(ndev); + + pldat->msg_enable = level; +} + +static int lpc_net_ethtool_getsettings(struct net_device *ndev, + struct ethtool_cmd *cmd) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct phy_device *phydev = pldat->phy_dev; + + if (!phydev) + { + return -ENODEV; + } + + return phy_ethtool_gset(phydev, cmd); +} + +static int lpc_net_ethtool_setsettings(struct net_device *ndev, + struct ethtool_cmd *cmd) +{ + struct netdata_local *pldat = netdev_priv(ndev); + struct phy_device *phydev = pldat->phy_dev; + + if (!phydev) + { + return -ENODEV; + } + + return phy_ethtool_sset(phydev, cmd); +} + +static const struct ethtool_ops lpc_net_ethtool_ops = { + .get_drvinfo = lpc_net_ethtool_getdrvinfo, + .get_settings = lpc_net_ethtool_getsettings, + .set_settings = lpc_net_ethtool_setsettings, + .get_msglevel = lpc_net_ethtool_getmsglevel, + .set_msglevel = lpc_net_ethtool_setmsglevel, + .get_link = ethtool_op_get_link, +}; + +static const struct net_device_ops lpc_netdev_ops = { + .ndo_open = lpc_net_open, + .ndo_stop = lpc_net_close, + .ndo_start_xmit = lpc_net_hard_start_xmit, + .ndo_set_multicast_list = lpc_net_set_multicast_list, +// .ndo_get_stats = tsi108_get_stats, + .ndo_do_ioctl = lpc_net_ioctl, + .ndo_tx_timeout = lpc_net_timeout, + .ndo_set_mac_address = lpc_set_mac_address, +// .ndo_validate_addr = eth_validate_addr, +// .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .poll_controller = lpc_net_poll_controller; +#endif +}; + +static int lpc_net_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + struct net_device *ndev; + struct netdata_local *pldat; + struct phy_device *phydev; + dma_addr_t dma_handle; + int irq, ret; + + /* Get platform resources */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if ((!res) || (irq < 0) || (irq >= NR_IRQS)) { + dev_err(&pdev->dev, "error getting resources.\n"); + ret = -ENXIO; + goto err_exit; + } + + /* Allocate net driver data structure */ + ndev = alloc_etherdev(sizeof(struct netdata_local)); + if (!ndev) { + dev_err(&pdev->dev, "could not allocate device.\n"); + ret = -ENOMEM; + goto err_exit; + } + + SET_NETDEV_DEV(ndev, &pdev->dev); + + pldat = netdev_priv(ndev); + pldat->pdev = pdev; + pldat->ndev = ndev; + + spin_lock_init(&pldat->lock); + + /* Save resources */ + pldat->net_region_start = res->start; + pldat->net_region_size = res->end - res->start + 1; + ndev->irq = irq; + + /* Get clock for the device */ + pldat->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(pldat->clk)) { + dev_err(&pdev->dev, "error getting clock.\n"); + ret = PTR_ERR(pldat->clk); + goto err_out_free_dev; + } + + /* Enable network clock */ + __lpc_net_clock_enable(pldat, 1); + + /* Map IO space */ + pldat->net_base = ioremap(pldat->net_region_start, pldat->net_region_size); + if (!pldat->net_base) { + dev_err(&pdev->dev, "failed to map registers\n"); + ret = -ENOMEM; + goto err_out_disable_clocks; + } + ret = request_irq(ndev->irq, __lpc_eth_interrupt, 0, + ndev->name, ndev); + if (ret) { + dev_err(&pdev->dev, "error requesting interrupt.\n"); + goto err_out_iounmap; + } + + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(ndev); + + /* Setup driver functions */ + ndev->netdev_ops = &lpc_netdev_ops; + ndev->ethtool_ops = &lpc_net_ethtool_ops; + ndev->base_addr = pldat->net_region_start; + ndev->watchdog_timeo = msecs_to_jiffies(watchdog); + + /* Save board specific configuration */ + pldat->ncfg = (struct lpc_net_cfg *) pdev->dev.platform_data; + if (pldat->ncfg == NULL) { + dev_err(&pdev->dev, "error requesting interrupt.\n"); + pldat->ncfg = &__lpc_local_net_config; + } + + /* Get size of DMA buffers/descriptors region */ + pldat->dma_buff_size = (ENET_TX_DESC + ENET_RX_DESC) * (ENET_MAXF_SIZE + + sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t)); + pldat->dma_buff_base_v = 0; + +#if defined(CONFIG_ARCH_LPC32XX_IRAM_FOR_NET) + dma_handle = (dma_addr_t) LPC32XX_IRAM_BASE; + if (pldat->dma_buff_size <= lpc32xx_return_iram_size()) + pldat->dma_buff_base_v = (u32) io_p2v(LPC32XX_IRAM_BASE); + else + pr_err("%s: IRAM not big enough for net buffers, " + "using SDRAM instead.\n", MODNAME); +#endif + + if (pldat->dma_buff_base_v == 0) { + pldat->dma_buff_size += 4096; /* Allows room for alignment */ + + /* Align on the next highest page entry size */ + pldat->dma_buff_size &= 0Xfffff000; + pldat->dma_buff_size += 0X00001000; + + /* Allocate a chunk of memory for the DMA ethernet buffers and descriptors */ + pldat->dma_buff_base_v = (u32) dma_alloc_coherent(&pldat->pdev->dev, + pldat->dma_buff_size, &dma_handle, GFP_KERNEL); + + if (pldat->dma_buff_base_v == (u32) NULL) + { + dev_err(&pdev->dev, "error getting DMA region.\n"); + ret = -ENOMEM; + goto err_out_free_irq; + } + } + pldat->dma_buff_base_p = (u32) dma_handle; + + pr_debug("IO address start :0x%08x\n", (u32) pldat->net_region_start); + pr_debug("IO address size :%d\n", (u32) pldat->net_region_size); + pr_debug("IO address (mapped) :0x%08x\n", (u32) pldat->net_base); + pr_debug("IRQ number :%d\n", ndev->irq); + pr_debug("DMA buffer size :%d\n", pldat->dma_buff_size); + pr_debug("DMA buffer P address :0x%08x\n", pldat->dma_buff_base_p); + pr_debug("DMA buffer V address :0x%08x\n", pldat->dma_buff_base_v); + + /* Get the board MAC address */ + ret = get_mac_addr(ndev->dev_addr); + if (ret) { + /* Mac address load error */ + goto err_out_dma_unmap; + } + if (!is_valid_ether_addr(ndev->dev_addr)) { + pr_info("%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", ndev->name); + } + + /* Reset the ethernet controller */ + __lpc_eth_reset(pldat); + + /* then shut everything down to save power */ + __lpc_net_shutdown(pldat); + + /* Set default parameters */ + pldat->msg_enable = NETIF_MSG_LINK; + + /* Force an MII interface reset and clock setup */ + __lpc_mii_mngt_reset(pldat); + + /* Force default PHY interface setup in chip, this will probably be + changed by the PHY driver */ + pldat->link = 0; + pldat->speed = 100; + pldat->duplex = DUPLEX_FULL; + __lpc_params_setup(pldat); + + ret = register_netdev(ndev); + if (ret) { + dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); + goto err_out_dma_unmap; + } + platform_set_drvdata(pdev, ndev); + + if (lpc_mii_init(pldat) != 0) { + goto err_out_unregister_netdev; + } + + pr_info("%s: LPC mac at 0x%08lx irq %d\n", + ndev->name, ndev->base_addr, ndev->irq); + + phydev = pldat->phy_dev; + pr_info("%s: attached PHY driver [%s] " + "(mii_bus:phy_addr=%s, irq=%d)\n", + ndev->name, phydev->drv->name, dev_name(&phydev->dev), + phydev->irq); + + return 0; + +err_out_unregister_netdev: + platform_set_drvdata(pdev, NULL); + unregister_netdev(ndev); +err_out_dma_unmap: +#if defined(CONFIG_ARCH_LPC32XX_IRAM_FOR_NET) + if (pldat->dma_buff_size > lpc32xx_return_iram_size()) +#endif + dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, + (void *) pldat->dma_buff_base_v, (dma_addr_t) pldat->dma_buff_base_p); +err_out_free_irq: + free_irq(ndev->irq, ndev); +err_out_iounmap: + iounmap(pldat->net_base); +err_out_disable_clocks: + clk_disable(pldat->clk); + clk_put(pldat->clk); +err_out_free_dev: + free_netdev(ndev); +err_exit: + pr_err("%s: not found (%d).\n", MODNAME, ret); + return ret; +} + +static int lpc_net_drv_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct netdata_local *pldat = netdev_priv(ndev); + + unregister_netdev(ndev); + platform_set_drvdata(pdev, NULL); + +#if defined(CONFIG_ARCH_LPC32XX_IRAM_FOR_NET) + if (pldat->dma_buff_size > lpc32xx_return_iram_size()) +#endif + dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, + (void *) pldat->dma_buff_base_v, + (dma_addr_t) pldat->dma_buff_base_p); + free_irq(ndev->irq, ndev); + iounmap(pldat->net_base); + clk_disable(pldat->clk); + clk_put(pldat->clk); + free_netdev(ndev); + + return 0; +} + +static int lpc_net_drv_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct netdata_local *pldat = netdev_priv(ndev); + + if (ndev) { + if (netif_running(ndev)) { + netif_device_detach(ndev); + __lpc_net_shutdown(pldat); + clk_disable(pldat->clk); + } + } + + return 0; +} + +static int lpc_net_drv_resume(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct netdata_local *pldat; + + if (ndev) { + if (netif_running(ndev)) { + pldat = netdev_priv(ndev); + + /* Enable interface clock */ + clk_enable(pldat->clk); + + /* Reset and initialize */ + __lpc_eth_reset(pldat); + __lpc_eth_init(pldat); + + netif_device_attach(ndev); + } + } + + return 0; +} + +static struct platform_driver lpc_net_driver = { + .probe = lpc_net_drv_probe, + .remove = __devexit_p(lpc_net_drv_remove), + .suspend = lpc_net_drv_suspend, + .resume = lpc_net_drv_resume, + .driver = { + .name = MODNAME, + }, +}; + +static int __init lpc_net_init(void) +{ + return platform_driver_register(&lpc_net_driver); +} + +static void __exit lpc_net_cleanup(void) +{ + platform_driver_unregister(&lpc_net_driver); +} + +module_init(lpc_net_init); +module_exit(lpc_net_cleanup); + +MODULE_AUTHOR("Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LPC_ETH_H +#define __LPC_ETH_H + +#include + +/* + * Ethernet MAC controller Register offsets + */ +#define LPC_ENET_MAC1(x) (x + 0x000) +#define LPC_ENET_MAC2(x) (x + 0x004) +#define LPC_ENET_IPGT(x) (x + 0x008) +#define LPC_ENET_IPGR(x) (x + 0x00C) +#define LPC_ENET_CLRT(x) (x + 0x010) +#define LPC_ENET_MAXF(x) (x + 0x014) +#define LPC_ENET_SUPP(x) (x + 0x018) +#define LPC_ENET_TEST(x) (x + 0x01C) +#define LPC_ENET_MCFG(x) (x + 0x020) +#define LPC_ENET_MCMD(x) (x + 0x024) +#define LPC_ENET_MADR(x) (x + 0x028) +#define LPC_ENET_MWTD(x) (x + 0x02C) +#define LPC_ENET_MRDD(x) (x + 0x030) +#define LPC_ENET_MIND(x) (x + 0x034) +#define LPC_ENET_SA0(x) (x + 0x040) +#define LPC_ENET_SA1(x) (x + 0x044) +#define LPC_ENET_SA2(x) (x + 0x048) +#define LPC_ENET_COMMAND(x) (x + 0x100) +#define LPC_ENET_STATUS(x) (x + 0x104) +#define LPC_ENET_RXDESCRIPTOR(x) (x + 0x108) +#define LPC_ENET_RXSTATUS(x) (x + 0x10C) +#define LPC_ENET_RXDESCRIPTORNUMBER(x) (x + 0x110) +#define LPC_ENET_RXPRODUCEINDEX(x) (x + 0x114) +#define LPC_ENET_RXCONSUMEINDEX(x) (x + 0x118) +#define LPC_ENET_TXDESCRIPTOR(x) (x + 0x11C) +#define LPC_ENET_TXSTATUS(x) (x + 0x120) +#define LPC_ENET_TXDESCRIPTORNUMBER(x) (x + 0x124) +#define LPC_ENET_TXPRODUCEINDEX(x) (x + 0x128) +#define LPC_ENET_TXCONSUMEINDEX(x) (x + 0x12C) +#define LPC_ENET_TSV0(x) (x + 0x158) +#define LPC_ENET_TSV1(x) (x + 0x15C) +#define LPC_ENET_RSV(x) (x + 0x160) +#define LPC_ENET_FLOWCONTROLCOUNTER(x) (x + 0x170) +#define LPC_ENET_FLOWCONTROLSTATUS(x) (x + 0x174) +#define LPC_ENET_RXFILTER_CTRL(x) (x + 0x200) +#define LPC_ENET_RXFILTERWOLSTATUS(x) (x + 0x204) +#define LPC_ENET_RXFILTERWOLCLEAR(x) (x + 0x208) +#define LPC_ENET_HASHFILTERL(x) (x + 0x210) +#define LPC_ENET_HASHFILTERH(x) (x + 0x214) +#define LPC_ENET_INTSTATUS(x) (x + 0xFE0) +#define LPC_ENET_INTENABLE(x) (x + 0xFE4) +#define LPC_ENET_INTCLEAR(x) (x + 0xFE8) +#define LPC_ENET_INTSET(x) (x + 0xFEC) +#define LPC_ENET_POWERDOWN(x) (x + 0xFF4) + +/* + * Structure of a TX/RX descriptors and RX status + */ +struct txrx_desc_t { + volatile u32 packet; + volatile u32 control; +}; +struct rx_status_t { + volatile u32 statusinfo; + volatile u32 statushashcrc; +}; + +/* + * mac1 register definitions + */ +#define LPC_MAC1_RECV_ENABLE (1 << 0) +#define LPC_MAC1_PASS_ALL_RX_FRAMES (1 << 1) +#define LPC_MAC1_RX_FLOW_CONTROL (1 << 2) +#define LPC_MAC1_TX_FLOW_CONTROL (1 << 3) +#define LPC_MAC1_LOOPBACK (1 << 4) +#define LPC_MAC1_RESET_TX (1 << 8) +#define LPC_MAC1_RESET_MCS_TX (1 << 9) +#define LPC_MAC1_RESET_RX (1 << 10) +#define LPC_MAC1_RESET_MCS_RX (1 << 11) +#define LPC_MAC1_SIMULATION_RESET (1 << 14) +#define LPC_MAC1_SOFT_RESET (1 << 15) + +/* + * mac2 register definitions + */ +#define LPC_MAC2_FULL_DUPLEX (1 << 0) +#define LPC_MAC2_FRAME_LENGTH_CHECKING (1 << 1) +#define LPC_MAC2_HUGH_LENGTH_CHECKING (1 << 2) +#define LPC_MAC2_DELAYED_CRC (1 << 3) +#define LPC_MAC2_CRC_ENABLE (1 << 4) +#define LPC_MAC2_PAD_CRC_ENABLE (1 << 5) +#define LPC_MAC2_VLAN_PAD_ENABLE (1 << 6) +#define LPC_MAC2_AUTO_DETECT_PAD_ENABLE (1 << 7) +#define LPC_MAC2_PURE_PREAMBLE_ENFORCEMENT (1 << 8) +#define LPC_MAC2_LONG_PREAMBLE_ENFORCEMENT (1 << 9) +#define LPC_MAC2_NO_BACKOFF (1 << 12) +#define LPC_MAC2_BACK_PRESSURE (1 << 13) +#define LPC_MAC2_EXCESS_DEFER (1 << 14) + +/* + * ipgt register definitions + */ +#define LPC_IPGT_LOAD(n) ((n) & 0x7F) + +/* + * ipgr register definitions + */ +#define LPC_IPGR_LOAD_PART2(n) ((n) & 0x7F) +#define LPC_IPGR_LOAD_PART1(n) (((n) & 0x7F) << 8) + +/* + * clrt register definitions + */ +#define LPC_CLRT_LOAD_RETRY_MAX(n) ((n) & 0xF) +#define LPC_CLRT_LOAD_COLLISION_WINDOW(n) (((n) & 0x3F) << 8) + +/* + * maxf register definitions + */ +#define LPC_MAXF_LOAD_MAX_FRAME_LEN(n) ((n) & 0xFFFF) + +/* + * supp register definitions + */ +#define LPC_SUPP_SPEED (1 << 8) +#define LPC_SUPP_RESET_RMII (1 << 11) + +/* + * test register definitions + */ +#define LPC_TEST_SHORTCUT_PAUSE_QUANTA (1 << 0) +#define LPC_TEST_PAUSE (1 << 1) +#define LPC_TEST_BACKPRESSURE (1 << 2) + +/* + * mcfg register definitions + */ +#define LPC_MCFG_SCAN_INCREMENT (1 << 0) +#define LPC_MCFG_SUPPRESS_PREAMBLE (1 << 1) +#define LPC_MCFG_CLOCK_SELECT(n) (((n) & 0x7) << 2) +#define LPC_MCFG_CLOCK_HOST_DIV_4 0 +#define LPC_MCFG_CLOCK_HOST_DIV_6 2 +#define LPC_MCFG_CLOCK_HOST_DIV_8 3 +#define LPC_MCFG_CLOCK_HOST_DIV_10 4 +#define LPC_MCFG_CLOCK_HOST_DIV_14 5 +#define LPC_MCFG_CLOCK_HOST_DIV_20 6 +#define LPC_MCFG_CLOCK_HOST_DIV_28 7 +#define LPC_MCFG_RESET_MII_MGMT (1 << 15) + +/* + * mcmd register definitions + */ +#define LPC_MCMD_READ (1 << 0) +#define LPC_MCMD_SCAN (1 << 1) + +/* + * madr register definitions + */ +#define LPC_MADR_REGISTER_ADDRESS(n) ((n) & 0x1F) +#define LPC_MADR_PHY_0ADDRESS(n) (((n) & 0x1F) << 8) + +/* + * mwtd register definitions + */ +#define LPC_MWDT_WRITE(n) ((n) & 0xFFFF) + +/* + * mrdd register definitions + */ +#define LPC_MRDD_READ_MASK 0xFFFF + +/* + * mind register definitions + */ +#define LPC_MIND_BUSY (1 << 0) +#define LPC_MIND_SCANNING (1 << 1) +#define LPC_MIND_NOT_VALID (1 << 2) +#define LPC_MIND_MII_LINK_FAIL (1 << 3) + +/* + * command register definitions + */ +#define LPC_COMMAND_RXENABLE (1 << 0) +#define LPC_COMMAND_TXENABLE (1 << 1) +#define LPC_COMMAND_REG_RESET (1 << 3) +#define LPC_COMMAND_TXRESET (1 << 4) +#define LPC_COMMAND_RXRESET (1 << 5) +#define LPC_COMMAND_PASSRUNTFRAME (1 << 6) +#define LPC_COMMAND_PASSRXFILTER (1 << 7) +#define LPC_COMMAND_TXFLOWCONTROL (1 << 8) +#define LPC_COMMAND_RMII (1 << 9) +#define LPC_COMMAND_FULLDUPLEX (1 << 10) + +/* + * status register definitions + */ +#define LPC_STATUS_RXACTIVE (1 << 0) +#define LPC_STATUS_TXACTIVE (1 << 1) + +/* + * tsv0 register definitions + */ +#define LPC_TSV0_CRC_ERROR (1 << 0) +#define LPC_TSV0_LENGTH_CHECK_ERROR (1 << 1) +#define LPC_TSV0_LENGTH_OUT_OF_RANGE (1 << 2) +#define LPC_TSV0_DONE (1 << 3) +#define LPC_TSV0_MULTICAST (1 << 4) +#define LPC_TSV0_BROADCAST (1 << 5) +#define LPC_TSV0_PACKET_DEFER (1 << 6) +#define LPC_TSV0_ESCESSIVE_DEFER (1 << 7) +#define LPC_TSV0_ESCESSIVE_COLLISION (1 << 8) +#define LPC_TSV0_LATE_COLLISION (1 << 9) +#define LPC_TSV0_GIANT (1 << 10) +#define LPC_TSV0_UNDERRUN (1 << 11) +#define LPC_TSV0_TOTAL_BYTES(n) (((n) >> 12) & 0xFFFF) +#define LPC_TSV0_CONTROL_FRAME (1 << 28) +#define LPC_TSV0_PAUSE (1 << 29) +#define LPC_TSV0_BACKPRESSURE (1 << 30) +#define LPC_TSV0_VLAN (1 << 31) + +/* + * tsv1 register definitions + */ +#define LPC_TSV1_TRANSMIT_BYTE_COUNT(n) ((n) & 0xFFFF) +#define LPC_TSV1_COLLISION_COUNT(n) (((n) >> 16) & 0xF) + +/* + * rsv register definitions + */ +#define LPC_RSV_RECEIVED_BYTE_COUNT(n) ((n) & 0xFFFF) +#define LPC_RSV_RXDV_EVENT_IGNORED (1 << 16) +#define LPC_RSV_RXDV_EVENT_PREVIOUSLY_SEEN (1 << 17) +#define LPC_RSV_CARRIER_EVNT_PREVIOUS_SEEN (1 << 18) +#define LPC_RSV_RECEIVE_CODE_VIOLATION (1 << 19) +#define LPC_RSV_CRC_ERROR (1 << 20) +#define LPC_RSV_LENGTH_CHECK_ERROR (1 << 21) +#define LPC_RSV_LENGTH_OUT_OF_RANGE (1 << 22) +#define LPC_RSV_RECEIVE_OK (1 << 23) +#define LPC_RSV_MULTICAST (1 << 24) +#define LPC_RSV_BROADCAST (1 << 25) +#define LPC_RSV_DRIBBLE_NIBBLE (1 << 26) +#define LPC_RSV_CONTROL_FRAME (1 << 27) +#define LPC_RSV_PAUSE (1 << 28) +#define LPC_RSV_UNSUPPORTED_OPCODE (1 << 29) +#define LPC_RSV_VLAN (1 << 30) + +/* + * flowcontrolcounter register definitions + */ +#define LPC_FCCR_MIRRORCOUNTER(n) ((n) & 0xFFFF) +#define LPC_FCCR_PAUSETIMER(n) (((n) >> 16) & 0xFFFF) + +/* + * flowcontrolstatus register definitions + */ +#define LPC_FCCR_MIRRORCOUNTERCURRENT(n) ((n) & 0xFFFF) + +/* + * rxfliterctrl, rxfilterwolstatus, and rxfilterwolclear shared + * register definitions + */ +#define LPC_RXFLTRW_ACCEPTUNICAST (1 << 0) +#define LPC_RXFLTRW_ACCEPTUBROADCAST (1 << 1) +#define LPC_RXFLTRW_ACCEPTUMULTICAST (1 << 2) +#define LPC_RXFLTRW_ACCEPTUNICASTHASH (1 << 3) +#define LPC_RXFLTRW_ACCEPTUMULTICASTHASH (1 << 4) +#define LPC_RXFLTRW_ACCEPTPERFECT (1 << 5) + +/* + * rxfliterctrl register definitions + */ +#define LPC_RXFLTRWSTS_MAGICPACKETENWOL (1 << 12) +#define LPC_RXFLTRWSTS_RXFILTERENWOL (1 << 13) + +/* + * rxfilterwolstatus/rxfilterwolclear register definitions + */ +#define LPC_RXFLTRWSTS_RXFILTERWOL (1 << 7) +#define LPC_RXFLTRWSTS_MAGICPACKETWOL (1 << 8) + +/* + * intstatus, intenable, intclear, and Intset shared register + * definitions + */ +#define LPC_MACINT_RXOVERRUNINTEN (1 << 0) +#define LPC_MACINT_RXERRORONINT (1 << 1) +#define LPC_MACINT_RXFINISHEDINTEN (1 << 2) +#define LPC_MACINT_RXDONEINTEN (1 << 3) +#define LPC_MACINT_TXUNDERRUNINTEN (1 << 4) +#define LPC_MACINT_TXERRORINTEN (1 << 5) +#define LPC_MACINT_TXFINISHEDINTEN (1 << 6) +#define LPC_MACINT_TXDONEINTEN (1 << 7) +#define LPC_MACINT_SOFTINTEN (1 << 12) +#define LPC_MACINT_WAKEUPINTEN (1 << 13) + +/* + * powerdown register definitions + */ +#define LPC_POWERDOWN_MACAHB (1 << 31) + +#endif diff -purN linux-2.6.34/drivers/net/Makefile linux-2.6.34-dev/drivers/net/Makefile --- linux-2.6.34/drivers/net/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/net/Makefile 2010-10-15 14:10:00.118524167 +0100 @@ -144,6 +144,7 @@ obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o +obj-$(CONFIG_LPC_ENET) += lpc_eth.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o diff -purN linux-2.6.34/drivers/rtc/Kconfig linux-2.6.34-dev/drivers/rtc/Kconfig --- linux-2.6.34/drivers/rtc/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/rtc/Kconfig 2010-10-15 14:10:00.118524167 +0100 @@ -888,4 +888,10 @@ config RTC_DRV_MPC5121 This driver can also be built as a module. If so, the module will be called rtc-mpc5121. +config RTC_DRV_LPC32XX + depends on ARCH_LPC32XX + tristate "NXP LPC32XX RTC" + help + This enables support for the NXP 1-second RTC in the LPC32XX + endif # RTC_CLASS diff -purN linux-2.6.34/drivers/rtc/Makefile linux-2.6.34-dev/drivers/rtc/Makefile --- linux-2.6.34/drivers/rtc/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/rtc/Makefile 2010-10-15 14:10:00.128530188 +0100 @@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93 obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o +obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o diff -purN linux-2.6.34/drivers/rtc/rtc-lpc32xx.c linux-2.6.34-dev/drivers/rtc/rtc-lpc32xx.c --- linux-2.6.34/drivers/rtc/rtc-lpc32xx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/rtc/rtc-lpc32xx.c 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2010 NXP Semiconductors + * + * 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. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Clock and Power control register offsets + */ +#define LPC32XX_RTC_UCOUNT 0x00 +#define LPC32XX_RTC_DCOUNT 0x04 +#define LPC32XX_RTC_MATCH0 0x08 +#define LPC32XX_RTC_MATCH1 0x0C +#define LPC32XX_RTC_CTRL 0x10 +#define LPC32XX_RTC_INTSTAT 0x14 +#define LPC32XX_RTC_KEY 0x18 +#define LPC32XX_RTC_SRAM 0x80 + +#define LPC32XX_RTC_CTRL_MATCH0 (1 << 0) +#define LPC32XX_RTC_CTRL_MATCH1 (1 << 1) +#define LPC32XX_RTC_CTRL_ONSW_MATCH0 (1 << 2) +#define LPC32XX_RTC_CTRL_ONSW_MATCH1 (1 << 3) +#define LPC32XX_RTC_CTRL_SW_RESET (1 << 4) +#define LPC32XX_RTC_CTRL_CNTR_DIS (1 << 6) +#define LPC32XX_RTC_CTRL_ONSW_FORCE_HI (1 << 7) + +#define LPC32XX_RTC_INTSTAT_MATCH0 (1 << 0) +#define LPC32XX_RTC_INTSTAT_MATCH1 (1 << 1) +#define LPC32XX_RTC_INTSTAT_ONSW (1 << 2) + +#define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27 + +#define RTC_NAME "rtc-lpc32xx" + +#define rtc_readl(dev, reg) \ + __raw_readl((dev)->rtc_base + (reg)) +#define rtc_writel(dev, reg, val) \ + __raw_writel((val), (dev)->rtc_base + (reg)) + +struct lpc32xx_rtc { + void __iomem *rtc_base; + int irq; + unsigned char alarm_enabled; + struct rtc_device *rtc; + spinlock_t lock; +}; + +static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) +{ + unsigned long elapsed_sec; + struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + + elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); + rtc_time_to_tm(elapsed_sec, time); + + return rtc_valid_tm(time); +} + +static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) +{ + struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + u32 tmp; + + spin_lock_irq(&rtc->lock); + + /* RTC must be disabled during count update */ + tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS); + rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs); + rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs); + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS); + + spin_unlock_irq(&rtc->lock); + + return 0; +} + +static int lpc32xx_rtc_read_alarm(struct device *dev, + struct rtc_wkalrm *wkalrm) +{ + struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + + rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); + wkalrm->enabled = rtc->alarm_enabled; + wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) & + LPC32XX_RTC_INTSTAT_MATCH0); + + return rtc_valid_tm(&wkalrm->time); +} + +static int lpc32xx_rtc_set_alarm(struct device *dev, + struct rtc_wkalrm *wkalrm) +{ + struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + unsigned long alarmsecs; + u32 tmp; + int ret; + + ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs); + if (ret < 0) { + dev_warn(dev, "Failed to convert time: %d\n", ret); + return ret; + } + + spin_lock_irq(&rtc->lock); + + /* Disable alarm during update */ + tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0); + + rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs); + + rtc->alarm_enabled = wkalrm->enabled; + if (wkalrm->enabled) { + rtc_writel(rtc, LPC32XX_RTC_INTSTAT, + LPC32XX_RTC_INTSTAT_MATCH0); + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | + LPC32XX_RTC_CTRL_MATCH0); + } + + spin_unlock_irq(&rtc->lock); + + return 0; +} + +static int lpc32xx_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + u32 tmp; + + spin_lock_irq(&rtc->lock); + tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); + + if (enabled) { + rtc->alarm_enabled = 1; + tmp |= LPC32XX_RTC_CTRL_MATCH0; + } else { + rtc->alarm_enabled = 0; + tmp &= ~LPC32XX_RTC_CTRL_MATCH0; + } + + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); + spin_unlock_irq(&rtc->lock); + + return 0; +} + +static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) +{ + struct lpc32xx_rtc *rtc = dev; + + spin_lock(&rtc->lock); + + /* Disable alarm interrupt */ + rtc_writel(rtc, LPC32XX_RTC_CTRL, + rtc_readl(rtc, LPC32XX_RTC_CTRL) & + ~LPC32XX_RTC_CTRL_MATCH0); + rtc->alarm_enabled = 0; + + /* + * Write a large value to the match value so the RTC won't + * keep firing the match status + */ + rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); + rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0); + + spin_unlock(&rtc->lock); + + rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +static const struct rtc_class_ops lpc32xx_rtc_ops = { + .read_time = lpc32xx_rtc_read_time, + .set_mmss = lpc32xx_rtc_set_mmss, + .read_alarm = lpc32xx_rtc_read_alarm, + .set_alarm = lpc32xx_rtc_set_alarm, + .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, +}; + +static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct lpc32xx_rtc *rtc; + resource_size_t size; + int rtcirq; + u32 tmp; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Can't get memory resource\n"); + return -ENOENT; + } + + rtcirq = platform_get_irq(pdev, 0); + if (rtcirq < 0 || rtcirq >= NR_IRQS) { + dev_warn(&pdev->dev, "Can't get interrupt resource\n"); + rtcirq = -1; + } + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (unlikely(!rtc)) { + dev_err(&pdev->dev, "Can't allocate memory\n"); + return -ENOMEM; + } + rtc->irq = rtcirq; + + size = resource_size(res); + + if (!devm_request_mem_region(&pdev->dev, res->start, size, + pdev->name)) { + dev_err(&pdev->dev, "RTC registers are not free\n"); + return -EBUSY; + } + + rtc->rtc_base = devm_ioremap(&pdev->dev, res->start, size); + if (!rtc->rtc_base) { + dev_err(&pdev->dev, "Can't map memory\n"); + return -ENOMEM; + } + + spin_lock_init(&rtc->lock); + + /* + * The RTC is on a seperate power domain and can keep it's state + * across a chip power cycle. If the RTC has never been previously + * setup, then set it up now for the first time. + */ + tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); + if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) { + tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET | + LPC32XX_RTC_CTRL_CNTR_DIS | + LPC32XX_RTC_CTRL_MATCH0 | + LPC32XX_RTC_CTRL_MATCH1 | + LPC32XX_RTC_CTRL_ONSW_MATCH0 | + LPC32XX_RTC_CTRL_ONSW_MATCH1 | + LPC32XX_RTC_CTRL_ONSW_FORCE_HI); + rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); + + /* Clear latched interrupt states */ + rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); + rtc_writel(rtc, LPC32XX_RTC_INTSTAT, + LPC32XX_RTC_INTSTAT_MATCH0 | + LPC32XX_RTC_INTSTAT_MATCH1 | + LPC32XX_RTC_INTSTAT_ONSW); + + /* Write key value to RTC so it won't reload on reset */ + rtc_writel(rtc, LPC32XX_RTC_KEY, + LPC32XX_RTC_KEY_ONSW_LOADVAL); + } else { + rtc_writel(rtc, LPC32XX_RTC_CTRL, + tmp & ~LPC32XX_RTC_CTRL_MATCH0); + } + + platform_set_drvdata(pdev, rtc); + + rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtc->rtc)) { + dev_err(&pdev->dev, "Can't get RTC\n"); + platform_set_drvdata(pdev, NULL); + return PTR_ERR(rtc->rtc); + } + + /* + * IRQ is enabled after device registration in case alarm IRQ + * is pending upon suspend exit. + */ + if (rtc->irq >= 0) { + if (devm_request_irq(&pdev->dev, rtc->irq, + lpc32xx_rtc_alarm_interrupt, + IRQF_DISABLED, pdev->name, rtc) < 0) { + dev_warn(&pdev->dev, "Can't request interrupt.\n"); + rtc->irq = -1; + } else { + device_init_wakeup(&pdev->dev, 1); + } + } + + return 0; +} + +static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev) +{ + struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); + + if (rtc->irq >= 0) + device_init_wakeup(&pdev->dev, 0); + + platform_set_drvdata(pdev, NULL); + rtc_device_unregister(rtc->rtc); + + return 0; +} + +#ifdef CONFIG_PM +static int lpc32xx_rtc_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); + + if (rtc->irq >= 0) { + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(rtc->irq); + else + disable_irq_wake(rtc->irq); + } + + return 0; +} + +static int lpc32xx_rtc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); + + if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev)) + disable_irq_wake(rtc->irq); + + return 0; +} + +/* Unconditionally disable the alarm */ +static int lpc32xx_rtc_freeze(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); + + spin_lock_irq(&rtc->lock); + + rtc_writel(rtc, LPC32XX_RTC_CTRL, + rtc_readl(rtc, LPC32XX_RTC_CTRL) & + ~LPC32XX_RTC_CTRL_MATCH0); + + spin_unlock_irq(&rtc->lock); + + return 0; +} + +static int lpc32xx_rtc_thaw(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); + + if (rtc->alarm_enabled) { + spin_lock_irq(&rtc->lock); + + rtc_writel(rtc, LPC32XX_RTC_CTRL, + rtc_readl(rtc, LPC32XX_RTC_CTRL) | + LPC32XX_RTC_CTRL_MATCH0); + + spin_unlock_irq(&rtc->lock); + } + + return 0; +} + +static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { + .suspend = lpc32xx_rtc_suspend, + .resume = lpc32xx_rtc_resume, + .freeze = lpc32xx_rtc_freeze, + .thaw = lpc32xx_rtc_thaw, + .restore = lpc32xx_rtc_resume +}; + +#define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops) +#else +#define LPC32XX_RTC_PM_OPS NULL +#endif + +static struct platform_driver lpc32xx_rtc_driver = { + .probe = lpc32xx_rtc_probe, + .remove = __devexit_p(lpc32xx_rtc_remove), + .driver = { + .name = RTC_NAME, + .owner = THIS_MODULE, + .pm = LPC32XX_RTC_PM_OPS + }, +}; + +static int __init lpc32xx_rtc_init(void) +{ + return platform_driver_register(&lpc32xx_rtc_driver); +} +module_init(lpc32xx_rtc_init); + +static void __exit lpc32xx_rtc_exit(void) +{ + platform_driver_unregister(&lpc32xx_rtc_driver); +} +module_exit(lpc32xx_rtc_exit); + +MODULE_AUTHOR("Kevin Wells port.irq)) { unsigned char iir1; +#ifdef CONFIG_ARCH_LPC32XX + serial_outp(up, UART_FCR, UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); +#endif /* * Test for UARTs that do not reassert THRE when the * transmitter is idle and the interrupt has already diff -purN linux-2.6.34/drivers/serial/Kconfig linux-2.6.34-dev/drivers/serial/Kconfig --- linux-2.6.34/drivers/serial/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/serial/Kconfig 2010-10-15 14:10:00.128530188 +0100 @@ -1046,6 +1046,22 @@ config SERIAL_PNX8XXX_CONSOLE If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 and you want to use serial console, say Y. Otherwise, say N. +config SERIAL_HS_LPC32XX + tristate "LPC32xx high serial port support" + depends on ARCH_LPC32XX + select SERIAL_CORE + help + Support for the LPC32XX high speed serial ports + +config SERIAL_HS_LPC32XX_CONSOLE + bool "Enable LPC32XX high speed UART serial console" + depends on SERIAL_HS_LPC32XX + select SERIAL_CORE_CONSOLE + help + If you would like to be able to use one of the high speed serial + ports on the LPC32XX as the console, you can do so by answering + Y to this option. + config SERIAL_CORE tristate diff -purN linux-2.6.34/drivers/serial/lpc32xx_hs.c linux-2.6.34-dev/drivers/serial/lpc32xx_hs.c --- linux-2.6.34/drivers/serial/lpc32xx_hs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/serial/lpc32xx_hs.c 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,753 @@ +/* + * drivers/serial/lpc32xx_hs.c + * + * Author: Kevin Wells + * + * Copyright (C) 2010 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * High speed UART register offsets + */ +#define LPC32XX_HSUART_FIFO(x) (x + 0x00) +#define LPC32XX_HSUART_LEVEL(x) (x + 0x04) +#define LPC32XX_HSUART_IIR(x) (x + 0x08) +#define LPC32XX_HSUART_CTRL(x) (x + 0x0C) +#define LPC32XX_HSUART_RATE(x) (x + 0x10) + +#define LPC32XX_HSU_BREAK_DATA (1 << 10) +#define LPC32XX_HSU_ERROR_DATA (1 << 9) +#define LPC32XX_HSU_RX_EMPTY (1 << 8) + +#define LPC32XX_HSU_TX_LEV(n) (((n) >> 8) & 0xFF) +#define LPC32XX_HSU_RX_LEV(n) ((n) & 0xFF) + +#define LPC32XX_HSU_TX_INT_SET (1 << 6) +#define LPC32XX_HSU_RX_OE_INT (1 << 5) +#define LPC32XX_HSU_BRK_INT (1 << 4) +#define LPC32XX_HSU_FE_INT (1 << 3) +#define LPC32XX_HSU_RX_TIMEOUT_INT (1 << 2) +#define LPC32XX_HSU_RX_TRIG_INT (1 << 1) +#define LPC32XX_HSU_TX_INT (1 << 0) + +#define LPC32XX_HSU_HRTS_INV (1 << 21) +#define LPC32XX_HSU_HRTS_TRIG_8B (0x0 << 19) +#define LPC32XX_HSU_HRTS_TRIG_16B (0x1 << 19) +#define LPC32XX_HSU_HRTS_TRIG_32B (0x2 << 19) +#define LPC32XX_HSU_HRTS_TRIG_48B (0x3 << 19) +#define LPC32XX_HSU_HRTS_EN (1 << 18) +#define LPC32XX_HSU_TMO_DISABLED (0x0 << 16) +#define LPC32XX_HSU_TMO_INACT_4B (0x1 << 16) +#define LPC32XX_HSU_TMO_INACT_8B (0x2 << 16) +#define LPC32XX_HSU_TMO_INACT_16B (0x3 << 16) +#define LPC32XX_HSU_HCTS_INV (1 << 15) +#define LPC32XX_HSU_HCTS_EN (1 << 14) +#define LPC32XX_HSU_OFFSET(n) ((n) << 9) +#define LPC32XX_HSU_BREAK (1 << 8) +#define LPC32XX_HSU_ERR_INT_EN (1 << 7) +#define LPC32XX_HSU_RX_INT_EN (1 << 6) +#define LPC32XX_HSU_TX_INT_EN (1 << 5) +#define LPC32XX_HSU_RX_TL1B (0x0 << 2) +#define LPC32XX_HSU_RX_TL4B (0x1 << 2) +#define LPC32XX_HSU_RX_TL8B (0x2 << 2) +#define LPC32XX_HSU_RX_TL16B (0x3 << 2) +#define LPC32XX_HSU_RX_TL32B (0x4 << 2) +#define LPC32XX_HSU_RX_TL48B (0x5 << 2) +#define LPC32XX_HSU_TX_TLEMPTY (0x0 << 0) +#define LPC32XX_HSU_TX_TL0B (0x0 << 0) +#define LPC32XX_HSU_TX_TL4B (0x1 << 0) +#define LPC32XX_HSU_TX_TL8B (0x2 << 0) +#define LPC32XX_HSU_TX_TL16B (0x3 << 0) + +#define MODNAME "lpc32xx_hsuart" + +struct lpc32xx_hsuart_port { + struct uart_port port; +}; + +#define FIFO_READ_LIMIT 128 +#define MAX_PORTS 3 +#define LPC32XX_TTY_NAME "ttyTX" +#define LPC32XX_TTY_MINOR_START 196 +#define LPC32XX_TTY_MAJOR 204 +static struct lpc32xx_hsuart_port lpc32xx_hs_ports[MAX_PORTS]; + +#ifdef CONFIG_SERIAL_HS_LPC32XX_CONSOLE +static void wait_for_xmit_empty(struct uart_port *port) +{ + unsigned int timeout = 10000; + + do { + if (LPC32XX_HSU_TX_LEV(__raw_readl(LPC32XX_HSUART_LEVEL( + port->membase))) == 0) + break; + if (--timeout == 0) + break; + udelay(1); + } while (1); +} + +static void wait_for_xmit_ready(struct uart_port *port) +{ + unsigned int timeout = 10000; + + while (1) { + if (LPC32XX_HSU_TX_LEV(__raw_readl(LPC32XX_HSUART_LEVEL( + port->membase))) < 32) + break; + if (--timeout == 0) + break; + udelay(1); + } +} + +static void lpc32xx_hsuart_console_putchar(struct uart_port *port, int ch) +{ + wait_for_xmit_ready(port); + __raw_writel((u32) ch, LPC32XX_HSUART_FIFO(port->membase)); +} + +static void lpc32xx_hsuart_console_write(struct console *co, const char *s, + unsigned int count) { + struct lpc32xx_hsuart_port *up = &lpc32xx_hs_ports[co->index]; + unsigned long flags; + int locked = 1; + + touch_nmi_watchdog(); + local_irq_save(flags); + if (up->port.sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&up->port.lock); + else + spin_lock(&up->port.lock); + + uart_console_write(&up->port, s, count, + lpc32xx_hsuart_console_putchar); + wait_for_xmit_empty(&up->port); + + if (locked) + spin_unlock(&up->port.lock); + local_irq_restore(flags); +} + +static int __init lpc32xx_hsuart_console_setup(struct console *co, + char *options) { + struct uart_port *port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index >= MAX_PORTS) + co->index = 0; + + port = &lpc32xx_hs_ports[co->index].port; + if (!port->membase) + return -ENODEV; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver lpc32xx_hsuart_reg; +static struct console lpc32xx_hsuart_console = { + .name = LPC32XX_TTY_NAME, + .write = lpc32xx_hsuart_console_write, + .device = uart_console_device, + .setup = lpc32xx_hsuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &lpc32xx_hsuart_reg, +}; + +static int __init lpc32xx_hsuart_console_init(void) +{ + register_console(&lpc32xx_hsuart_console); + return 0; +} +console_initcall(lpc32xx_hsuart_console_init); + +#define LPC32XX_HSUART_CONSOLE (&lpc32xx_hsuart_console) +#else +#define LPC32XX_HSUART_CONSOLE NULL +#endif + +static struct uart_driver lpc32xx_hs_reg = { + .owner = THIS_MODULE, + .driver_name = MODNAME, + .dev_name = LPC32XX_TTY_NAME, + .major = LPC32XX_TTY_MAJOR, + .minor = LPC32XX_TTY_MINOR_START, + .nr = MAX_PORTS, + .cons = LPC32XX_HSUART_CONSOLE, +}; +static int uarts_registered; + +static unsigned int __serial_get_clock_div(unsigned long uartclk, + unsigned long rate) { + u32 div, goodrate, hsu_rate, l_hsu_rate, comprate; + u32 rate_diff; + + /* Find the closest divider to get the desired clock rate */ + div = uartclk / rate; + goodrate = hsu_rate = (div / 14) - 1; + if (hsu_rate != 0) + hsu_rate--; + + /* Tweak divider */ + l_hsu_rate = hsu_rate + 3; + rate_diff = 0xFFFFFFFF; + + while (hsu_rate < l_hsu_rate) { + comprate = uartclk / ((hsu_rate + 1) * 14); + if (abs(comprate - rate) < rate_diff) { + goodrate = hsu_rate; + rate_diff = abs(comprate - rate); + } + + hsu_rate++; + } + if (hsu_rate > 0xFF) + hsu_rate = 0xFF; + + return goodrate; +} + +static void __serial_uart_flush(struct uart_port *port) +{ + u32 tmp; + int cnt = 0; + + while ((__raw_readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) && + (cnt++ < FIFO_READ_LIMIT)) + tmp = __raw_readl(LPC32XX_HSUART_FIFO(port->membase)); +} + +static void __serial_lpc32xx_rx(struct uart_port *port) +{ + struct tty_struct *tty = port->state->port.tty; + unsigned int tmp, flag; + + /* Read data from FIFO and push into terminal */ + tmp = __raw_readl(LPC32XX_HSUART_FIFO(port->membase)); + while (!(tmp & LPC32XX_HSU_RX_EMPTY)) { + flag = TTY_NORMAL; + port->icount.rx++; + + if (tmp & LPC32XX_HSU_ERROR_DATA) { + /* Framing error */ + __raw_writel(LPC32XX_HSU_FE_INT, + LPC32XX_HSUART_IIR(port->membase)); + port->icount.frame++; + flag = TTY_FRAME; + tty_insert_flip_char(port->state->port.tty, 0, + TTY_FRAME); + tty_schedule_flip(port->state->port.tty); + } + + tty_insert_flip_char(port->state->port.tty, (tmp & 0xFF), + flag); + + tmp = __raw_readl(LPC32XX_HSUART_FIFO(port->membase)); + } + + tty_flip_buffer_push(tty); +} + +static void __serial_lpc32xx_tx(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + unsigned int tmp; + + if (port->x_char) { + __raw_writel((u32) port->x_char, + LPC32XX_HSUART_FIFO(port->membase)); + port->icount.tx++; + port->x_char = 0; + return; + } + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) + goto exit_tx; + + /* Transfer data */ + while (LPC32XX_HSU_TX_LEV(__raw_readl( + LPC32XX_HSUART_LEVEL(port->membase))) < 64) { + __raw_writel((u32) xmit->buf[xmit->tail], + LPC32XX_HSUART_FIFO(port->membase)); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + if (uart_circ_empty(xmit)) + break; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + +exit_tx: + if (uart_circ_empty(xmit)) { + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + tmp &= ~LPC32XX_HSU_TX_INT_EN; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + } +} + +static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + u32 status; + + spin_lock(&port->lock); + + /* Read UART status and clear latched interrupts */ + status = __raw_readl(LPC32XX_HSUART_IIR(port->membase)); + + if (status & LPC32XX_HSU_BRK_INT) { + /* Break received */ + __raw_writel(LPC32XX_HSU_BRK_INT, + LPC32XX_HSUART_IIR(port->membase)); + port->icount.brk++; + uart_handle_break(port); + } + + /* Framing error */ + if (status & LPC32XX_HSU_FE_INT) + __raw_writel(LPC32XX_HSU_FE_INT, + LPC32XX_HSUART_IIR(port->membase)); + + if (status & LPC32XX_HSU_RX_OE_INT) { + /* Receive FIFO overrun */ + __raw_writel(LPC32XX_HSU_RX_OE_INT, + LPC32XX_HSUART_IIR(port->membase)); + port->icount.overrun++; + tty_insert_flip_char(port->state->port.tty, 0, TTY_OVERRUN); + tty_schedule_flip(port->state->port.tty); + } + + /* Data received? */ + if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) + __serial_lpc32xx_rx(port); + + /* Transmit data request? */ + if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) { + __raw_writel(LPC32XX_HSU_TX_INT, + LPC32XX_HSUART_IIR(port->membase)); + __serial_lpc32xx_tx(port); + } + + spin_unlock(&port->lock); + + return IRQ_HANDLED; +} + +static unsigned int serial_lpc32xx_tx_empty(struct uart_port *port) +{ + unsigned int ret = 0; + + if (LPC32XX_HSU_TX_LEV(__raw_readl( + LPC32XX_HSUART_LEVEL(port->membase))) == 0) + ret = TIOCSER_TEMT; + + return ret; +} + +static void serial_lpc32xx_set_mctrl(struct uart_port *port, + unsigned int mctrl) { + /* No signals are supported on HS UARTs */ +} + +static unsigned int serial_lpc32xx_get_mctrl(struct uart_port *port) +{ + /* No signals are supported on HS UARTs */ + return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; +} + +static void serial_lpc32xx_stop_tx(struct uart_port *port) +{ + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&port->lock, flags); + + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + tmp &= ~LPC32XX_HSU_TX_INT_EN; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void serial_lpc32xx_start_tx(struct uart_port *port) +{ + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&port->lock, flags); + + __serial_lpc32xx_tx(port); + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + tmp |= LPC32XX_HSU_TX_INT_EN; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void serial_lpc32xx_stop_rx(struct uart_port *port) +{ + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&port->lock, flags); + + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + __raw_writel((LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT | + LPC32XX_HSU_FE_INT), LPC32XX_HSUART_IIR(port->membase)); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void serial_lpc32xx_enable_ms(struct uart_port *port) +{ + /* Modem status is not supported */ +} + +static void serial_lpc32xx_break_ctl(struct uart_port *port, + int break_state) { + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&port->lock, flags); + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + if (break_state != 0) + tmp |= LPC32XX_HSU_BREAK; + else + tmp &= ~LPC32XX_HSU_BREAK; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + spin_unlock_irqrestore(&port->lock, flags); +} + +static int serial_lpc32xx_startup(struct uart_port *port) +{ + int retval; + u32 tmp; + + __serial_uart_flush(port); + + __raw_writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | + LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), + LPC32XX_HSUART_IIR(port->membase)); + + __raw_writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); + + /* + * Set receiver timeout, HSU offset of 20, no break, no interrupts, + * and default FIFO trigger levels + */ + tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | + LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + retval = request_irq(port->irq, serial_lpc32xx_interrupt, + 0, MODNAME, port); + if (retval) + return retval; + + __raw_writel((tmp | LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN), + LPC32XX_HSUART_CTRL(port->membase)); + + return 0; +} + +static void serial_lpc32xx_shutdown(struct uart_port *port) +{ + u32 tmp; + + tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | + LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + free_irq(port->irq, port); +} + +static void serial_lpc32xx_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + unsigned long flags; + unsigned int baud, quot; + u32 tmp; + + /* Always 8-bit, no parity, 1 stop bit */ + termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); + termios->c_cflag |= CS8; + + termios->c_cflag &= ~(HUPCL | CMSPAR | CLOCAL | CRTSCTS); + + baud = uart_get_baud_rate(port, termios, old, 0, + (port->uartclk / 14)); + quot = __serial_get_clock_div(port->uartclk, baud); + + spin_lock_irqsave(&port->lock, flags); + + /* Ignore characters? */ + tmp = __raw_readl(LPC32XX_HSUART_CTRL(port->membase)); + if ((termios->c_cflag & CREAD) == 0) + tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); + else + tmp |= LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN; + __raw_writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); + + __raw_writel(quot, LPC32XX_HSUART_RATE(port->membase)); + + uart_update_timeout(port, termios->c_cflag, baud); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *serial_lpc32xx_type(struct uart_port *port) +{ + return MODNAME; +} + +static void serial_lpc32xx_release_port(struct uart_port *port) +{ + if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { + if (port->flags & UPF_IOREMAP) { + iounmap(port->membase); + port->membase = NULL; + } + + release_mem_region(port->mapbase, SZ_4K); + } +} + +static int serial_lpc32xx_request_port(struct uart_port *port) +{ + int ret = -ENODEV; + + if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { + ret = 0; + + if (!request_mem_region(port->mapbase, SZ_4K, MODNAME)) + ret = -EBUSY; + else if (port->flags & UPF_IOREMAP) { + port->membase = ioremap(port->mapbase, SZ_4K); + if (!port->membase) { + release_mem_region(port->mapbase, SZ_4K); + ret = -ENOMEM; + } + } + } + + return ret; +} + +static void serial_lpc32xx_config_port(struct uart_port *port, int uflags) +{ + int ret; + + ret = serial_lpc32xx_request_port(port); + if (ret < 0) + return; + port->type = PORT_UART00; + port->fifosize = 64; + + __serial_uart_flush(port); + + __raw_writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | + LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), + LPC32XX_HSUART_IIR(port->membase)); + + __raw_writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); + + /* Set receiver timeout, HSU offset of 20, no break, no interrupts, + and default FIFO trigger levels */ + __raw_writel(LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | + LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B, + LPC32XX_HSUART_CTRL(port->membase)); +} + +static int serial_lpc32xx_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + int ret = 0; + + if (ser->type != PORT_UART00) + ret = -EINVAL; + + return ret; +} + +static struct uart_ops serial_lpc32xx_pops = { + .tx_empty = serial_lpc32xx_tx_empty, + .set_mctrl = serial_lpc32xx_set_mctrl, + .get_mctrl = serial_lpc32xx_get_mctrl, + .stop_tx = serial_lpc32xx_stop_tx, + .start_tx = serial_lpc32xx_start_tx, + .stop_rx = serial_lpc32xx_stop_rx, + .enable_ms = serial_lpc32xx_enable_ms, + .break_ctl = serial_lpc32xx_break_ctl, + .startup = serial_lpc32xx_startup, + .shutdown = serial_lpc32xx_shutdown, + .set_termios = serial_lpc32xx_set_termios, + .type = serial_lpc32xx_type, + .release_port = serial_lpc32xx_release_port, + .request_port = serial_lpc32xx_request_port, + .config_port = serial_lpc32xx_config_port, + .verify_port = serial_lpc32xx_verify_port, +}; + +/* + * Register a set of serial devices attached to a platform device + */ +static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev) +{ + struct uart_port *p = pdev->dev.platform_data; + struct lpc32xx_hsuart_port *pdr; + int i, ret = 0; + + uarts_registered = 0; + for (i = 0; p && (p->flags != 0); i++) { + pdr = &lpc32xx_hs_ports[i]; + memset(pdr, 0, sizeof(struct lpc32xx_hsuart_port)); + + pdr->port.iotype = p->iotype; + pdr->port.membase = p->membase; + pdr->port.mapbase = p->mapbase; + pdr->port.irq = p->irq; + pdr->port.uartclk = p->uartclk; + pdr->port.regshift = p->regshift; + pdr->port.flags = p->flags | UPF_FIXED_PORT; + pdr->port.dev = &pdev->dev; + pdr->port.ops = &serial_lpc32xx_pops; + pdr->port.line = p->line; + spin_lock_init(&pdr->port.lock); + + uart_add_one_port(&lpc32xx_hs_reg, &pdr->port); + p++; + uarts_registered++; + } + + return ret; +} + +/* + * Remove serial ports registered against a platform device. + */ +static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev) +{ + struct lpc32xx_hsuart_port *p; + int i; + + for (i = 0; i < uarts_registered; i++) { + p = &lpc32xx_hs_ports[i]; + + if (p->port.dev == &pdev->dev) + uart_remove_one_port(&lpc32xx_hs_reg, &p->port); + } + + platform_set_drvdata(pdev, NULL); + + return 0; +} + + +#if defined (CONFIG_PM) +static int serial_hs_lpc32xx_suspend(struct platform_device *dev, pm_message_t state) +{ + int i; + + for (i = 0; i < uarts_registered; i++) { + struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[i]; + + if (p->port.type != PORT_UNKNOWN && p->port.dev == &dev->dev) + uart_suspend_port(&lpc32xx_hs_reg, &p->port); + } + + return 0; +} + +static int serial_hs_lpc32xx_resume(struct platform_device *dev) +{ + int i; + + for (i = 0; i < uarts_registered; i++) { + struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[i]; + + if (p->port.type != PORT_UNKNOWN && p->port.dev == &dev->dev) + uart_resume_port(&lpc32xx_hs_reg, &p->port); + } + + return 0; +} +#else +#define serial_hs_lpc32xx_suspend NULL +#define serial_hs_lpc32xx_resume NULL +#endif + +static struct platform_driver serial_hs_lpc32xx_driver = { + .probe = serial_hs_lpc32xx_probe, + .remove = __devexit_p(serial_hs_lpc32xx_remove), + .suspend = serial_hs_lpc32xx_suspend, + .resume = serial_hs_lpc32xx_resume, + .driver = { + .name = MODNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init lpc32xx_hsuart_init(void) +{ + int ret; + + ret = uart_register_driver(&lpc32xx_hs_reg); + if (ret == 0) { + ret = platform_driver_register(&serial_hs_lpc32xx_driver); + if (ret) + uart_unregister_driver(&lpc32xx_hs_reg); + } + + return ret; +} + +static void __exit lpc32xx_hsuart_exit(void) +{ + platform_driver_unregister(&serial_hs_lpc32xx_driver); + uart_unregister_driver(&lpc32xx_hs_reg); +} + +module_init(lpc32xx_hsuart_init); +module_exit(lpc32xx_hsuart_exit); + +MODULE_AUTHOR("Kevin Wells (kevin.wells@nxp.com)"); +MODULE_DESCRIPTION("NXP LPC32XX High speed UART driver"); +MODULE_LICENSE("GPL"); diff -purN linux-2.6.34/drivers/serial/Makefile linux-2.6.34-dev/drivers/serial/Makefile --- linux-2.6.34/drivers/serial/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/serial/Makefile 2010-10-15 14:10:00.128530188 +0100 @@ -53,6 +53,7 @@ obj-$(CONFIG_SERIAL_68328) += 68328seria obj-$(CONFIG_SERIAL_68360) += 68360serial.o obj-$(CONFIG_SERIAL_MCF) += mcf.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o +obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_ZS) += zs.o diff -purN linux-2.6.34/drivers/usb/gadget/gadget_chips.h linux-2.6.34-dev/drivers/usb/gadget/gadget_chips.h --- linux-2.6.34/drivers/usb/gadget/gadget_chips.h 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/gadget/gadget_chips.h 2010-10-15 14:10:00.128530188 +0100 @@ -142,6 +142,11 @@ #define gadget_is_s3c_hsotg(g) 0 #endif +#ifdef CONFIG_USB_GADGET_LPC32XX +#define gadget_is_lpc32xx(g) !strcmp("lpc32xx_udc", (g)->name) +#else +#define gadget_is_lpc32xx(g) 0 +#endif /** * usb_gadget_controller_number - support bcdDevice id convention @@ -200,6 +205,8 @@ static inline int usb_gadget_controller_ return 0x25; else if (gadget_is_s3c_hsotg(gadget)) return 0x26; + else if (gadget_is_lpc32xx(gadget)) + return 0x27; return -ENOENT; } diff -purN linux-2.6.34/drivers/usb/gadget/Kconfig linux-2.6.34-dev/drivers/usb/gadget/Kconfig --- linux-2.6.34/drivers/usb/gadget/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/gadget/Kconfig 2010-10-15 14:10:00.128530188 +0100 @@ -140,6 +140,16 @@ config USB_AT91 depends on USB_GADGET_AT91 default USB_GADGET +config USB_GADGET_LPC32XX + boolean "LPC32XX USB Device Port" + depends on ARCH_LPC32XX + +config USB_LPC32XX + tristate + depends on USB_GADGET_LPC32XX + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_ATMEL_USBA boolean "Atmel USBA" select USB_GADGET_DUALSPEED diff -purN linux-2.6.34/drivers/usb/gadget/lpc32xx_udc.c linux-2.6.34-dev/drivers/usb/gadget/lpc32xx_udc.c --- linux-2.6.34/drivers/usb/gadget/lpc32xx_udc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/gadget/lpc32xx_udc.c 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,3259 @@ +/* + * drivers/usb/gadget/lpc32xx_udc.c + * + * Author: Kevin Wells + * + * Copyright (C) 2009 NXP Semiconductors + * Copyright (C) 2006 Mike James , Philips Semiconductors + * + * Note: This driver is based on original work done by Mike James for + * the LPC3180. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Notes + * + * ISO functionality is untested. It probably works, but may not be reliable. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "lpc32xx_udc.h" +#ifdef CONFIG_USB_GADGET_DEBUG_FILES +#include +#endif + +#define UDCA_BUFF_SIZE (128) + +#define USB_CTRL IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64) +#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | DEV_CLOCK_ON | I2C_CLOCK_ON) + +/* USB_CTRL bit defines */ +#define USB_SLAVE_HCLK_EN (1 << 24) +#define USB_HOST_NEED_CLK_EN (1 << 21) +#define USB_DEV_NEED_CLK_EN (1 << 22) + +#define USB_OTG_CLK_CTRL IO_ADDRESS(LPC32XX_USB_BASE + 0xFF4) +#define USB_OTG_CLK_STAT IO_ADDRESS(LPC32XX_USB_BASE + 0xFF8) + +/* USB_OTG_CLK_CTRL bit defines */ +#define AHB_M_CLOCK_ON (1 << 4) +#define OTG_CLOCK_ON (1 << 3) +#define I2C_CLOCK_ON (1 << 2) +#define DEV_CLOCK_ON (1 << 1) +#define HOST_CLOCK_ON (1 << 0) + +#define USB_OTG_STAT_CONTROL IO_ADDRESS(LPC32XX_USB_BASE + 0x110) + +/* USB_OTG_STAT_CONTROL bit defines */ +#define TRANSPARENT_I2C_EN (1 << 7) +#define HOST_EN (1 << 0) + +/* ISP1301 USB transceiver I2C registers */ +#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ + +#define MC1_SPEED_REG (1 << 0) +#define MC1_SUSPEND_REG (1 << 1) +#define MC1_DAT_SE0 (1 << 2) +#define MC1_TRANSPARENT (1 << 3) +#define MC1_BDIS_ACON_EN (1 << 4) +#define MC1_OE_INT_EN (1 << 5) +#define MC1_UART_EN (1 << 6) +#define MC1_MASK 0x7f + +#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ + +#define MC2_GLOBAL_PWR_DN (1 << 0) +#define MC2_SPD_SUSP_CTRL (1 << 1) +#define MC2_BI_DI (1 << 2) +#define MC2_TRANSP_BDIR0 (1 << 3) +#define MC2_TRANSP_BDIR1 (1 << 4) +#define MC2_AUDIO_EN (1 << 5) +#define MC2_PSW_EN (1 << 6) +#define MC2_EN2V7 (1 << 7) + +#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ +#define OTG1_DP_PULLUP (1 << 0) +#define OTG1_DM_PULLUP (1 << 1) +#define OTG1_DP_PULLDOWN (1 << 2) +#define OTG1_DM_PULLDOWN (1 << 3) +#define OTG1_ID_PULLDOWN (1 << 4) +#define OTG1_VBUS_DRV (1 << 5) +#define OTG1_VBUS_DISCHRG (1 << 6) +#define OTG1_VBUS_CHRG (1 << 7) +#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ +#define OTG_B_SESS_END (1 << 6) +#define OTG_B_SESS_VLD (1 << 7) + +#define INT_CR_INT (1 << 7) +#define INT_BDIS_ACON (1 << 6) +#define INT_ID_FLOAT (1 << 5) +#define INT_DM_HI (1 << 4) +#define INT_ID_GND (1 << 3) +#define INT_DP_HI (1 << 2) +#define INT_SESS_VLD (1 << 1) +#define INT_VBUS_VLD (1 << 0) + +#define ISP1301_I2C_ADDR 0x2C + +#define ISP1301_I2C_MODE_CONTROL_1 0x4 +#define ISP1301_I2C_MODE_CONTROL_2 0x12 +#define ISP1301_I2C_OTG_CONTROL_1 0x6 +#define ISP1301_I2C_OTG_CONTROL_2 0x10 +#define ISP1301_I2C_INTERRUPT_SOURCE 0x8 +#define ISP1301_I2C_INTERRUPT_LATCH 0xA +#define ISP1301_I2C_INTERRUPT_FALLING 0xC +#define ISP1301_I2C_INTERRUPT_RISING 0xE +#define ISP1301_I2C_REG_CLEAR_ADDR 1 + +#define DRIVER_VERSION "$Revision: 1.01 $" +static const char driver_name [] = "lpc32xx_udc"; + +static void udc_set_address(struct lpc32xx_udc *udc, u32 addr); +#if defined(UDC_ENABLE_DMA) +static int udc_ep_in_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep); +static int udc_ep_out_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep); +#else +static int udc_ep_in_req(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep); +static int udc_ep_out_req(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep); +#endif +static int udc_ep0_in_req(struct lpc32xx_udc *udc); +static int udc_ep0_out_req(struct lpc32xx_udc *udc); + +/* + * + * proc interface support + * + */ +#ifdef CONFIG_USB_GADGET_DEBUG_FILES +static char *epnames[] = {"INT", "ISO", "BULK", "CTRL"}; +static const char debug_filename[] = "driver/udc"; + +static void proc_ep_show(struct seq_file *s, struct lpc32xx_ep *ep) +{ + struct lpc32xx_request *req; + unsigned long flags; + + local_irq_save(flags); + + seq_printf(s, "\n"); + seq_printf(s, "%12s, maxpacket %4d %3s", + ep->ep.name, ep->ep.maxpacket, + ep->is_in ? "in" : "out"); + seq_printf(s, " type %4s", epnames[ep->eptype]); + seq_printf(s, " ints: %12d", ep->totalints); + seq_printf(s, " stalls: %12d", ep->totalstalls); + seq_printf(s, " NAKs: %12d\n", ep->totalnaks); + + if (list_empty (&ep->queue)) + seq_printf(s, "\t(queue empty)\n"); + else { + list_for_each_entry (req, &ep->queue, queue) { + u32 length = req->req.actual; + + seq_printf(s, "\treq %p len %d/%d buf %p\n", + &req->req, length, + req->req.length, req->req.buf); + } + } + + local_irq_restore(flags); +} + +static int proc_udc_show(struct seq_file *s, void *unused) +{ + struct lpc32xx_udc *udc = s->private; + struct lpc32xx_ep *ep; + + seq_printf(s, "%s: version %s\n", driver_name, DRIVER_VERSION); + + seq_printf(s, "vbus %s, pullup %s, %s powered%s, gadget %s\n\n", + udc->vbus ? "present" : "off", + udc->enabled + ? (udc->vbus ? "active" : "enabled") + : "disabled", + udc->selfpowered ? "self" : "VBUS", + udc->suspended ? ", suspended" : "", + udc->driver ? udc->driver->driver.name : "(none)"); + + if (udc->enabled && udc->vbus) { + proc_ep_show(s, &udc->ep[0]); + list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { + if (ep->desc) { + proc_ep_show(s, ep); + } + } + } + + return 0; +} + +static int proc_udc_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_udc_show, PDE(inode)->data); +} + +static const struct file_operations proc_ops = { + .owner = THIS_MODULE, + .open = proc_udc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void create_debug_file(struct lpc32xx_udc *udc) +{ + udc->pde = proc_create_data(debug_filename, 0, NULL, &proc_ops, udc); +} + +static void remove_debug_file(struct lpc32xx_udc *udc) +{ + if (udc->pde) + remove_proc_entry(debug_filename, NULL); +} + +#else +static inline void create_debug_file(struct lpc32xx_udc *udc) {} +static inline void remove_debug_file(struct lpc32xx_udc *udc) {} +#endif + +/* + * + * ISP1301 transceiver support functions + * + */ +struct i2c_driver isp1301_driver; +struct i2c_client *isp1301_i2c_client; +static int isp1301_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id); +static int isp1301_remove(struct i2c_client *client); + +static const unsigned short normal_i2c[] = +{ ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; + +static const struct i2c_device_id isp1301_id[] = { + { "isp1301_pnx", 0 }, + { } +}; + +struct i2c_driver isp1301_driver = { + .driver = { + .name = "isp1301_pnx", + }, + .probe = isp1301_probe, + .remove = isp1301_remove, + .id_table = isp1301_id, +}; + +static int isp1301_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) +{ + return 0; +} + +static int isp1301_remove(struct i2c_client *client) +{ + return 0; +} + +static void i2c_write(u8 buf, u8 subaddr) +{ + char tmpbuf[2]; + + tmpbuf[0] = subaddr; /*register number */ + tmpbuf[1] = buf; /*register data */ + i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2); +} + +static u16 i2c_read(u8 subaddr) +{ + u8 data; + + i2c_master_send(isp1301_i2c_client, &subaddr, 1); + i2c_master_recv(isp1301_i2c_client, (u8 *) &data, 1); + + return data; +} + +static u16 i2c_read16(u8 subaddr) +{ + u16 data; + + i2c_master_send(isp1301_i2c_client, &subaddr, 1); + i2c_master_recv(isp1301_i2c_client, (u8 *) &data, 2); + + return data; +} + +/* Primary initializion sequence for the ISP1301 transceiver */ +static void isp1301_udc_configure(struct lpc32xx_udc *udc) +{ + /* LPC32XX only supports DAT_SE0 USB mode */ + /* This sequence is important */ + + /* Disable transparent UART mode first */ + i2c_write(MC1_UART_EN, (ISP1301_I2C_MODE_CONTROL_1 | + ISP1301_I2C_REG_CLEAR_ADDR)); + + /* Set full speed and SE0 mode */ + i2c_write(~0, (ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write((MC1_SPEED_REG | MC1_DAT_SE0), ISP1301_I2C_MODE_CONTROL_1); + + /* The PSW_OE enable bit state is reversed in the ISP1301 User's guide! */ + i2c_write(~0, (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write((MC2_BI_DI | MC2_SPD_SUSP_CTRL), ISP1301_I2C_MODE_CONTROL_2); + + /* Driver VBUS_DRV high or low depending on board setup */ + if (udc->board->vbus_drv_pol != 0) { + i2c_write(OTG1_VBUS_DRV, ISP1301_I2C_OTG_CONTROL_1); + } + else { + i2c_write(OTG1_VBUS_DRV, (ISP1301_I2C_OTG_CONTROL_1 | + ISP1301_I2C_REG_CLEAR_ADDR)); + } + + /* Bi-derctional mode with suspend control */ + /* Enable both pulldowns for now - the pullup will be enable when VBUS is detected */ + i2c_write(~0, (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write((0 | OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN), + ISP1301_I2C_OTG_CONTROL_1); + + /* Discharge VBUS (just in case) */ + i2c_write(OTG1_VBUS_DISCHRG, ISP1301_I2C_OTG_CONTROL_1); + mdelay(1); + i2c_write(OTG1_VBUS_DISCHRG, + (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + + /* Clear and enable VBUS high edge interrupt */ + i2c_write(~0, ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR); + i2c_write(~0, ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); + i2c_write(INT_VBUS_VLD, ISP1301_I2C_INTERRUPT_FALLING); + i2c_write(~0, ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); + i2c_write(INT_VBUS_VLD, ISP1301_I2C_INTERRUPT_RISING); + + /* Enable usb_need_clk clock after transceiver is initialized */ + __raw_writel((__raw_readl(USB_CTRL) | (1 << 22)), USB_CTRL); + + dev_dbg(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", i2c_read16(0x00)); + dev_dbg(udc->dev, "ISP1301 Product ID : 0x%04x\n", i2c_read16(0x02)); + dev_dbg(udc->dev, "ISP1301 Version ID : 0x%04x\n", i2c_read16(0x14)); +} + +/* Enables or disables the USB device pullup via the ISP1301 transceiver */ +static void isp1301_pullup_enable(int en_pullup) +{ + if (en_pullup) { + /* Enable pullup for bus signalling */ + i2c_write(OTG1_DP_PULLUP, ISP1301_I2C_OTG_CONTROL_1); + } + else { + /* Enable pullup for bus signalling */ + i2c_write(OTG1_DP_PULLUP, + (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + } +} + +#ifdef CONFIG_PM +/* Powers up or down the ISP1301 transceiver */ +static void isp1301_set_powerstate(int enable) { + if (enable != 0) { + /* Power up ISP1301 - this ISP1301 will automatically wakeup + when VBUS is detected */ + i2c_write(MC2_GLOBAL_PWR_DN, + (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR)); + } + else { + /* Power down ISP1301 */ + i2c_write(MC2_GLOBAL_PWR_DN, ISP1301_I2C_MODE_CONTROL_2); + } +} +#endif + +/* + * + * USB protocol engine command/data read/write helper functions + * + */ +/* Issues a single command to the USB device state machine */ +static void udc_protocol_cmd_w(struct lpc32xx_udc *udc, u32 cmd) { + u32 pass = 0; + int to; + + /* EP may lock on CLRI if this read isn't done */ + volatile u32 tmp = __raw_readl(USBD_DEVINTST(udc->udp_baseaddr)); + (void) tmp; + + while (pass == 0) { + __raw_writel(USBD_CCEMPTY, USBD_DEVINTCLR(udc->udp_baseaddr)); + + /* Write command code */ + __raw_writel(cmd, USBD_CMDCODE(udc->udp_baseaddr)); + to = 10000; + while (((__raw_readl(USBD_DEVINTST(udc->udp_baseaddr)) & + USBD_CCEMPTY) == 0) && (to > 0)) { + to--; + } + + if (to > 0) pass = 1; + } +} + +/* Issues 2 commands (or command and data) to the USB device state machine */ +static inline void udc_protocol_cmd_data_w(struct lpc32xx_udc *udc, u32 cmd, u32 data) { + udc_protocol_cmd_w(udc, cmd); + udc_protocol_cmd_w(udc, data); +} + +/* Issues a single command to the USB device state machine and reads + response data */ +static u32 udc_protocol_cmd_r(struct lpc32xx_udc *udc, u32 cmd) { + /* Write a command and read data from the protocol engine */ + u32 tmp; + + __raw_writel((USBD_CDFULL | USBD_CCEMPTY), + USBD_DEVINTCLR(udc->udp_baseaddr)); + + /* Write command code */ + udc_protocol_cmd_w(udc, cmd); + while ((__raw_readl(USBD_DEVINTST(udc->udp_baseaddr)) & + USBD_CDFULL) == 0); + + tmp = __raw_readl(USBD_CMDDATA(udc->udp_baseaddr)); + + return tmp; +} + +/* + * + * USB device interrupt mask support functions + * + */ +/* Enable one or more USB device interrupts */ +static inline void uda_enable_devint(struct lpc32xx_udc *udc, u32 devmask) { + udc->enabled_devints |= devmask; + __raw_writel(udc->enabled_devints, USBD_DEVINTEN(udc->udp_baseaddr)); +} + +/* Disable one or more USB device interrupts */ +static inline void uda_disable_devint(struct lpc32xx_udc *udc, u32 mask) { + udc->enabled_devints &= ~mask; + __raw_writel(udc->enabled_devints, USBD_DEVINTEN(udc->udp_baseaddr)); +} + +/* Clear one or more USB device interrupts */ +static inline void uda_clear_devint(struct lpc32xx_udc *udc, u32 mask) { + __raw_writel(mask, USBD_DEVINTCLR(udc->udp_baseaddr)); +} + +/* + * + * Endpoint interrupt disable/enable functions + * + */ +/* Enable one or more USB endpoint interrupts */ +static void uda_enable_hwepint(struct lpc32xx_udc *udc, u32 hwep) { + udc->enabled_hwepints |= (1 << hwep); + __raw_writel(udc->enabled_hwepints, USBD_EPINTEN(udc->udp_baseaddr)); +} + +/* Disable one or more USB endpoint interrupts */ +static void uda_disable_hwepint(struct lpc32xx_udc *udc, u32 hwep) { + udc->enabled_hwepints &= ~(1 << hwep); + __raw_writel(udc->enabled_hwepints, USBD_EPINTEN(udc->udp_baseaddr)); +} + +/* Clear one or more USB endpoint interrupts */ +static inline void uda_clear_hwepint(struct lpc32xx_udc *udc, u32 hwep) { + __raw_writel((1 << hwep), USBD_EPINTCLR(udc->udp_baseaddr)); +} + +/* Enable DMA for the HW channel */ +static inline void udc_ep_dma_enable(struct lpc32xx_udc *udc, u32 hwep) { + __raw_writel((1 << hwep), USBD_EPDMAEN(udc->udp_baseaddr)); +} + +/* Disable DMA for the HW channel */ +static inline void udc_ep_dma_disable(struct lpc32xx_udc *udc, u32 hwep) { + __raw_writel((1 << hwep), USBD_EPDMADIS(udc->udp_baseaddr)); +} + +/* + * + * Endpoint realize/unrealize functions + * + */ +/* Before an endpoint can be used, it needs to be realized + in the USB protocol engine - this realizes the endpoint. + The interrupt (FIFO or DMA) is not enabled with this function */ +static void udc_realize_hwep(struct lpc32xx_udc *udc, u32 hwep, + u32 maxpacket) { + __raw_writel(USBD_EP_RLZED, USBD_DEVINTCLR(udc->udp_baseaddr)); + __raw_writel(hwep, USBD_EPIND(udc->udp_baseaddr)); + udc->realized_eps |= (1 << hwep); + __raw_writel(udc->realized_eps, USBD_REEP(udc->udp_baseaddr)); + __raw_writel(maxpacket, USBD_EPMAXPSIZE(udc->udp_baseaddr)); + + /* Wait until endpoint is realized in hardware */ + while (!(__raw_readl(USBD_DEVINTST(udc->udp_baseaddr)) & USBD_EP_RLZED)); + __raw_writel(USBD_EP_RLZED, USBD_DEVINTCLR(udc->udp_baseaddr)); +} + +/* Unrealize an EP */ +static void udc_unrealize_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc->realized_eps &= ~(1 << hwep); + __raw_writel(udc->realized_eps, USBD_REEP(udc->udp_baseaddr)); +} + +/* + * + * Endpoint support functions + * + */ +/* Select and clear endpoint interrupt */ +static u32 udc_selep_clrint(struct lpc32xx_udc *udc, u32 hwep) { + udc_protocol_cmd_w(udc, CMD_SEL_EP_CLRI(hwep)); + return udc_protocol_cmd_r(udc, DAT_SEL_EP_CLRI(hwep)); +} + +/* Disables the endpoint in the USB protocol engine */ +static void udc_disable_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep), + DAT_WR_BYTE(EP_STAT_DA)); +} + +/* Stalls the endpoint - endpoint will return STALL */ +static void udc_stall_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep), + DAT_WR_BYTE(EP_STAT_ST)); +} + +/* Clear stall or reset endpoint */ +static void udc_clrstall_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep), + DAT_WR_BYTE(0)); +} + +/* Select an endpoint for endpoint status, clear, validate */ +static void udc_select_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_protocol_cmd_w(udc, CMD_SEL_EP(hwep)); +} + +/* + * + * Endpoint buffer management functions + * + */ +/* Clear the current endpoint's buffer */ +static void udc_clr_buffer_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_select_hwep(udc, hwep); + udc_protocol_cmd_w(udc, CMD_CLR_BUF); +} + +/* Validate the current endpoint's buffer */ +static void udc_val_buffer_hwep(struct lpc32xx_udc *udc, u32 hwep) { + udc_select_hwep(udc, hwep); + udc_protocol_cmd_w(udc, CMD_VALID_BUF); +} + +static inline u32 udc_clearep_getsts(struct lpc32xx_udc *udc, u32 hwep) { + /* Clear EP interrupt */ + uda_clear_hwepint(udc, hwep); + return udc_selep_clrint(udc, hwep); +} + +#if defined(UDC_ENABLE_DMA) +/* + * + * USB EP DMA support + * + */ +/* Allocate a DMA Descriptor */ +static struct lpc32xx_usbd_dd_gad *udc_dd_alloc(struct lpc32xx_udc *udc) { + dma_addr_t dma; + struct lpc32xx_usbd_dd_gad *dd; + + dd = (struct lpc32xx_usbd_dd_gad *) dma_pool_alloc( + udc->dd_cache, (GFP_KERNEL | GFP_DMA), &dma); + if (dd) { + dd->this_dma = dma; + } + + return dd; +} + +/* Free a DMA Descriptor */ +static void udc_dd_free(struct lpc32xx_udc *udc, struct lpc32xx_usbd_dd_gad *dd) +{ + dma_pool_free(udc->dd_cache, dd, dd->this_dma); +} +#endif + +/* + * + * USB setup and shutdown functions + * + */ +/* Enables or disables most of the USB system clocks when low power mode is + needed. Clocks are typically started on a connection event, and disabled + when a cable is disconnected */ +#define OTGOFF_CLK_MASK (AHB_M_CLOCK_ON | I2C_CLOCK_ON) +static void udc_clk_set(struct lpc32xx_udc *udc, int enable) +{ + if (enable != 0) { + if (udc->clocked) + return; + + udc->clocked = 1; + + /* 48MHz PLL up */ + clk_enable(udc->usb_pll_clk); + + /* Enable the USb device clock */ + __raw_writel(__raw_readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, USB_CTRL); + + /* Set to enable all needed USB OTG clocks */ + __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); + + while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != + USB_CLOCK_MASK); + } + else { + if (!udc->clocked) + return; + + udc->clocked = 0; + udc->gadget.speed = USB_SPEED_UNKNOWN; + + /* Never disable the USB_HCLK during normal operation */ + + /* 48MHz PLL dpwn */ + clk_disable(udc->usb_pll_clk); + + /* Enable the USb device clock */ + __raw_writel(__raw_readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN, USB_CTRL); + + /* Set to enable all needed USB OTG clocks */ + __raw_writel(OTGOFF_CLK_MASK, USB_OTG_CLK_CTRL); + + while ((__raw_readl(USB_OTG_CLK_STAT) & OTGOFF_CLK_MASK) != + OTGOFF_CLK_MASK); + } +} + +static void udc_disable(struct lpc32xx_udc *udc) { + u32 i; + + /* Disable device */ + udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(0)); + udc_protocol_cmd_data_w(udc, CMD_SET_DEV_STAT, DAT_WR_BYTE(0)); + + /* Disable all device interrupts (including EP0) */ + uda_disable_devint(udc, 0x3FF); + + /* Disable and reset all endpoint interrupts */ + for (i = 0; i < 32; i++) { + uda_disable_hwepint(udc, i); + uda_clear_hwepint(udc, i); + udc_disable_hwep(udc, i); + udc_unrealize_hwep(udc, i); + udc->udca_v_base [i] = 0; + + /* Disable and clear all interrupts and DMA */ + udc_ep_dma_disable(udc, i); + __raw_writel((1 << i), USBD_EOTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << i), USBD_NDDRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << i), USBD_SYSERRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << i), USBD_DMARCLR(udc->udp_baseaddr)); + } + + /* Disable DMA interrupts */ + __raw_writel(0, USBD_DMAINTEN(udc->udp_baseaddr)); + + __raw_writel(0, USBD_UDCAH(udc->udp_baseaddr)); +} + +static void udc_enable(struct lpc32xx_udc *udc) +{ + u32 i; + struct lpc32xx_ep *ep = &udc->ep[0]; + + udc->gadget.speed = USB_SPEED_UNKNOWN; + + /* Start with known state */ + udc_disable(udc); + + /* Enable device */ + udc_protocol_cmd_data_w(udc, CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); + + /* EP interrupts on high priority, FRAME interrupt on low priority */ + __raw_writel(USBD_EP_FAST, USBD_DEVINTPRI(udc->udp_baseaddr)); + __raw_writel(0xFFFF, USBD_EPINTPRI(udc->udp_baseaddr)); + + /* Clear any pending device interrupts */ + __raw_writel(0x3FF, USBD_DEVINTCLR(udc->udp_baseaddr)); + + /* Setup UDCA - not yet used (DMA) */ + __raw_writel((u32) udc->udca_p_base, USBD_UDCAH(udc->udp_baseaddr)); + + /* Only enable EP0 in and out for now, EP0 only works in FIFO mode */ + for (i = 0; i <= 1; i++) { + udc_realize_hwep(udc, i, ep->ep.maxpacket); + uda_enable_hwepint(udc, i); + udc_select_hwep(udc, i); + udc_clrstall_hwep(udc, i); + udc_clr_buffer_hwep(udc, i); + } + + /* Device interrupt setup */ + uda_clear_devint(udc, (USBD_ERR_INT | USBD_DEV_STAT | USBD_EP_SLOW | + USBD_EP_FAST)); + uda_enable_devint(udc, (USBD_ERR_INT | USBD_DEV_STAT | USBD_EP_SLOW | + USBD_EP_FAST)); + + /* Set device address to 0 - called twice to force a latch in the USB + engine without the need of a setup packet status closure */ + udc_set_address(udc, 0); + udc_set_address(udc, 0); + +#if defined(UDC_ENABLE_DMA) + /* Enable master DMA interrupts */ + __raw_writel((USBD_SYS_ERR_INT | USBD_EOT_INT), USBD_DMAINTEN(udc->udp_baseaddr)); +#endif + + udc->dev_status = 0; +} + +/* + * + * USB device board specific events handled via callbacks + * + */ +/* Connection change event - notify board function of change */ +static void uda_power_event(struct lpc32xx_udc *udc, u32 conn) { + /* Just notify of a connection change event (optional) */ + if (udc->board->conn_chgb != NULL) { + udc->board->conn_chgb(conn); + } +} + +/* Suspend/resume event - notify board function of change */ +static void uda_resm_susp_event(struct lpc32xx_udc *udc, u32 conn) { + /* Just notify of a Suspend/resume change event (optional) */ + if (udc->board->susp_chgb != NULL) { + udc->board->susp_chgb(conn); + } + + if (conn) + udc->suspended = 0; + else + udc->suspended = 1; +} + +/* Remote wakeup enable/disable - notify board function of change */ +static void uda_remwkp_cgh(struct lpc32xx_udc *udc) { + if (udc->board->rmwk_chgb != NULL) { + udc->board->rmwk_chgb(udc->dev_status & + (1 << USB_DEVICE_REMOTE_WAKEUP)); + } +} + +/* Reads data from FIFO, adjusts for alignment and data size */ +static void udc_pop_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes) { + int n, i, bl; + u16 *p16; + u32 *p32, tmp, cbytes; + + /* Use optimal data transfer method based on source address and size */ + switch (((u32) data) & 0x3) { + case 0: /* 32-bit aligned */ + p32 = (u32 *) data; + cbytes = (bytes & ~0x3); + + /* Copy 32-bit aligned data first */ + for (n = 0; n < cbytes; n += 4) + *p32++ = __raw_readl(USBD_RXDATA(udc->udp_baseaddr)); + + /* Handle any remaining bytes */ + bl = bytes - cbytes; + if (bl) { + tmp = __raw_readl(USBD_RXDATA(udc->udp_baseaddr)); + for (n = 0; n < bl; n++) + data[cbytes + n] = ((tmp >> (n * 8)) & 0xFF); + + } + break; + + case 1: /* 8-bit aligned */ + case 3: + /* Each byte has to be handled independently */ + for (n = 0; n < bytes; n += 4) { + tmp = __raw_readl(USBD_RXDATA(udc->udp_baseaddr)); + + bl = bytes - n; + if (bl > 3) + bl = 3; + + for (i = 0; i < bl; i++) + data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF); + } + break; + + case 2: /* 16-bit aligned */ + p16 = (u16 *) data; + cbytes = (bytes & ~0x3); + + /* Copy 32-bit sized objects first with 16-bit alignment */ + for (n = 0; n < cbytes; n += 4) { + tmp = __raw_readl(USBD_RXDATA(udc->udp_baseaddr)); + *p16++ = (u16) (tmp & 0xFFFF); + *p16++ = (u16) ((tmp >> 16) & 0xFFFF); + } + + /* Handle any remaining bytes */ + bl = bytes - cbytes; + if (bl) { + tmp = __raw_readl(USBD_RXDATA(udc->udp_baseaddr)); + for (n = 0; n < bl; n++) + data[cbytes + n] = ((tmp >> (n * 8)) & 0xFF); + } + break; + } +} + +/* Read data from the FIFO for an endpoint. This function is for endpoints (such + as EP0) that don't use DMA. This function should only be called if a packet + is known to be ready to read for the endpopint. Note that the endpoint must + be selected in the protocol engine prior to this call. */ +static u32 udc_read_hwep(struct lpc32xx_udc *udc, u32 hwep, u32 *data, + int bytes) { + volatile u32 tmpv; + u32 tmp, hwrep = ((hwep & 0x1E) << 1) | CTRL_RD_EN; + + /* Setup read of endpoint */ + __raw_writel(hwrep, USBD_CTRL(udc->udp_baseaddr)); + __raw_writel(hwrep, USBD_CTRL(udc->udp_baseaddr)); + + while (__raw_readl(USBD_CTRL(udc->udp_baseaddr)) != hwrep) { + __raw_writel(hwrep, USBD_CTRL(udc->udp_baseaddr)); + } + + /* Wait until packet is ready */ + tmpv = 0; + while ((tmpv & PKT_RDY) == 0) { + tmpv = __raw_readl(USBD_RXPLEN(udc->udp_baseaddr)); + } + + /* Mask out count */ + tmp = tmpv & PKT_LNGTH_MASK; + if (bytes < tmp) { + tmp = (u32) bytes; + } + + if ((tmp > 0) && (data != NULL)) { + udc_pop_fifo(udc, (u8 *) data, tmp); + } + + __raw_writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr)); + __raw_writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr)); + + /* Clear the buffer */ + udc_clr_buffer_hwep(udc, hwep); + + return tmp; +} + +/* Stuffs data into the FIFO, adjusts for alignment and data size */ +static void udc_stuff_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes) { + int n, i, bl; + u16 *p16; + u32 *p32, tmp, cbytes; + + /* Use optimal data transfer method based on source address and size */ + switch (((u32) data) & 0x3) { + case 0: /* 32-bit aligned */ + p32 = (u32 *) data; + cbytes = (bytes & ~0x3); + + /* Copy 32-bit aligned data first */ + for (n = 0; n < cbytes; n += 4) + __raw_writel(*p32++, USBD_TXDATA(udc->udp_baseaddr)); + + /* Handle any remaining bytes */ + bl = bytes - cbytes; + if (bl) { + tmp = 0; + for (n = 0; n < bl; n++) + tmp |= (u32) (data[cbytes + n] << (n * 8)); + + __raw_writel(tmp, USBD_TXDATA(udc->udp_baseaddr)); + } + break; + + case 1: /* 8-bit aligned */ + case 3: + /* Each byte has to be handled independently */ + for (n = 0; n < bytes; n += 4) { + bl = bytes - n; + if (bl > 4) + bl = 4; + + tmp = 0; + for (i = 0; i < bl; i++) + tmp |= (u32) (data[n + i] << (i * 8)); + + __raw_writel(tmp, USBD_TXDATA(udc->udp_baseaddr)); + } + break; + + case 2: /* 16-bit aligned */ + p16 = (u16 *) data; + cbytes = (bytes & ~0x3); + + /* Copy 32-bit aligned data first */ + for (n = 0; n < cbytes; n += 4) { + tmp = (u32) (*p16++ & 0xFFFF); + tmp |= (u32) ((*p16++ & 0xFFFF) << 16); + __raw_writel(tmp, USBD_TXDATA(udc->udp_baseaddr)); + } + + /* Handle any remaining bytes */ + bl = bytes - cbytes; + if (bl) { + tmp = 0; + for (n = 0; n < bl; n++) + tmp |= (u32) (data[cbytes + n] << (n * 8)); + + __raw_writel(tmp, USBD_TXDATA(udc->udp_baseaddr)); + } + break; + } +} + +/* Write data to the FIFO for an endpoint. This function is for endpoints (such + as EP0) that don't use DMA. Note that the endpoint must be selected in the + protocol engine prior to this call. */ +static void udc_write_hwep(struct lpc32xx_udc *udc, u32 hwep, + u32 *data, u32 bytes) { + u32 hwwep = ((hwep & 0x1E) << 1) | CTRL_WR_EN; + + if ((bytes > 0) && (data == NULL)) { + return; + } + + /* Setup write of endpoint */ + __raw_writel(hwwep, USBD_CTRL(udc->udp_baseaddr)); + __raw_writel(hwwep, USBD_CTRL(udc->udp_baseaddr)); + while (__raw_readl(USBD_CTRL(udc->udp_baseaddr)) != hwwep) { + __raw_writel(hwwep, USBD_CTRL(udc->udp_baseaddr)); + } + + __raw_writel(bytes, USBD_TXPLEN(udc->udp_baseaddr)); + + /* Need at least 1 byte to rgigger TX, may not be needed */ + if (bytes == 0) { + __raw_writel(0, USBD_TXDATA(udc->udp_baseaddr)); + } + else { + udc_stuff_fifo(udc, (u8 *) data, bytes); + } + + __raw_writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr)); + __raw_writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr)); + + udc_val_buffer_hwep(udc, hwep); +} + +/* + * + * USB protocol high level support functions + * + */ +/* Set/reset USB device address */ +static void udc_set_address(struct lpc32xx_udc *udc, u32 addr) { + /* Address will be latched at the end of the status phase, or + latched immediately if function is called twice */ + udc_protocol_cmd_data_w(udc, CMD_SET_ADDR, + DAT_WR_BYTE(DEV_EN | addr)); +} + +/* USB device reset - resets USB to a default state with just EP0 + enabled */ +static void uda_usb_reset(struct lpc32xx_udc *udc) { + u32 i = 0; + /* Re-init device controller and EP0 */ + udc_enable(udc); + udc->gadget.speed = USB_SPEED_FULL; + + for (i = 1; i < NUM_ENDPOINTS; i++) { + struct lpc32xx_ep *ep = &udc->ep[i]; + ep->req_pending = 0; + } +} + +/* Send a ZLP on EP0 */ +static void udc_ep0_send_zlp(struct lpc32xx_udc *udc) { + udc_write_hwep(udc, EP_IN, NULL, 0); +} + +/* Get current frame number */ +static u16 udc_get_current_frame(struct lpc32xx_udc *udc) { + u16 flo, fhi; + + udc_protocol_cmd_w(udc, CMD_RD_FRAME); + flo = (u16) udc_protocol_cmd_r(udc, DAT_RD_FRAME); + fhi = (u16) udc_protocol_cmd_r(udc, DAT_RD_FRAME); + + return (fhi << 8) | flo; +} + +/* Set the device as configured - enables all endpoints */ +static inline void udc_set_device_configured(struct lpc32xx_udc *udc) { + udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(CONF_DVICE)); +} + +/* Set the device as unconfigured - disables all endpoints */ +static inline void udc_set_device_unconfigured(struct lpc32xx_udc *udc) { + udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(0)); +} + +/* reinit == restore inital software state */ +static void udc_reinit(struct lpc32xx_udc *udc) +{ + u32 i; + + INIT_LIST_HEAD(&udc->gadget.ep_list); + INIT_LIST_HEAD(&udc->gadget.ep0->ep_list); + + for (i = 0; i < NUM_ENDPOINTS; i++) { + struct lpc32xx_ep *ep = &udc->ep[i]; + + if (i != 0) { + list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); + } + ep->desc = NULL; + ep->ep.maxpacket = ep->maxpacket; + INIT_LIST_HEAD(&ep->queue); + ep->req_pending = 0; + } + + udc->ep0state = WAIT_FOR_SETUP; +} + +static void done(struct lpc32xx_ep *ep, struct lpc32xx_request *req, int status) +{ + struct lpc32xx_udc *udc = ep->udc; + + list_del_init(&req->queue); + if (req->req.status == -EINPROGRESS) { + req->req.status = status; + } + else { + status = req->req.status; + } + +#if defined(UDC_ENABLE_DMA) + if (ep->uses_dma) { + enum dma_data_direction direction; + + if (ep->is_in) + direction = DMA_TO_DEVICE; + else + direction = DMA_FROM_DEVICE; + + if (req->mapped) { + dma_unmap_single(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, direction); + req->req.dma = 0; + req->mapped = 0; + } + else { + dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, direction); + } + + /* Free DDs */ + udc_dd_free(udc, req->dd_desc_ptr); + } +#endif + + if (status && status != -ESHUTDOWN) { + ep_dbg(ep, "%s done %p, status %d\n", ep->ep.name, req, status); + } + + spin_unlock(&udc->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&udc->lock); +} + + +static void nuke(struct lpc32xx_ep *ep, int status) +{ + struct lpc32xx_request *req; + + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + done(ep, req, status); + } + + if (ep->desc) { + if (status == -ESHUTDOWN) { + uda_disable_hwepint(ep->udc, ep->hwep_num); + udc_disable_hwep(ep->udc, ep->hwep_num); + } + } +} + +static void stop_activity(struct lpc32xx_udc *udc) +{ + struct usb_gadget_driver *driver = udc->driver; + int i; + + if (udc->gadget.speed == USB_SPEED_UNKNOWN) + driver = NULL; + + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->suspended = 0; + + for (i = 0; i < NUM_ENDPOINTS; i++) { + struct lpc32xx_ep *ep = &udc->ep[i]; + nuke(ep, -ESHUTDOWN); + } + if (driver) { + driver->disconnect(&udc->gadget); + /* + * Wait for all the endpoints to disable, + * before disabling clocks. Don't wait if + * endpoints are not enabled. + */ + if(atomic_read(&udc->enabled_ep_cnt)) + wait_event_interruptible(udc->ep_disable_wait_queue, + (atomic_read(&udc->enabled_ep_cnt) == 0)); + } + + isp1301_pullup_enable(0); + udc_disable(udc); + udc_reinit(udc); +} + +/* + * Activate or kill host pullup + */ +static void pullup(struct lpc32xx_udc *udc, int is_on) +{ + if(!udc->clocked) + return; + + if (!udc->enabled || !udc->vbus) + is_on = 0; + + if (is_on) { + udc_clk_set(udc, 1); + isp1301_pullup_enable(1); + } else { + stop_activity(udc); + isp1301_pullup_enable(0); + udc_clk_set(udc, 0); + } +} + +static int lpc32xx_ep_disable (struct usb_ep * _ep) +{ + struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep); + struct lpc32xx_udc *udc = ep->udc; + unsigned long flags; + + if ((ep->hwep_num_base == 0) || (ep->hwep_num == 0)) { + return -EINVAL; + } + + local_irq_save(flags); + + nuke(ep, -ESHUTDOWN); + + /* restore the endpoint's pristine config */ + ep->desc = NULL; + + /* Clear all DMA statuses for this EP */ + udc_ep_dma_disable(udc, ep->hwep_num); + __raw_writel((1 << ep->hwep_num), USBD_EOTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_NDDRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_SYSERRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_DMARCLR(udc->udp_baseaddr)); + + /* Remove the DD pointer in the UDCA */ + udc->udca_v_base[ep->hwep_num] = 0; + ep->uses_dma = 0; + + /* Disable and reset endpoint and interrupt */ + uda_clear_hwepint(udc, ep->hwep_num); + udc_unrealize_hwep(udc, ep->hwep_num); + + ep->hwep_num = 0; + + local_irq_restore(flags); + + atomic_dec(&udc->enabled_ep_cnt); + wake_up(&udc->ep_disable_wait_queue); + + return 0; +} + +static int lpc32xx_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep); + struct lpc32xx_udc *udc = ep->udc; + u16 maxpacket; + u32 tmp; + unsigned long flags; + + /* Verify EP data */ + if ((!_ep) || (!ep) || (!desc) || (ep->desc) || + (desc->bDescriptorType != USB_DT_ENDPOINT) || + ((maxpacket = le16_to_cpu(desc->wMaxPacketSize)) == 0) || + (maxpacket > ep->maxpacket)) { + dev_dbg(udc->dev, "bad ep or descriptor\n"); + return -EINVAL; + } + + /* Don't touch EP0 */ + if (ep->hwep_num_base == 0) { + dev_dbg(udc->dev, "Can't re-enable EP0!!!\n"); + return -EINVAL; + } + + /* Is driver ready? */ + if ((!udc->driver) || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { + dev_dbg(udc->dev, "bogus device state\n"); + return -ESHUTDOWN; + } + + tmp = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + switch (tmp) { + case USB_ENDPOINT_XFER_CONTROL: + return -EINVAL; + + case USB_ENDPOINT_XFER_INT: + if (maxpacket > ep->maxpacket) { + dev_dbg(udc->dev, "Bad INT endpoint maxpacket %d\n", maxpacket); + return -EINVAL; + } + break; + + case USB_ENDPOINT_XFER_BULK: + switch (maxpacket) { + case 8: + case 16: + case 32: + case 64: + break; + + default: + dev_dbg(udc->dev, "Bad BULK endpoint maxpacket %d\n", maxpacket); + return -EINVAL; + } + break; + + case USB_ENDPOINT_XFER_ISOC: + break; + } + + local_irq_save(flags); + + /* Initialize endpoint to match the selected descriptor */ + ep->is_in = (desc->bEndpointAddress & USB_DIR_IN) != 0; + ep->desc = desc; + ep->ep.maxpacket = maxpacket; + + /* Map hardware endpoint from base and direction */ + if (ep->is_in) { + /* IN endpoints are offset 1 from the OUT endpoint */ + ep->hwep_num = ep->hwep_num_base + EP_IN; + } + else { + ep->hwep_num = ep->hwep_num_base; + } + + ep_dbg(ep, "EP enabled: %s, HW:%d, MP:%d IN:%d\n", ep->ep.name, ep->hwep_num, + maxpacket, (ep->is_in == 1)); + + /* Realize the endpoint, interrupt is enabled later when + buffers are queued, IN EPs will NAK until buffers are ready */ + udc_realize_hwep(udc, ep->hwep_num, ep->ep.maxpacket); + udc_clr_buffer_hwep(udc, ep->hwep_num); + uda_disable_hwepint(udc, ep->hwep_num); + udc_clrstall_hwep(udc, ep->hwep_num); + + /* Clear all DMA statuses for this EP */ + udc_ep_dma_disable(udc, ep->hwep_num); + __raw_writel((1 << ep->hwep_num), USBD_EOTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_NDDRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_SYSERRTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_DMARCLR(udc->udp_baseaddr)); + +#if defined(UDC_ENABLE_DMA) + ep->uses_dma = 1; +#endif + + local_irq_restore(flags); + + atomic_inc(&udc->enabled_ep_cnt); + return 0; +} + +/* Allocate a USB request list */ +static struct usb_request *lpc32xx_ep_alloc_request( + struct usb_ep *_ep, gfp_t gfp_flags) +{ + struct lpc32xx_request *req; + + req = kzalloc(sizeof (struct lpc32xx_request), gfp_flags); + if (!req) + return NULL; + + INIT_LIST_HEAD(&req->queue); + return &req->req; +} + +/* De-allocate a USB request list */ +static void lpc32xx_ep_free_request(struct usb_ep *_ep, + struct usb_request *_req) +{ + struct lpc32xx_request *req; + + req = container_of(_req, struct lpc32xx_request, req); + BUG_ON(!list_empty(&req->queue)); + kfree(req); +} + +static int lpc32xx_ep_queue(struct usb_ep *_ep, + struct usb_request *_req, gfp_t gfp_flags) +{ + struct lpc32xx_request *req; + struct lpc32xx_ep *ep; + struct lpc32xx_udc *udc; + unsigned long flags; + int status = 0; + + req = container_of(_req, struct lpc32xx_request, req); + ep = container_of(_ep, struct lpc32xx_ep, ep); + + if (!_req || !_req->complete || !_req->buf || !list_empty(&req->queue)) { + return -EINVAL; + } + + udc = ep->udc; + + if (!_ep || (!ep->desc && ep->hwep_num_base != 0)) { + dev_dbg(udc->dev, "invalid ep\n"); + return -EINVAL; + } + + + if ((!udc) || (!udc->driver) || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { + dev_dbg(udc->dev, "invalid device\n"); + return -EINVAL; + } + +#if defined(UDC_ENABLE_DMA) + if (ep->uses_dma) { + enum dma_data_direction direction; + struct lpc32xx_usbd_dd_gad *dd; + + /* Map DMA pointer */ + if (ep->is_in) + direction = DMA_TO_DEVICE; + else + direction = DMA_FROM_DEVICE; + + if (req->req.dma == 0) { + req->req.dma = dma_map_single( + ep->udc->gadget.dev.parent, + req->req.buf, req->req.length, direction); + req->mapped = 1; + } + else { + dma_sync_single_for_device( + ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, direction); + req->mapped = 0; + } + + /* For the request, build a list of DDs */ + dd = udc_dd_alloc(udc); + if (!dd) { + /* Error allocating DD */ + return -ENOMEM; + } + req->dd_desc_ptr = dd; + + /* Setup the DMA descriptor */ + dd->dd_next_phy = dd->dd_next_v = NULL; + dd->dd_buffer_addr = (u32) req->req.dma; + dd->dd_status = 0; + + /* Special handling for ISO EPs */ + if (ep->eptype == EP_ISO_TYPE) { + dd->dd_setup = DD_SETUP_ISO_EP | + DD_SETUP_PACKETLEN(ep->ep.maxpacket) | + DD_SETUP_DMALENBYTES(req->req.length); + dd->dd_iso_ps_mem_addr = (u32 *) ((u32) dd->this_dma + 20); + dd->iso_status[0] = req->req.length; + } + else { + dd->dd_setup = DD_SETUP_PACKETLEN(ep->ep.maxpacket) | + DD_SETUP_DMALENBYTES(req->req.length); + } + } +#endif + + ep_dbg(ep, "%s queue req %p len %d buf %p (in=%d) z=%d\n", _ep->name, _req, _req->length, + _req->buf, ep->is_in, _req->zero); + + spin_lock_irqsave(&udc->lock, flags); + + _req->status = -EINPROGRESS; + _req->actual = 0; + req->send_zlp = _req->zero; + + /* Kickstart empty queues */ + if (list_empty(&ep->queue)) { + list_add_tail(&req->queue, &ep->queue); + + if (ep->hwep_num_base == 0) { + /* Handle expected data direction */ + if (ep->is_in) { + /* IN packet to host */ + udc->ep0state = DATA_IN; + status = udc_ep0_in_req(udc); + } + else { + /* OUT packet from host */ + udc->ep0state = DATA_OUT; + status = udc_ep0_out_req(udc); + } + } + else if (ep->is_in) { + /* IN packet to host and kick off transfer */ + if (!ep->req_pending) { +#if defined(UDC_ENABLE_DMA) + udc_ep_in_req_dma(udc, ep); +#else + uda_enable_hwepint(udc, ep->hwep_num); + udc_ep_in_req(udc, ep); +#endif + } + } + else { + /* OUT packet from host and kick off list */ + if (!ep->req_pending) { +#if defined(UDC_ENABLE_DMA) + udc_ep_out_req_dma(udc, ep); +#else + uda_enable_hwepint(udc, ep->hwep_num); + udc_ep_out_req(udc, ep); +#endif + } + } + } + else + list_add_tail(&req->queue, &ep->queue); + + spin_unlock_irqrestore(&udc->lock, flags); + + return (status < 0) ? status : 0; +} + +static int lpc32xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct lpc32xx_ep *ep; + struct lpc32xx_request *req; + unsigned long flags; + + ep = container_of(_ep, struct lpc32xx_ep, ep); + if (!_ep || ep->hwep_num_base == 0) + return -EINVAL; + + spin_lock_irqsave(&ep->udc->lock, flags); + + /* make sure it's actually queued on this endpoint */ + list_for_each_entry (req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + if (&req->req != _req) { + spin_unlock_irqrestore(&ep->udc->lock, flags); + return -EINVAL; + } + + done(ep, req, -ECONNRESET); + spin_unlock_irqrestore(&ep->udc->lock, flags); + + return 0; +} + +static int lpc32xx_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep); + struct lpc32xx_udc *udc = ep->udc; + unsigned long flags; + + if ((!ep) || (ep->desc == NULL) || (ep->hwep_num <= 1)) + return -EINVAL; + + /* Don't halt an IN EP */ + if (ep->is_in) + return -EAGAIN; + + spin_lock_irqsave(&udc->lock, flags); + + if (value == 1) { + /* stall */ + udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(ep->hwep_num), + DAT_WR_BYTE(EP_STAT_ST)); + } + else { + /* End stall */ + udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(ep->hwep_num), + DAT_WR_BYTE(0)); + } + + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +static const struct usb_ep_ops lpc32xx_ep_ops = { + .enable = lpc32xx_ep_enable, + .disable = lpc32xx_ep_disable, + .alloc_request = lpc32xx_ep_alloc_request, + .free_request = lpc32xx_ep_free_request, + .queue = lpc32xx_ep_queue, + .dequeue = lpc32xx_ep_dequeue, + .set_halt = lpc32xx_ep_set_halt, +}; + +#if defined(UDC_ENABLE_DMA) +/* Setup up a IN request for DMA transfer - this consists of determining the + list of DMA addresses for the transfer, allocating DMA Descriptors, + installing the DD into the UDCA, and then enabling the DMA for that EP */ +static int udc_ep_in_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) +{ + struct lpc32xx_request *req; + u32 hwep = ep->hwep_num; + + ep->req_pending = 1; + + /* There will always be a request waiting here */ + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + + /* Place the DD Descriptor into the UDCA */ + udc->udca_v_base[hwep] = (u32) req->dd_desc_ptr->this_dma; + + /* Enable DMA and interrupt for the HW EP */ + udc_ep_dma_enable(udc, hwep); + + return 0; +} + +/* Setup up a OUT request for DMA transfer - this consists of determining the + list of DMA addresses for the transfer, allocating DMA Descriptors, + installing the DD into the UDCA, and then enabling the DMA for that EP */ +static int udc_ep_out_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) +{ + struct lpc32xx_request *req; + u32 hwep = ep->hwep_num; + + ep->req_pending = 1; + + /* There will always be a request waiting here */ + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + + /* Place the DD Descriptor into the UDCA */ + udc->udca_v_base[hwep] = (u32) req->dd_desc_ptr->this_dma; + + /* Enable DMA and interrupt for the HW EP */ + udc_ep_dma_enable(udc, hwep); + + return 0; +} + +/* Handle EP completion */ +void udc_handle_eps(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) { + u32 epstatus; + struct lpc32xx_request *req; + + uda_disable_hwepint(udc, ep->hwep_num); + + if (ep->hwep_num <= 0) + return; + + epstatus = udc_clearep_getsts(udc, ep->hwep_num); + + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + done(ep, req, 0); + + /* Start another request if ready */ + if(!list_empty(&ep->queue)) { + if (ep->is_in) { + udc_ep_in_req_dma(udc, ep); + } + else { + udc_ep_out_req_dma(udc, ep); + } + } + else + ep->req_pending = 0; +} + +/* Send a ZLP on a non-0 IN EP */ +void udc_send_in_zlp(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep, + struct lpc32xx_usbd_dd_gad *dd) { + /* Set up EP interrupt status */ + uda_enable_hwepint(udc, ep->hwep_num); + udc_clearep_getsts(udc, ep->hwep_num); + + /* Send ZLP */ + udc_write_hwep(udc, ep->hwep_num, NULL, 0); +} + +/* DMA end of transfer completion */ +static void udc_handle_dma_ep(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) { + u32 status; + struct lpc32xx_request *req; + struct lpc32xx_usbd_dd_gad *dd; + +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + ep->totalints++; +#endif + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + if (!req) { + ep_err(ep, "DMA interrupt on no req!\n"); + return; + } + dd = req->dd_desc_ptr; + + /* Wait for end of descriptor to retire */ + while (!(dd->dd_status & DD_STATUS_DD_RETIRED)); + + /* Disable DMA */ + udc_ep_dma_disable(udc, ep->hwep_num); + __raw_writel((1 << ep->hwep_num), USBD_EOTINTCLR(udc->udp_baseaddr)); + __raw_writel((1 << ep->hwep_num), USBD_NDDRTINTCLR(udc->udp_baseaddr)); + + /* System error? */ + if (__raw_readl(USBD_SYSERRTINTST(udc->udp_baseaddr)) & (1 << ep->hwep_num)) { + __raw_writel((1 << ep->hwep_num), USBD_SYSERRTINTCLR(udc->udp_baseaddr)); + ep_err(ep, "AHB critical error!\n"); + ep->req_pending = 0; + + /* The error could of occurred on a packet of a multipacket transfer, + so recovering the transfer is not possible. Close the request with + an error */ + done(ep, req, -ECONNABORTED); + + return; + } + + /* Handle the current DD's status */ + status = dd->dd_status; + switch (status & DD_STATUS_STS_MASK) { + case DD_STATUS_STS_NS: + /* DD not serviced? This shouldn't happen! */ + ep->req_pending = 0; + ep_err(ep, "DMA critical EP error: DD not serviced (0x%x)!\n", status); + done(ep, req, -ECONNABORTED); + return; + + case DD_STATUS_STS_BS: + /* Interrupt only fires on EOT - This shouldn't happen! */ + ep->req_pending = 0; + ep_err(ep, "DMA critical EP error: EOT prior to service completion (0x%x)!\n", status); + done(ep, req, -ECONNABORTED); + return; + + case DD_STATUS_STS_NC: + case DD_STATUS_STS_DUR: /* Really just a short packet, not an underrun */ + /* This is a good status and what we expect */ + break; + + default: + /* Data overrun, system error, or unknown */ + ep->req_pending = 0; + ep_err(ep, "DMA critical EP error: System error (0x%x)!\n", status); + done(ep, req, -ECONNABORTED); + return; + } + + /* Save transferred data size */ + req->req.actual += DD_STATUS_CURDMACNT(status); + + /* Work around the wierd underrun packet issue */ + if ((!ep->is_in) && (!(req->req.actual % ep->maxpacket)) && + ((req->req.length - req->req.actual) > 0)) { + ep_dbg(ep, "Short packet in unexpected situation!\n"); + + // WTF is this? An underrun packet on OUT with no ZLP! Hardware issue? */ + dd->dd_next_phy = dd->dd_next_v = NULL; + dd->dd_buffer_addr = (u32) req->req.dma; + dd->dd_buffer_addr += req->req.actual; + dd->dd_status = 0; + + /* Special handling for ISO EPs */ + dd->dd_setup = DD_SETUP_PACKETLEN(ep->ep.maxpacket) | + DD_SETUP_DMALENBYTES(req->req.length - req->req.actual); + + /* Do the remainder of the req */ + udc_ep_out_req_dma(udc, ep); + + return; + } + + /* ISO endpoints are handled differently */ + if (ep->eptype == EP_ISO_TYPE) { + if (!ep->is_in) + req->req.actual = dd->iso_status[0] & 0xFFFF; + } + + /* For an Bulk IN EP, the DMA engine will only send data as specified in the + descriptor. If the total transfer size is a multiple of the max packet + size, then the transfer was completed, but no ZLP was sent. The ZLP needs + to be sent using the FIFO mechanism to terminate this transfer */ + if (req->send_zlp) { + udc_send_in_zlp(udc, ep, dd); + + /* Just exit */ + return; + } + + /* Transfer request is complete */ + done(ep, req, 0); + + udc_clearep_getsts(udc, ep->hwep_num); + /* Start another request if ready */ + if(!list_empty((&ep->queue))) { + if (ep->is_in) { + udc_ep_in_req_dma(udc, ep); + } + else { + udc_ep_out_req_dma(udc, ep); + } + } + else + ep->req_pending = 0; +} + +#else +/* This function was called if a new request is ready to be placed into the SEND FIFO + for transfer to the host, or when a previous transfer to the host has completed. */ +static int udc_ep_in_req(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) { + struct lpc32xx_request *req; + u32 ts, epstatus, bufst; + int is_last; + + /* Select and clear EP interrupt */ + epstatus = udc_clearep_getsts(udc, ep->hwep_num); + + if (epstatus & EP_SEL_ST) { + /* EP is stalled */ + ep->totalstalls++; + return 0; + } + + if (epstatus & EP_SEL_EPN) { + /* NAK'd on other side */ + ep->totalnaks++; + } + + bufst = (epstatus & EP_SEL_F); + + /* Are any requests available? */ + if (list_empty(&ep->queue)) { + if (!bufst) { + /* No reqs and the hardware is idle, disable IRQ */ + uda_disable_hwepint(udc, ep->hwep_num); + } + + return 0; + } + + /* If both buffers are currently full, just exit for now */ + if (bufst) + return 0; + + /* A buffer is available in the hardware, so we can fill it */ + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + + /* Limit packet size to the size of the EP */ + ts = req->req.length - req->req.actual; + if (ts > ep->ep.maxpacket) + ts = ep->ep.maxpacket; + + /* Write data to the EP0 FIFO and start transfer */ + ep_dbg(ep, "SEND %s 0x%x(%d)\n", ep->ep.name, (u32)(req->req.buf + req->req.actual), ts); + udc_write_hwep(udc, ep->hwep_num, (req->req.buf + req->req.actual), ts); + + /* Increment data pointer */ + req->req.actual += ts; + + if (ts < ep->ep.maxpacket) + is_last = 1; + else if ((req->req.actual != req->req.length) || (req->send_zlp)) { + req->send_zlp = 0; + is_last = 0; + } + else + is_last = 1; + + if (is_last) { + /* Transfer request is complete */ + done(ep, req, 0); + return 1; + } + + /* Stay in data transfer state */ + return 0; +} + +static int udc_ep_out_req(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) { + struct lpc32xx_request *req; + u32 tr, bufferspace, epstatus; + + /* Clear EP interrupt */ + epstatus = udc_clearep_getsts(udc, ep->hwep_num); + + if (epstatus & EP_SEL_ST) { + /* EP is stalled */ + ep->totalstalls++; + } + + if (epstatus & EP_SEL_EPN) { + /* Sent NAK */ + ep->totalnaks++; + } + + /* Are any requests available? */ + if (list_empty(&ep->queue)) { + uda_disable_hwepint(udc, ep->hwep_num); + + return 0; + } + + if (epstatus & EP_SEL_F) { + req = list_entry(ep->queue.next, struct lpc32xx_request, queue); + if (req->req.length == 0) { + ep_dbg(ep, "%s OUT zero buffer length!\n", ep->ep.name); + return 0; + } + + /* Limit transfer size to size of endpoint */ + bufferspace = req->req.length - req->req.actual; + if (bufferspace > ep->ep.maxpacket) + bufferspace = ep->ep.maxpacket; + + /* Copy data to buffer from FIFO */ + prefetchw(req->req.buf + req->req.actual); + tr = udc_read_hwep(udc, ep->hwep_num, + (req->req.buf + req->req.actual), bufferspace); + + ep_dbg(ep, "RECV %s 0x%x(%d) %d %d\n", ep->ep.name, (u32)(req->req.buf + req->req.actual), tr, + req->req.actual, req->req.length); + req->req.actual += tr; + + if ((tr < ep->ep.maxpacket) || (req->req.actual == req->req.length)) { + /* This is the last packet */ + done(ep, req, 0); + + return 1; + } + } + + return 0; +} + +static void udc_handle_ep(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep) { + ep->totalints++; + + if (!ep->desc) { + uda_disable_hwepint(udc, ep->hwep_num); + return; + } + + /* Nice and easy */ + if (ep->is_in) { + /* Handle IN request */ + udc_ep_in_req(udc, ep); + } + else { + /* Handle OUT request */ + udc_ep_out_req(udc, ep); + } +} +#endif + +/* + * + * Endpoint 0 functions + * + * + * + */ +static void udc_handle_dev(struct lpc32xx_udc *udc) { + u32 tmp; + + udc_protocol_cmd_w(udc, CMD_GET_DEV_STAT); + tmp = udc_protocol_cmd_r(udc, DAT_GET_DEV_STAT); + + if (tmp & DEV_RST) { + uda_usb_reset(udc); + } + else if (tmp & DEV_CON_CH) { + uda_power_event(udc, (tmp & DEV_CON)); + } + else if (tmp & DEV_SUS_CH) { + if (tmp & DEV_SUS) { + if (udc->vbus == 0) { + stop_activity(udc); + } else if ((udc->gadget.speed != + USB_SPEED_UNKNOWN) && udc->driver && + udc->driver->suspend) { + udc->driver->suspend(&udc->gadget); + uda_resm_susp_event(udc, 1); + } + } + else { + if ((udc->gadget.speed != USB_SPEED_UNKNOWN) && + udc->driver && udc->driver->resume && + udc->vbus) { + udc->driver->resume(&udc->gadget); + uda_resm_susp_event(udc, 0); + } + } + } +} + +/* IN endpoint 0 transfer */ +static int udc_ep0_in_req(struct lpc32xx_udc *udc) { + struct lpc32xx_request *req; + struct lpc32xx_ep *ep0 = &udc->ep [0]; + u32 tsend, ts = 0; + + if (list_empty(&ep0->queue)) + { + /* Nothing to send */ + return 0; + } + else { + req = list_entry(ep0->queue.next, + struct lpc32xx_request, queue); + } + + tsend = ts = req->req.length - req->req.actual; + if (ts == 0) { + /* Send a ZLP */ + udc_ep0_send_zlp(udc); + done(ep0, req, 0); + return 1; + } + else if (ts > ep0->ep.maxpacket) { + /* Just send what we can */ + ts = ep0->ep.maxpacket; + } + + /* Write data to the EP0 FIFO and start transfer */ + udc_write_hwep(udc, EP_IN, (req->req.buf + req->req.actual), ts); + + /* Increment data pointer */ + req->req.actual += ts; + + if (tsend >= ep0->ep.maxpacket) { + /* Stay in data transfer state */ + return 0; + } + + /* Transfer request is complete */ + udc->ep0state = WAIT_FOR_SETUP; + done(ep0, req, 0); + return 1; +} + +/* OUT endpoint 0 transfer */ +static int udc_ep0_out_req(struct lpc32xx_udc *udc) { + struct lpc32xx_request *req; + struct lpc32xx_ep *ep0 = &udc->ep[0]; + u32 tr, bufferspace; + + if (list_empty(&ep0->queue)) { + return 0; + } + else { + req = list_entry(ep0->queue.next, struct lpc32xx_request, queue); + } + + if (req) { + if (req->req.length == 0) { + /* Just dequeue request */ + done(ep0, req, 0); + udc->ep0state = WAIT_FOR_SETUP; + return 1; + } + + /* Get data from FIFO */ + bufferspace = req->req.length - req->req.actual; + if (bufferspace > ep0->ep.maxpacket) { + bufferspace = ep0->ep.maxpacket; + } + + /* Copy data to buffer */ + prefetchw(req->req.buf + req->req.actual); + tr = udc_read_hwep(udc, EP_OUT, + (req->req.buf + req->req.actual), bufferspace); + req->req.actual += bufferspace; + + if (tr < ep0->ep.maxpacket) { + /* This is the last packet */ + done(ep0, req, 0); + udc->ep0state = WAIT_FOR_SETUP; + return 1; + } + } + + return 0; +} + +static int udc_get_status(struct lpc32xx_udc *udc, u16 reqtype, u16 wIndex) { + struct lpc32xx_ep *ep; + u32 ep0buff = 0, tmp; + + switch (reqtype) { + case USB_RECIP_INTERFACE: + /* Not supported */ + break; + + case USB_RECIP_DEVICE: + ep0buff = (udc->selfpowered << USB_DEVICE_SELF_POWERED); + if (udc->dev_status & (1 << USB_DEVICE_REMOTE_WAKEUP)) { + ep0buff |= (1 << USB_DEVICE_REMOTE_WAKEUP); + } + break; + + case USB_RECIP_ENDPOINT: + tmp = wIndex & USB_ENDPOINT_NUMBER_MASK; + ep = &udc->ep[tmp]; + if ((tmp == 0) || (tmp >= NUM_ENDPOINTS) || (tmp && !ep->desc)) { + return -EOPNOTSUPP; + } + + if (wIndex & USB_DIR_IN) { + if (!ep->is_in) { + /* Somethings wrong */ + return -EOPNOTSUPP; + } + } else if (ep->is_in) + /* Not an IN endpoint */ + return -EOPNOTSUPP; + + /* Get status of the endpoint */ + udc_protocol_cmd_w(udc, CMD_SEL_EP(ep->hwep_num)); + tmp = udc_protocol_cmd_r(udc, DAT_SEL_EP(ep->hwep_num)); + + if (tmp & EP_SEL_ST) { + ep0buff = (1 << USB_ENDPOINT_HALT); + } + else { + ep0buff = 0; + } + break; + + default: + break; + } + + /* Return data */ + udc_write_hwep(udc, EP_IN, &ep0buff, 2); + + return 0; +} + +static void udc_handle_ep0_setup(struct lpc32xx_udc *udc) { + struct lpc32xx_ep *ep, *ep0 = &udc->ep[0]; + struct usb_ctrlrequest ctrlpkt; + int i, bytes; + u16 wIndex, wValue, wLength, reqtype, req, tmp; + + /* Nuke previous transfers */ + nuke(ep0, -EPROTO); + + /* Get setup packet */ + bytes = udc_read_hwep(udc, EP_OUT, (u32 *) &ctrlpkt, 8); + if (bytes != 8) { + ep_dbg(ep0, "Incorrectly sized setup packet (s/b 8, is %d!\n", bytes); + return; + } + + /* Native endianness */ + wIndex = le16_to_cpu(ctrlpkt.wIndex); + wValue = le16_to_cpu(ctrlpkt.wValue); + wLength = le16_to_cpu(ctrlpkt.wLength); + reqtype = le16_to_cpu(ctrlpkt.bRequestType); + + /* Set direction of EP0 */ + if (likely(reqtype & USB_DIR_IN)) { + ep0->is_in = 1; + } else { + ep0->is_in = 0; + } + + /* Handle SETUP packet */ + req = le16_to_cpu(ctrlpkt.bRequest); + switch (req) { + case USB_REQ_CLEAR_FEATURE: + case USB_REQ_SET_FEATURE: + switch (reqtype) { + case (USB_TYPE_STANDARD | USB_RECIP_DEVICE): + if (wValue != USB_DEVICE_REMOTE_WAKEUP) { + /* Nothing else handled */ + goto stall; + } + + /* Tell board about event */ + if (req == USB_REQ_CLEAR_FEATURE) + udc->dev_status &= ~(1 << USB_DEVICE_REMOTE_WAKEUP); + else + udc->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP); + uda_remwkp_cgh(udc); + goto zlp_send; + + case (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): + tmp = wIndex & USB_ENDPOINT_NUMBER_MASK; + if ((wValue != USB_ENDPOINT_HALT) || (tmp >= NUM_ENDPOINTS)) + break; + + /* Find hardware endpoint from logical endpoint */ + ep = &udc->ep[tmp]; + tmp = ep->hwep_num; + if (tmp == 0) + break; + + if (req == USB_REQ_CLEAR_FEATURE) + udc_stall_hwep(udc, tmp); + else + udc_clrstall_hwep(udc, tmp); + + goto zlp_send; + + default: + break; + } + + + case USB_REQ_SET_ADDRESS: + if (reqtype == (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) { + udc_set_address(udc, wValue); + goto zlp_send; + } + break; + + case USB_REQ_GET_STATUS: + udc_get_status(udc, reqtype, wIndex); + return; + + default: + /* Let GadgetFs handle the descriptor instead */ + break; + } + + if (likely(udc->driver)) { + /* device-2-host (IN) or no data setup command, process immediately */ + spin_unlock(&udc->lock); + i = udc->driver->setup(&udc->gadget, &ctrlpkt); + spin_lock(&udc->lock); + if (req == USB_REQ_SET_CONFIGURATION) { + /* Configuration is set after endpoints are realized */ + if (wValue) { + /* Set configuration */ + udc_set_device_configured(udc); + + /* NAK EP interrupts do not need to be enabled for this + driver, but if you really want them for statistic + purposes, uncomment the following lines */ + udc_protocol_cmd_data_w(udc, CMD_SET_MODE, DAT_WR_BYTE(AP_CLK | +#if defined(UDC_ENABLE_DMA) + INAK_BI | INAK_II)); +#else + INAK_BO | INAK_BI | INAK_IO | INAK_II)); +#endif + } + else { + /* Clear configuration */ + udc_set_device_unconfigured(udc); + + /* Disable NAK interrupts */ + udc_protocol_cmd_data_w(udc, CMD_SET_MODE, DAT_WR_BYTE(AP_CLK)); + } + } + + if (i < 0) { + /* setup processing failed, force stall */ + dev_err(udc->dev, "req %02x.%02x protocol STALL; stat %d\n", + reqtype, req, i); + udc->ep0state = WAIT_FOR_SETUP; + goto stall; + } + } + + if (!ep0->is_in) { + /* ZLP IN packet on on data phase */ + udc_ep0_send_zlp(udc); + } + + return; + +stall: + udc_stall_hwep(udc, EP_IN); + return; + +zlp_send: + udc_ep0_send_zlp(udc); + return; +} + +/* IN endpoint 0 transfer */ +static void udc_handle_ep0_in(struct lpc32xx_udc *udc) { + struct lpc32xx_ep *ep0 = &udc->ep [0]; + u32 epstatus; + + /* Clear EP interrupt */ + epstatus = udc_clearep_getsts(udc, EP_IN); + +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + ep0->totalints++; +#endif + + /* Stalled? Clear stall and reset buffers */ + if (epstatus & EP_SEL_ST) { + udc_clrstall_hwep(udc, EP_IN); + nuke(ep0, -ECONNABORTED); + udc->ep0state = WAIT_FOR_SETUP; + return; + } + + /* Is a buffer available? */ + if (!(epstatus & EP_SEL_F)) { + /* Handle based on current state */ + if (udc->ep0state == DATA_IN) { + udc_ep0_in_req(udc); + } + else { + /* Unknown state for EP0 oe end of DATA IN phase */ + nuke(ep0, -ECONNABORTED); + udc->ep0state = WAIT_FOR_SETUP; + } + } +} + +/* OUT endpoint 0 transfer */ +static void udc_handle_ep0_out(struct lpc32xx_udc *udc) { + struct lpc32xx_ep *ep0 = &udc->ep[0]; + u32 epstatus; + + /* Clear EP interrupt */ + epstatus = udc_clearep_getsts(udc, EP_OUT); + +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + ep0->totalints++; +#endif + + /* Stalled? */ + if (epstatus & EP_SEL_ST) { + udc_clrstall_hwep(udc, EP_OUT); + nuke(ep0, -ECONNABORTED); + udc->ep0state = WAIT_FOR_SETUP; + return; + } + + /* A NAK may occur if a packet coudn't be received yet */ + if (epstatus & EP_SEL_EPN) { + return; + } + /* Setup packet incoming? */ + if (epstatus & EP_SEL_STP) { + nuke(ep0, 0); + udc->ep0state = WAIT_FOR_SETUP; + } + + /* Data available? */ + if (epstatus & EP_SEL_F) { + /* Handle based on current state */ + switch (udc->ep0state) { + case WAIT_FOR_SETUP: + udc_handle_ep0_setup(udc); + break; + + case DATA_OUT: + udc_ep0_out_req(udc); + break; + + default: + /* Unknown state for EP0 */ + nuke(ep0, -ECONNABORTED); + udc->ep0state = WAIT_FOR_SETUP; + } + } +} + +static int lpc32xx_get_frame(struct usb_gadget *gadget) +{ + struct lpc32xx_udc *udc = to_udc(gadget); + + if (!to_udc(gadget)->clocked) + return -EINVAL; + + return (int) udc_get_current_frame(udc); +} + +static int lpc32xx_wakeup(struct usb_gadget *gadget) +{ + return -ENOTSUPP; +} + +static int lpc32xx_set_selfpowered(struct usb_gadget *gadget, int is_on) +{ + struct lpc32xx_udc *udc = to_udc(gadget); + + /* Always self-powered */ + udc->selfpowered = (is_on != 0); + + return 0; + return -ENOTSUPP; +} + +/* vbus is here! turn everything on that's ready */ +static int lpc32xx_vbus_session(struct usb_gadget *gadget, int is_active) +{ + struct lpc32xx_udc *udc = to_udc(gadget); + + /* Doesn't need lock */ + if (udc->driver) + pullup(udc, is_active); + else + pullup(udc, 0); + + return 0; +} + +static int lpc32xx_pullup(struct usb_gadget *gadget, int is_on) +{ + struct lpc32xx_udc *udc = to_udc(gadget); + + /* Doesn't need lock */ + pullup(udc, is_on); + + return 0; +} + +static const struct usb_gadget_ops lpc32xx_udc_ops = { + .get_frame = lpc32xx_get_frame, + .wakeup = lpc32xx_wakeup, + .set_selfpowered = lpc32xx_set_selfpowered, + .vbus_session = lpc32xx_vbus_session, + .pullup = lpc32xx_pullup, +}; + +static void nop_release(struct device *dev) +{ + /* nothing to free */ +} + +static struct lpc32xx_udc controller = { + .gadget = { + .ops = &lpc32xx_udc_ops, + .ep0 = &controller.ep[0].ep, + .name = driver_name, + .dev = { + .init_name = "gadget", + .release = nop_release, + } + }, + .ep[0] = { + .ep = { + .name = "ep0", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 0, + .hwep_num = 0, /* Can be 0 or 1, has special handling */ + .lep = 0, + .eptype = EP_CTL_TYPE, + }, + .ep[1] = { + .ep = { + .name = "ep1-int", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 2, + .hwep_num = 0, /* 2 or 3, will be set later */ + .lep = 1, + .eptype = EP_INT_TYPE, + }, + .ep[2] = { + .ep = { + .name = "ep2-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 4, + .hwep_num = 0, /* 4 or 5, will be set later */ + .doublebuff = 1, + .lep = 2, + .eptype = EP_BLK_TYPE, + }, + .ep[3] = { + .ep = { + .name = "ep3-iso", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 1023, + .hwep_num_base = 6, + .hwep_num = 0, /* 6 or 7, will be set later */ + .doublebuff = 1, + .lep = 3, + .eptype = EP_ISO_TYPE, + }, + .ep[4] = { + .ep = { + .name = "ep4-int", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 8, + .hwep_num = 0, /* 8 or 9, will be set later */ + .lep = 4, + .eptype = EP_INT_TYPE, + }, + .ep[5] = { + .ep = { + .name = "ep5-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 10, + .hwep_num = 0, /* 10 or 11, will be set later */ + .doublebuff = 1, + .lep = 5, + .eptype = EP_BLK_TYPE, + }, + .ep[6] = { + .ep = { + .name = "ep6-iso", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 1023, + .hwep_num_base = 12, + .hwep_num = 0, /* 12 or 13, will be set later */ + .doublebuff = 1, + .lep = 6, + .eptype = EP_ISO_TYPE, + }, + .ep[7] = { + .ep = { + .name = "ep7-int", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 14, + .hwep_num = 0, + .lep = 7, + .eptype = EP_INT_TYPE, + }, + .ep[8] = { + .ep = { + .name = "ep8-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 16, + .hwep_num = 0, + .doublebuff = 1, + .lep = 8, + .eptype = EP_BLK_TYPE, + }, + .ep[9] = { + .ep = { + .name = "ep9-iso", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 1023, + .hwep_num_base = 18, + .hwep_num = 0, + .doublebuff = 1, + .lep = 9, + .eptype = EP_ISO_TYPE, + }, + .ep[10] = { + .ep = { + .name = "ep10-int", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 20, + .hwep_num = 0, + .lep = 10, + .eptype = EP_INT_TYPE, + }, + .ep[11] = { + .ep = { + .name = "ep11-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 22, + .hwep_num = 0, + .doublebuff = 1, + .lep = 11, + .eptype = EP_BLK_TYPE, + }, + .ep[12] = { + .ep = { + .name = "ep12-iso", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 1023, + .hwep_num_base = 24, + .hwep_num = 0, + .doublebuff = 1, + .lep = 12, + .eptype = EP_ISO_TYPE, + }, + .ep[13] = { + .ep = { + .name = "ep13-int", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 26, + .hwep_num = 0, + .lep = 13, + .eptype = EP_INT_TYPE, + }, + .ep[14] = { + .ep = { + .name = "ep14-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 64, + .hwep_num_base = 28, + .hwep_num = 0, + .doublebuff = 1, + .lep = 14, + .eptype = EP_BLK_TYPE, + }, + .ep[15] = { + .ep = { + .name = "ep15-bulk", + .ops = &lpc32xx_ep_ops, + }, + .udc = &controller, + .maxpacket = 1023, + .hwep_num_base = 30, + .hwep_num = 0, + .doublebuff = 1, + .lep = 15, + .eptype = EP_BLK_TYPE, + }, +}; + +/* ISO and status interrupts */ +static irqreturn_t lpc32xx_usb_lp_irq(int irq, void *_udc) { + u32 tmp, devstat; + struct lpc32xx_udc *udc = _udc; + + spin_lock(&udc->lock); + + /* Read the device status register */ + devstat = __raw_readl(USBD_DEVINTST(udc->udp_baseaddr)); + devstat &= ~USBD_EP_FAST; + __raw_writel(devstat, USBD_DEVINTCLR(udc->udp_baseaddr)); + devstat = devstat & udc->enabled_devints; + + /* Device specific handling needed? */ + if (devstat & USBD_DEV_STAT) { + udc_handle_dev(udc); + } + + /* Start of frame? */ + if (devstat & FRAME_INT) { + /* The frame interrupt isn't really needed for ISO support, + as the driver will queue the necessary packets */ + dev_dbg(udc->dev, "Device frame interrupt not supported\n"); + } + + /* Error? */ + if (devstat & ERR_INT) { + /* All types of errors, from cable removal during transfer to + misc protocol and bit errors. These are mostly for just info, + as the USB hardware will work around these */ + udc_protocol_cmd_w(udc, CMD_RD_ERR_STAT); + tmp = udc_protocol_cmd_r(udc, DAT_RD_ERR_STAT); + dev_err(udc->dev, "Device error (0x%x)!\n", tmp); + } + + spin_unlock(&udc->lock); + return IRQ_HANDLED; +} + +/* EP interrupts */ +static irqreturn_t lpc32xx_usb_hp_irq(int irq, void *_udc) +{ + u32 tmp; + struct lpc32xx_udc *udc = _udc; + + spin_lock(&udc->lock); + + /* Read the device status register */ + tmp = __raw_readl(USBD_DEVINTST(udc->udp_baseaddr)); + __raw_writel(USBD_EP_FAST, USBD_DEVINTCLR(udc->udp_baseaddr)); + + /* Endpoints */ + tmp = __raw_readl(USBD_EPINTST(udc->udp_baseaddr)); + + /* Special handling for EP0 */ + if (tmp & (EP_MASK_SEL(0, EP_OUT) | EP_MASK_SEL(0, EP_IN))) { + /* Handle EP0 IN */ + if (tmp & (EP_MASK_SEL(0, EP_IN))) + udc_handle_ep0_in(udc); + + /* Handle EP0 OUT */ + if (tmp & (EP_MASK_SEL(0, EP_OUT))) + udc_handle_ep0_out(udc); + } + + /* All other EPs */ + if (tmp & ~(EP_MASK_SEL(0, EP_OUT) | EP_MASK_SEL(0, EP_IN))) { + int i; + + /* Handle other EP interrupts */ + for (i = 1; i < NUM_ENDPOINTS; i++) { + if (tmp & (1 << udc->ep [i].hwep_num)) +#if defined(UDC_ENABLE_DMA) + udc_handle_eps(udc, &udc->ep[i]); +#else + udc_handle_ep(udc, &udc->ep[i]); +#endif + } + } + + spin_unlock(&udc->lock); + return IRQ_HANDLED; +} + +static irqreturn_t lpc32xx_usb_devdma_irq(int irq, void *_udc) +{ + struct lpc32xx_udc *udc = _udc; + +#if defined(UDC_ENABLE_DMA) + int i; + u32 tmp; + + spin_lock(&udc->lock); + + /* Handle EP DMA EOT interrupts */ + tmp = __raw_readl(USBD_EOTINTST(udc->udp_baseaddr)) | + __raw_readl(USBD_NDDRTINTST(udc->udp_baseaddr)) | + __raw_readl(USBD_SYSERRTINTST(udc->udp_baseaddr)); + for (i = 1; i < NUM_ENDPOINTS; i++) { + if (tmp & (1 << udc->ep [i].hwep_num)) + udc_handle_dma_ep(udc, &udc->ep[i]); + } + + spin_unlock(&udc->lock); +#endif + + return IRQ_HANDLED; +} + +/* + * + * VBUS detection, pullup handler, and Gadget cable state notification + * + */ +static int vbus_handler_thread(void *udc_) +{ + struct lpc32xx_udc *udc = udc_; + u8 value; + + /* The main loop */ + while (!kthread_should_stop()) { + if (udc->enabled != 0) { + /* Get the VBUS status from the transceiver */ + value = i2c_read(ISP1301_I2C_OTG_CONTROL_2); + + /* VBUS on or off? */ + if (value & OTG_B_SESS_VLD) { + udc->vbus = 1; + + /* Enable USB clocks */ + udc_clk_set(udc, 1); + + /* Setup the UDC and ep0 */ + udc_enable(udc); + } + else { + /* Will force disconnect */ + udc->vbus = 0; + } + + /* VBUS changed? */ + if (udc->last_vbus != udc->vbus) { + lpc32xx_vbus_session(&udc->gadget, udc->vbus); + udc->last_vbus = udc->vbus; + } + } + + /* sleep if nothing to send */ + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + + udc->thread_task = NULL; + + return 0; +} + +static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc) +{ + struct lpc32xx_udc *udc = _udc; + + /* Discharge VBUS real quick */ + i2c_write(OTG1_VBUS_DISCHRG, ISP1301_I2C_OTG_CONTROL_1); + + /* Give VBUS some time (100mS) to discharge */ + msleep(100); + + /* Disable VBUS discharge resistor */ + i2c_write(OTG1_VBUS_DISCHRG, + (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + + /* Clear interrupt */ + i2c_write(~0, ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR); + + /* Kick off the VBUS handler thread */ + udc->thread_wakeup_needed = 1; + wake_up_process(udc->thread_task); + + return IRQ_HANDLED; +} + +int usb_gadget_register_driver (struct usb_gadget_driver *driver) +{ + struct lpc32xx_udc *udc = &controller; + int retval; + + if (!driver || driver->speed < USB_SPEED_FULL || + !driver->bind || !driver->setup) { + dev_err(udc->dev, "bad parameter.\n"); + return -EINVAL; + } + + if (udc->driver) { + dev_err(udc->dev, "UDC already has a gadget driver\n"); + return -EBUSY; + } + + udc->driver = driver; + udc->gadget.dev.driver = &driver->driver; + udc->enabled = 1; + udc->selfpowered = 1; + udc->vbus = 0; + + retval = driver->bind(&udc->gadget); + if (retval) { + dev_err(udc->dev, "driver->bind() returned %d\n", retval); + udc->enabled = 0; + udc->selfpowered = 0; + udc->driver = NULL; + udc->gadget.dev.driver = NULL; + return retval; + } + + dev_dbg(udc->dev, "bound to %s\n", driver->driver.name); + + /* Force VBUS process once to check for cable insertion */ + udc->last_vbus = udc->vbus = 0; + wake_up_process(udc->thread_task); + enable_irq(udc->udp_irq[IRQ_USB_ATX]); + + return 0; +} +EXPORT_SYMBOL (usb_gadget_register_driver); + +int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) +{ + struct lpc32xx_udc *udc = &controller; + + if (!driver || driver != udc->driver || !driver->unbind) + return -EINVAL; + + disable_irq(udc->udp_irq[IRQ_USB_ATX]); + local_irq_disable(); + udc->enabled = 0; + pullup(udc, 0); + local_irq_enable(); + + driver->unbind(&udc->gadget); + udc->gadget.dev.driver = NULL; + udc->driver = NULL; + + dev_dbg(udc->dev, "unbound from %s\n", driver->driver.name); + return 0; +} +EXPORT_SYMBOL (usb_gadget_unregister_driver); + +/*-------------------------------------------------------------------------*/ + +static void lpc32xx_udc_shutdown(struct platform_device *dev) +{ + /* Force disconnect on reboot */ + struct lpc32xx_udc *udc = &controller; + + pullup(udc, 0); +} + +static int __init lpc32xx_udc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct lpc32xx_udc *udc = &controller; + int retval, i; + struct resource *res; + dma_addr_t dma_handle; + struct i2c_adapter *i2c_adap; + struct i2c_board_info i2c_info; + + /* init software state */ + udc->gadget.dev.parent = dev; + udc->pdev = pdev; + udc->dev = &pdev->dev; + udc->enabled = 0; + + if (!dev->platform_data) { + dev_err(udc->dev, "missing platform_data\n"); + return -ENODEV; + } + + udc->board = (struct lpc32xx_usbd_cfg *) dev->platform_data; + + /* + * Resources are mapped as follows: + * [0] = IORESOURCE_MEM, base address and size of USB space + * [1] = IORESOURCE_IRQ, USB device low priority interrupt number + * [2] = IORESOURCE_IRQ, USB device high priority interrupt number + * [3] = IORESOURCE_IRQ, USB device interrupt number + * [4] = IORESOURCE_IRQ, USB transciever interrupt number + */ + if (pdev->num_resources != 5) { + dev_err(udc->dev, "invalid num_resources\n"); + return -ENODEV; + } + + if (pdev->resource[0].flags != IORESOURCE_MEM) { + dev_err(udc->dev, "invalid resource type\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + spin_lock_init(&udc->lock); + + /* Get IRQs */ + for (i = 0; i < 4; i++) { + if (pdev->resource[i + 1].flags != IORESOURCE_IRQ) { + dev_err(udc->dev, "invalid resource type\n"); + return -ENODEV; + } + udc->udp_irq[i] = platform_get_irq(pdev, i); + } + + udc->io_p_start = res->start; + udc->io_p_size = res->end - res->start + 1; + if (!request_mem_region(udc->io_p_start, udc->io_p_size, driver_name)) { + dev_err(udc->dev, "someone's using UDC memory\n"); + return -EBUSY; + } + + /* Enable AHB slave USB clock, needed for further USB clock control */ + __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL); + + /* Get required clocks */ + udc->usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); + if (IS_ERR(udc->usb_pll_clk)) { + dev_err(udc->dev, "failed to acquire USB PLL"); + retval = PTR_ERR(udc->usb_pll_clk); + goto pll_get_fail; + } + udc->usb_slv_clk = clk_get(&pdev->dev, "ck_usbd"); + if (IS_ERR(udc->usb_slv_clk)) { + dev_err(udc->dev, "failed to acquire USB device clock"); + retval = PTR_ERR(udc->usb_slv_clk); + goto usb_clk_get_fail; + } + + /* Setup PLL clock to 48MHz */ + retval = clk_enable(udc->usb_pll_clk); + if (retval < 0) { + dev_err(udc->dev, "failed to start USB PLL"); + goto pll_enable_fail; + } + + retval = clk_set_rate(udc->usb_pll_clk, 48000); + if (retval < 0) { + dev_err(udc->dev, "failed to set USB clock rate"); + goto pll_set_fail; + } + + __raw_writel(__raw_readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, USB_CTRL); + + /* Enable USB device clock */ + retval = clk_enable(udc->usb_slv_clk); + if (retval < 0) { + dev_err(udc->dev, "failed to start USB device clock"); + goto usb_clk_enable_fail; + } + + /* Set to enable all needed USB OTG clocks */ + __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); + + /* This is unsafe */ + while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != + USB_CLOCK_MASK); + + /* All clocks are now on */ + udc->clocked = 1; + + retval = i2c_add_driver(&isp1301_driver); + if (retval < 0) { + dev_err(udc->dev, "Failed to add ISP1301 driver \n"); + goto i2c_add_fail; + } + i2c_adap = i2c_get_adapter(2); + memset(&i2c_info, 0, sizeof(struct i2c_board_info)); + isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, + normal_i2c); + i2c_put_adapter(i2c_adap); + if (!isp1301_i2c_client) { + dev_err(udc->dev,"failed to connect I2C to ISP1301 USB Transceiver"); + goto i2c_probe_fail; + } + + dev_info(udc->dev, "I2C device at address 0x%x", isp1301_i2c_client->addr); + + isp1301_udc_configure(udc); + /* Map register space */ + udc->udp_baseaddr = ioremap(udc->io_p_start, udc->io_p_size); + if (!udc->udp_baseaddr) { + retval = -ENOMEM; + dev_err(udc->dev, "IO map failure"); + goto io_map_fail; + } + + /* Allocate memory for the UDCA */ + udc->udca_v_base = dma_alloc_coherent(&pdev->dev, UDCA_BUFF_SIZE, + &dma_handle, (GFP_KERNEL | GFP_DMA)); + if (!udc->udca_v_base) + { + dev_err(udc->dev, "error getting UDCA region"); + retval = -ENOMEM; + goto dma_alloc_fail; + } + udc->udca_p_base = (void *) dma_handle; + dev_dbg(udc->dev, "DMA buffer(0x%x bytes), P:0x%08x, V:0x%08x", + UDCA_BUFF_SIZE, (u32) udc->udca_p_base, (u32) udc->udca_v_base); + + /* Setup the DD DMA memory pool */ + udc->dd_cache = dma_pool_create ("udc_dd", udc->dev, + sizeof (struct lpc32xx_usbd_dd_gad), sizeof (u32), 0); + if (!udc->dd_cache) { + dev_err(udc->dev, "error getting DD DMA region"); + retval = -ENOMEM; + goto dma2_alloc_fail; + } + + /* Clear USB peripheral and initialize gadget endpoints */ + udc_disable(udc); + udc_reinit(udc); + + retval = device_register(&udc->gadget.dev); + if (retval < 0) { + dev_err(udc->dev, "Device registration failure"); + goto dev_register_fail; + } + + /* Request IRQs - low and high priority USB device IRQs are routed to the + same handler, while the DMA interrupt is routed elsewhere */ + retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq, + 0, "udc_lp", udc); + if (retval < 0) { + dev_err(udc->dev, "LP request irq %d failed", udc->udp_irq[IRQ_USB_LP]); + goto irq_lp_fail; + } + retval = request_irq(udc->udp_irq[IRQ_USB_HP], lpc32xx_usb_hp_irq, + 0, "udc_hp", udc); + if (retval < 0) { + dev_err(udc->dev, "HP request irq %d failed", udc->udp_irq[IRQ_USB_HP]); + goto irq_hp_fail; + } + + retval = request_irq(udc->udp_irq[IRQ_USB_DEVDMA], lpc32xx_usb_devdma_irq, + 0, "udc_dma", udc); + if (retval < 0) { + dev_err(udc->dev, "DEV request irq %d failed", udc->udp_irq[IRQ_USB_DEVDMA]); + goto irq_dev_fail; + } + + /* Create VBUS handler thread */ + udc->thread_wakeup_needed = 0; + udc->thread_task = kthread_create(vbus_handler_thread, udc, + "vbus_handler_thread"); + if (IS_ERR(udc->thread_task)) { + retval = PTR_ERR(udc->thread_task); + dev_err(udc->dev, "VBUS handler thread failures"); + goto vbus_thread_fail; + } + + /* The transceiver interrupt is used for VBUS detection and will + kick off the VBUS handler thread */ + retval = request_threaded_irq(udc->udp_irq[IRQ_USB_ATX], NULL, lpc32xx_usb_vbus_irq, + IRQF_ONESHOT, "udc_otg", udc); + if (retval < 0) { + dev_err(udc->dev, "VBUS request irq %d failed\n", udc->udp_irq[IRQ_USB_ATX]); + goto irq_xcvr_fail; + } + + /* Initialize wait queue */ + init_waitqueue_head(&udc->ep_disable_wait_queue); + atomic_set(&udc->enabled_ep_cnt,0); + + /* Keep VBUS IRQ disabled until GadgetFS starts up */ + disable_irq(udc->udp_irq[IRQ_USB_ATX]); + + dev_set_drvdata(dev, udc); + device_init_wakeup(dev, 1); + create_debug_file(udc); + + /* Disable clocks for now */ + udc_clk_set(udc, 0); + + dev_info(udc->dev, "%s version %s\n", driver_name, DRIVER_VERSION); + return 0; + +irq_xcvr_fail: + kthread_stop(udc->thread_task); +vbus_thread_fail: + free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc); +irq_dev_fail: + free_irq(udc->udp_irq[IRQ_USB_HP], udc); +irq_hp_fail: + free_irq(udc->udp_irq[IRQ_USB_LP], udc); +irq_lp_fail: + device_unregister(&udc->gadget.dev); +dev_register_fail: + dma_pool_destroy(udc->dd_cache); +dma2_alloc_fail: + dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, + udc->udca_v_base, (dma_addr_t) udc->udca_p_base); +dma_alloc_fail: + iounmap(udc->udp_baseaddr); +io_map_fail: + i2c_unregister_device(isp1301_i2c_client); + isp1301_i2c_client = NULL; +i2c_probe_fail: + i2c_del_driver(&isp1301_driver); +i2c_add_fail: + clk_disable(udc->usb_slv_clk); +usb_clk_enable_fail: +pll_set_fail: + clk_disable(udc->usb_pll_clk); +pll_enable_fail: + clk_put(udc->usb_slv_clk); +usb_clk_get_fail: + clk_put(udc->usb_pll_clk); +pll_get_fail: + release_mem_region(udc->io_p_start, udc->io_p_size); + dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval); + + return retval; +} + +static int __exit lpc32xx_udc_remove(struct platform_device *pdev) +{ + struct lpc32xx_udc *udc = platform_get_drvdata(pdev); + + if (udc->driver) + return -EBUSY; + + udc_clk_set(udc, 1); + udc_disable(udc); + pullup(udc, 0); + + free_irq(udc->udp_irq[IRQ_USB_ATX], udc); + + device_init_wakeup(&pdev->dev, 0); + remove_debug_file(udc); + + dma_pool_destroy(udc->dd_cache); + dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, + udc->udca_v_base, (dma_addr_t) udc->udca_p_base); + kthread_stop(udc->thread_task); + free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc); + free_irq(udc->udp_irq[IRQ_USB_HP], udc); + free_irq(udc->udp_irq[IRQ_USB_LP], udc); + + device_unregister(&udc->gadget.dev); + + clk_disable(udc->usb_slv_clk); + clk_put(udc->usb_slv_clk); + clk_disable(udc->usb_pll_clk); + clk_put(udc->usb_pll_clk); + iounmap(udc->udp_baseaddr); + i2c_unregister_device(isp1301_i2c_client); + isp1301_i2c_client = NULL; + i2c_del_driver(&isp1301_driver); + release_mem_region(udc->io_p_start, udc->io_p_size); + + return 0; +} + +#ifdef CONFIG_PM +static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + struct lpc32xx_udc *udc = platform_get_drvdata(pdev); + + if (udc->clocked) { + /* Power down ISP */ + isp1301_set_powerstate(0); + + /* Disable clocking */ + udc_clk_set(udc, 0); + + /* Keep clock flag on, so we know to re-enable clocks + on resume */ + udc->clocked = 1; + + /* Kill OTG and I2C clocks */ + __raw_writel(0, USB_OTG_CLK_CTRL); + while ((__raw_readl(USB_OTG_CLK_STAT) & OTGOFF_CLK_MASK) != + OTGOFF_CLK_MASK); + + /* Kill global USB clock */ + clk_disable(udc->usb_slv_clk); + } + + return 0; +} + +static int lpc32xx_udc_resume(struct platform_device *pdev) +{ + struct lpc32xx_udc *udc = platform_get_drvdata(pdev); + + if (udc->clocked) { + /* Enable global USB clock */ + clk_enable(udc->usb_slv_clk); + + /* Enable clocking */ + udc_clk_set(udc, 1); + + /* ISP back to normal power mode */ + isp1301_set_powerstate(1); + } + + return 0; +} +#else +#define lpc32xx_udc_suspend NULL +#define lpc32xx_udc_resume NULL +#endif + +static struct platform_driver lpc32xx_udc_driver = { + .probe = lpc32xx_udc_probe, + .remove = __exit_p(lpc32xx_udc_remove), + .shutdown = lpc32xx_udc_shutdown, + .suspend = lpc32xx_udc_suspend, + .resume = lpc32xx_udc_resume, + .driver = { + .name = (char *) driver_name, + .owner = THIS_MODULE, + }, +}; + +static int __init udc_init_module(void) +{ + return platform_driver_register(&lpc32xx_udc_driver); +} +module_init(udc_init_module); + +static void __exit udc_exit_module(void) +{ + platform_driver_unregister(&lpc32xx_udc_driver); +} +module_exit(udc_exit_module); + +MODULE_DESCRIPTION("LPC32XX udc driver"); +MODULE_AUTHOR("Kevin Wells + * + * Copyright (C) 2009 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LPC32XX_UDC_H +#define LPC32XX_UDC_H + +/* + * Although the driver supports DMA, it is not yet working completely. It + * seems to work ok for serial ACM, but eventually bonks out for MSC and + * ether classes. Disabling this define will use FIFO mode for all EPs + */ +#define UDC_ENABLE_DMA + +/* + * controller driver data structures + */ + +/* 16 endpoints (not to be confused with 32 hardware endpoints) */ +#define NUM_ENDPOINTS 16 + +/* + * IRQ indices make reading the code a little easier + */ +#define IRQ_USB_LP 0 +#define IRQ_USB_HP 1 +#define IRQ_USB_DEVDMA 2 +#define IRQ_USB_ATX 3 + +#define EP_OUT 0 /* RX (from host) */ +#define EP_IN 1 /* TX (to host) */ + +/* Returns the interrupt mask for the selected hardware endpoint */ +#define EP_MASK_SEL(ep, dir) (1 << (((ep) * 2) + dir)) + +#define EP_INT_TYPE 0 +#define EP_ISO_TYPE 1 +#define EP_BLK_TYPE 2 +#define EP_CTL_TYPE 3 + +/* EP0 states */ +#define WAIT_FOR_SETUP 0 /* Wait for setup packet */ +#define DATA_IN 1 /* Expect dev->host transfer */ +#define DATA_OUT 2 /* Expect host->dev transfer */ +#define WAIT_OUT 3 /* ??? */ + +/* DD (DMA Descriptor) structure, requires word alignment, this is already defined + in the LPC32XX USB device header file, but this version si slightly modified to + tag some work data with each DMA descriptor. */ +struct lpc32xx_usbd_dd_gad; +struct lpc32xx_usbd_dd_gad +{ + struct lpc32xx_usbd_dd_gad *dd_next_phy; + u32 dd_setup; + u32 dd_buffer_addr; + u32 dd_status; + u32 *dd_iso_ps_mem_addr; + dma_addr_t this_dma; + u32 iso_status[5]; + struct lpc32xx_usbd_dd_gad *dd_next_v; +}; + +/* + * Logical endpoint structure + */ +struct lpc32xx_ep { + struct usb_ep ep; + struct list_head queue; + struct lpc32xx_udc *udc; + + u32 hwep_num_base; /* Physical hardware EP */ + u32 hwep_num; /* Maps to hardware endpoint */ + u32 maxpacket; + u32 doublebuff; + u32 lep; + + u32 is_in:1; + u32 uses_dma:1; + volatile u32 req_pending:1; + u32 eptype; + + /* Statuses for proc, NAK and stall aren't used */ + u32 totalints; + u32 totalnaks; + u32 totalstalls; + + const struct usb_endpoint_descriptor *desc; +}; + +/* + * Common UDC structure + */ +struct lpc32xx_udc { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct platform_device *pdev; + struct device *dev; + struct proc_dir_entry *pde; + spinlock_t lock; + + /* Board and device specific */ + struct lpc32xx_usbd_cfg *board; + u32 io_p_start; + u32 io_p_size; + void __iomem *udp_baseaddr; + int udp_irq[4]; + struct clk *usb_pll_clk; + struct clk *usb_slv_clk; + + /* DMA support */ + u32 *udca_v_base; + u32 *udca_p_base; + struct dma_pool *dd_cache; + + /* Common EP and control data */ + u32 enabled_devints; + u32 enabled_hwepints; + u32 dev_status; + u32 realized_eps; + + /* VBUS thread support */ + struct task_struct *thread_task; + volatile int thread_wakeup_needed; + u8 vbus; + u8 last_vbus; + volatile int irq_asrtd; + + /* USB device peripheral - various */ + struct lpc32xx_ep ep[NUM_ENDPOINTS]; + u32 enabled:1; + u32 clocked:1; + u32 suspended:1; + u32 selfpowered:1; + int ep0state; + atomic_t enabled_ep_cnt; + wait_queue_head_t ep_disable_wait_queue; +}; + +/* + * Endpoint request + */ +struct lpc32xx_request { + struct usb_request req; + struct list_head queue; + struct lpc32xx_usbd_dd_gad *dd_desc_ptr; + u32 mapped:1; + u32 send_zlp:1; +}; + +static inline struct lpc32xx_udc *to_udc(struct usb_gadget *g) +{ + return container_of(g, struct lpc32xx_udc, gadget); +} + +#define ep_dbg(epp, fmt, arg...) \ + dev_dbg(epp->udc->dev, "%s:%s: " fmt, epp->ep.name, __func__, ## arg) +#define ep_err(epp, fmt, arg...) \ + dev_err(epp->udc->dev, "%s:%s: " fmt, epp->ep.name, __func__, ## arg) +#define ep_info(epp, fmt, arg...) \ + dev_info(epp->udc->dev, "%s:%s: " fmt, epp->ep.name, __func__, ## arg) +#define ep_warn(epp, fmt, arg...) \ + dev_warn(epp->udc->dev, "%s:%s:" fmt, epp->ep.name, __func__, ## arg) + +#endif + diff -purN linux-2.6.34/drivers/usb/gadget/Makefile linux-2.6.34-dev/drivers/usb/gadget/Makefile --- linux-2.6.34/drivers/usb/gadget/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/gadget/Makefile 2010-10-15 14:10:00.128530188 +0100 @@ -28,7 +28,7 @@ obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o - +obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o # # USB gadget drivers # diff -purN linux-2.6.34/drivers/usb/host/ohci-hcd.c linux-2.6.34-dev/drivers/usb/host/ohci-hcd.c --- linux-2.6.34/drivers/usb/host/ohci-hcd.c 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/host/ohci-hcd.c 2010-10-15 14:10:00.128530188 +0100 @@ -1051,6 +1051,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER usb_hcd_pnx4008_driver #endif +#ifdef CONFIG_ARCH_LPC32XX +#include "ohci-pnx4008.c" +#define PLATFORM_DRIVER usb_hcd_pnx4008_driver +#endif + #ifdef CONFIG_ARCH_DAVINCI_DA8XX #include "ohci-da8xx.c" #define PLATFORM_DRIVER ohci_hcd_da8xx_driver diff -purN linux-2.6.34/drivers/usb/host/ohci-pnx4008.c linux-2.6.34-dev/drivers/usb/host/ohci-pnx4008.c --- linux-2.6.34/drivers/usb/host/ohci-pnx4008.c 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/usb/host/ohci-pnx4008.c 2010-10-15 14:10:00.128530188 +0100 @@ -24,9 +24,16 @@ #include #include +#if defined(CONFIG_ARCH_LPC32XX) +#include +#include +#define PNX4008_PWRMAN_BASE LPC32XX_CLK_PM_BASE +#define PNX4008_USB_CONFIG_BASE LPC32XX_USB_BASE +#else #include #include #include +#endif #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) @@ -143,8 +150,19 @@ static void i2c_write(u8 buf, u8 subaddr i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2); } +static u16 i2c_read16(u8 subaddr) +{ + u16 data; + + i2c_master_send(isp1301_i2c_client, &subaddr, 1); + i2c_master_recv(isp1301_i2c_client, (u8 *) &data, 2); + + return data; +} + static void isp1301_configure(void) { +#if !defined(CONFIG_ARCH_LPC32XX) /* PNX4008 only supports DAT_SE0 USB mode */ /* PNX4008 R2A requires setting the MAX603 to output 3.6V */ /* Power up externel charge-pump */ @@ -166,7 +184,40 @@ static void isp1301_configure(void) ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); i2c_write(0xFF, ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); - +#else + /* LPC32XX only supports DAT_SE0 USB mode */ + /* This sequence is important */ + + /* Disable transparent UART mode first */ + i2c_write(MC1_UART_EN, (ISP1301_I2C_MODE_CONTROL_1 | + ISP1301_I2C_REG_CLEAR_ADDR)); + + i2c_write(~MC1_SPEED_REG, (ISP1301_I2C_MODE_CONTROL_1 | + ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write(MC1_SPEED_REG, ISP1301_I2C_MODE_CONTROL_1); + i2c_write(~0, (ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write((MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL), + ISP1301_I2C_MODE_CONTROL_2); + i2c_write(~0, (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write(MC1_DAT_SE0, ISP1301_I2C_MODE_CONTROL_1); + i2c_write((OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN), + ISP1301_I2C_OTG_CONTROL_1); + i2c_write((OTG1_DM_PULLUP | OTG1_DP_PULLUP), + (ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR)); + i2c_write(~0, + ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR); + i2c_write(~0, + ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR); + i2c_write(~0, + ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR); + + /* Enable usb_need_clk clock after transceiver is initialized */ + __raw_writel((__raw_readl(USB_CTRL) | (1 << 22)), USB_CTRL); + + printk(KERN_INFO "ISP1301 Vendor ID : 0x%04x\n", i2c_read16(0x00)); + printk(KERN_INFO "ISP1301 Product ID : 0x%04x\n", i2c_read16(0x02)); + printk(KERN_INFO "ISP1301 Version ID : 0x%04x\n", i2c_read16(0x14)); +#endif } static inline void isp1301_vbus_on(void) @@ -257,6 +308,7 @@ static const struct hc_driver ohci_pnx40 static void pnx4008_set_usb_bits(void) { +#if !defined(CONFIG_ARCH_LPC32XX) start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N); start_int_ack(SE_USB_OTG_ATX_INT_N); start_int_umask(SE_USB_OTG_ATX_INT_N); @@ -280,16 +332,19 @@ static void pnx4008_set_usb_bits(void) start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT); start_int_ack(SE_USB_AHB_NEED_CLK_INT); start_int_umask(SE_USB_AHB_NEED_CLK_INT); +#endif } static void pnx4008_unset_usb_bits(void) { +#if !defined(CONFIG_ARCH_LPC32XX) start_int_mask(SE_USB_OTG_ATX_INT_N); start_int_mask(SE_USB_OTG_TIMER_INT); start_int_mask(SE_USB_I2C_INT); start_int_mask(SE_USB_INT); start_int_mask(SE_USB_NEED_CLK_INT); start_int_mask(SE_USB_AHB_NEED_CLK_INT); +#endif } static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) @@ -320,6 +375,16 @@ static int __devinit usb_hcd_pnx4008_pro /* Enable AHB slave USB clock, needed for further USB clock control */ __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL); +#if defined(CONFIG_ARCH_LPC32XX) + if ((__raw_readl(USB_OTG_CLK_STAT) & I2C_CLOCK_ON) != I2C_CLOCK_ON) + { + /* Enable I2C clock in the OTG block if it isn't on */ + __raw_writel(I2C_CLOCK_ON, USB_OTG_CLK_CTRL); + + /* Ideally, a timeout based on jiffies would be nice here */ + while (__raw_readl(USB_OTG_CLK_STAT) != I2C_CLOCK_ON); + } +#endif ret = i2c_add_driver(&isp1301_driver); if (ret < 0) { err("failed to add ISP1301 driver"); diff -purN linux-2.6.34/drivers/watchdog/Kconfig linux-2.6.34-dev/drivers/watchdog/Kconfig --- linux-2.6.34/drivers/watchdog/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/drivers/watchdog/Kconfig 2010-10-15 14:10:00.128530188 +0100 @@ -201,7 +201,7 @@ config OMAP_WATCHDOG config PNX4008_WATCHDOG tristate "PNX4008 Watchdog" - depends on ARCH_PNX4008 + depends on ARCH_PNX4008 || ARCH_LPC32XX help Say Y here if to include support for the watchdog timer in the PNX4008 processor. diff -purN linux-2.6.34/include/linux/amba/clcd.h linux-2.6.34-dev/include/linux/amba/clcd.h --- linux-2.6.34/include/linux/amba/clcd.h 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/include/linux/amba/clcd.h 2010-10-15 14:10:00.128530188 +0100 @@ -232,14 +232,29 @@ static inline void clcdfb_decode(struct static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) { + u32 hbp, hfp, hsw; + + /* + * These clock constraints are for the pl11x DMA latency. TFT mode + * is slightly faster than STN + */ + if (fb->panel->cntl & CNTL_LCDTFT) { + /* No TFT constraint given for min TFT HFP clocks in TRM */ + hbp = hfp = (2 + 1); + hsw = (2 + 1); + } else { + hbp = hfp = (5 + 1); + hsw = (3 + 1); + } + var->xres_virtual = var->xres = (var->xres + 15) & ~15; var->yres_virtual = var->yres = (var->yres + 1) & ~1; #define CHECK(e,l,h) (var->e < l || var->e > h) - if (CHECK(right_margin, (5+1), 256) || /* back porch */ - CHECK(left_margin, (5+1), 256) || /* front porch */ - CHECK(hsync_len, (5+1), 256) || - var->xres > 4096 || + if (CHECK(right_margin, hbp, 256) || /* back porch */ + CHECK(left_margin, hfp, 256) || /* front porch */ + CHECK(hsync_len, hsw, 256) || + var->xres > 1024 || var->lower_margin > 255 || /* back porch */ var->upper_margin > 255 || /* front porch */ var->vsync_len > 32 || diff -purN linux-2.6.34/sound/soc/codecs/uda1380.c linux-2.6.34-dev/sound/soc/codecs/uda1380.c --- linux-2.6.34/sound/soc/codecs/uda1380.c 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/codecs/uda1380.c 2010-10-15 14:10:00.128530188 +0100 @@ -55,7 +55,7 @@ static const u16 uda1380_reg[UDA1380_CAC 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8000, 0x0002, 0x0000, + 0x0000, 0x0000, 0x0002, 0x0000, }; static unsigned long uda1380_cache_dirty; @@ -402,9 +402,14 @@ static int uda1380_set_dai_fmt_both(stru iface |= R01_SFORI_MSB | R01_SFORO_MSB; } + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) + iface |= R01_SIM; + +#if 0 /* DATAI is slave only, so in single-link mode, this has to be slave */ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) return -EINVAL; +#endif uda1380_write(codec, UDA1380_IFACE, iface); @@ -496,9 +501,47 @@ static int uda1380_trigger(struct snd_pc return 0; } +static int uda1380_pcm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + int reg, reg_start, reg_end, clk; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + reg_start = UDA1380_MVOL; + reg_end = UDA1380_MIXER; + } else { + reg_start = UDA1380_DEC; + reg_end = UDA1380_AGC; + } + + clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK); + + for (reg = reg_start; reg <= reg_end; reg++) { + pr_debug("uda1380: flush reg %x val %x:", reg, + uda1380_read_reg_cache(codec, reg)); + if(reg == UDA1380_MIXER) + uda1380_write(codec, reg, + uda1380_read_reg_cache(codec, reg) | R14_SILENCE); + /* Disable DAC mute */ + else if(reg == UDA1380_PGA) + uda1380_write(codec, reg, + uda1380_read_reg_cache(codec, reg) & ~R21_MT_ADC); + else + uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); + } + + uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); + + return 0; +} + static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) + 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; @@ -586,6 +629,7 @@ static int uda1380_set_bias_level(struct static struct snd_soc_dai_ops uda1380_dai_ops = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, .trigger = uda1380_trigger, .set_fmt = uda1380_set_dai_fmt_both, }; @@ -593,6 +637,7 @@ static struct snd_soc_dai_ops uda1380_da static struct snd_soc_dai_ops uda1380_dai_ops_playback = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, .trigger = uda1380_trigger, .set_fmt = uda1380_set_dai_fmt_playback, }; @@ -600,6 +645,7 @@ static struct snd_soc_dai_ops uda1380_da static struct snd_soc_dai_ops uda1380_dai_ops_capture = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, .trigger = uda1380_trigger, .set_fmt = uda1380_set_dai_fmt_capture, }; @@ -705,7 +751,7 @@ static int uda1380_probe(struct platform uda1380_write(codec, UDA1380_CLK, 0); break; case UDA1380_DAC_CLK_WSPLL: - uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK); + uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK | R00_ADC_CLK); break; } diff -purN linux-2.6.34/sound/soc/codecs/uda1380.h linux-2.6.34-dev/sound/soc/codecs/uda1380.h --- linux-2.6.34/sound/soc/codecs/uda1380.h 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/codecs/uda1380.h 2010-10-15 14:10:00.128530188 +0100 @@ -36,6 +36,7 @@ #define R00_EN_DEC 0x0400 #define R00_EN_DAC 0x0200 #define R00_EN_INT 0x0100 +#define R00_ADC_CLK 0x0020 #define R00_DAC_CLK 0x0010 #define R01_SFORI_I2S 0x0000 #define R01_SFORI_LSB16 0x0100 diff -purN linux-2.6.34/sound/soc/Kconfig linux-2.6.34-dev/sound/soc/Kconfig --- linux-2.6.34/sound/soc/Kconfig 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/Kconfig 2010-10-15 14:10:00.128530188 +0100 @@ -36,6 +36,7 @@ source "sound/soc/s3c24xx/Kconfig" source "sound/soc/s6000/Kconfig" source "sound/soc/sh/Kconfig" source "sound/soc/txx9/Kconfig" +source "sound/soc/lpc3xxx/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff -purN linux-2.6.34/sound/soc/lpc3xxx/Kconfig linux-2.6.34-dev/sound/soc/lpc3xxx/Kconfig --- linux-2.6.34/sound/soc/lpc3xxx/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/Kconfig 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,55 @@ +config SND_LPC3XXX_SOC + tristate "SoC Audio for the NXP LPC32XX System-on-a-Chip" + depends on ARCH_LPC32XX && SND_SOC + help + Say Y or M if you want to add support for codecs attached to + the LPC3XXX I2S interface. You will also need to to select + the audio interfaces to support below. + +config SND_LPC3XXX_SOC_I2S_UDA1380 + tristate "SoC Audio support for Phytec 3250 board with the UDA1380" + depends on SND_LPC3XXX_SOC + select I2C + select SND_SOC_UDA1380 + select SND_LPC32XX_USEI2S1 + select SND_LPC32XX_SLAVE_TX_CLK_TO_RX + help + Say Y or M here if you want to add support for SoC audio + on the Phytec 3250 board. This requires an I2C channel connected + to the I2C interface of the UDA1380 codec. + +config SND_LPC32XX_USEI2S1 + bool "Use I2S1 channel instead of I2S0" + depends on SND_LPC3XXX_SOC + help + The LPC32XX has 2 I2S channels (0 and 1). Normally, I2S0 is + used for communications with an I2S codec. If I2S1 should be + used instead, select this option. For LPC32XX systems that + used the LCD interface, I2S1 must be used. + +config SND_LPC32XX_USEI2S_SLAVE_MODETX + bool "Use slave mode on the TX channel instead of master mode" + depends on SND_LPC3XXX_SOC + default n + help + In this mode, the TX WS and bit clocks are driven from the audio + CODEC instead of from the LPC32x0. For most CODECs, this won't + be the case, but CODECs that have their own clocking may be able + to provide TX clocking. + +config SND_LPC32XX_USEI2S_SLAVE_MODERX + bool "Use slave mode on the RX channel instead of master mode" + depends on SND_LPC3XXX_SOC + default n + help + In this mode, the RX WS and bit clocks are driven from the audio + CODEC instead of from the LPC32x0. + +config SND_LPC32XX_SLAVE_TX_CLK_TO_RX + bool "Enable TX WS clock during RX" + depends on SND_LPC3XXX_SOC + default n + help + This enables the TX WS clock during RX transfers. Some CODECS use + the TX clock for internal clock or for RX clocking. + diff -purN linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-i2s.c linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-i2s.c --- linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-i2s.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-i2s.c 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,538 @@ +/* + * sound/soc/lpc3xxx/lpc3xxx-i2s.c + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include "lpc3xxx-pcm.h" +#include "lpc3xxx-i2s.h" + +#include + +#define I2S_NAME "lpc3xxx-i2s" + +#define LPC3XXX_I2S_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) + +#define LPC3XXX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SND_SOC_DAIFMT_I2S | \ + SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S32) + +#define CLKPWR_IOBASE io_p2v(CLK_PM_BASE) + +static struct lpc3xxx_i2s_info i2s_info[NUM_I2S_DEVICES] = { + { + .name = "i2s0", + .lock = __SPIN_LOCK_UNLOCKED(i2s_info[0].lock), + .initialized = 0, + .clkname = "i2s0_ck", + .baseio = LPC32XX_I2S0_BASE, + }, + { + .name = "i2s1", + .lock = __SPIN_LOCK_UNLOCKED(i2s_info[1].lock), + .initialized = 0, + .clkname = "i2s1_ck", + .baseio = LPC32XX_I2S1_BASE, + }, +}; + +static u32 absd32(u32 v1, u32 v2) { + if (v1 > v2) { + return v1 - v2; + } + + return v2 - v1; +} + +static void __lpc3xxx_find_clkdiv(u32 *clkx, u32 *clky, int freq, + int xbytes, u32 clkrate) { + u32 i2srate; + u32 idxx, idyy; + u32 savedbitclkrate, diff, trate, baseclk; + + /* Adjust rate for sample size (bits) and 2 channels and offset for + divider in clock output */ + i2srate = (freq / 100) * 2 * (8 * xbytes); + i2srate = i2srate << 1; + clkrate = clkrate / 100; + baseclk = clkrate; + *clkx = 1; + *clky = 1; + + /* Find the best divider */ + *clkx = *clky = 0; + savedbitclkrate = 0; + diff = ~0; + for (idxx = 1; idxx < 0xFF; idxx++) { + for (idyy = 1; idyy < 0xFF; idyy++) { + trate = (baseclk * idxx) / idyy; + if (absd32(trate, i2srate) < diff) { + diff = absd32(trate, i2srate); + savedbitclkrate = trate; + *clkx = idxx; + *clky = idyy; + } + } + } +} + +static int lpc3xxx_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[rtd->dai->cpu_dai->id]; + u32 dmamask, clkx, clky; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dmamask = I2S_DMA_XMIT; + } + else { + dmamask = I2S_DMA_RECV; + } + if (dmamask & i2s_info_p->dma_flags) { + /* This channel already enabled! */ + pr_warning("%s: I2S DMA channel is busy!\n", + I2S_NAME); + return -EBUSY; + } + + /* Initialize I2S interface */ + if (i2s_info_p->initialized == 0) { + i2s_info_p->clk = clk_get(NULL, i2s_info_p->clkname); + if (IS_ERR(i2s_info_p->clk)) { + i2s_info_p->clk = NULL; + pr_warning("%s: Failed enabling the I2S clock: %s\n", + I2S_NAME, i2s_info_p->clkname); + return -ENODEV; + } + + clk_enable(i2s_info_p->clk); + i2s_info_p->clkrate = clk_get_rate(i2s_info_p->clk); + if (i2s_info_p->clkrate == 0) { + pr_warning("%s: Invalid returned clock rate\n", + I2S_NAME); + clk_disable(i2s_info_p->clk); + clk_put(i2s_info_p->clk); + i2s_info_p->clk = NULL; + return -ENODEV; + } + + i2s_info_p->iomem = ioremap(i2s_info_p->baseio, SZ_4K); + if (i2s_info_p->iomem == NULL) { + pr_warning("%s: Can't remap I2S registers\n", + I2S_NAME); + clk_disable(i2s_info_p->clk); + clk_put(i2s_info_p->clk); + i2s_info_p->clk = NULL; + return -ENOMEM; + } + + /* I2S is setup here with a dummy configuration to allow the + bit clock to toggle. The CODEC attached to the I2S may not + work without this clock. The actual values here do not yet + matter and will be reconfigured when needed by the I2S hw + setup function. To match the default selected PLL setting, + this clock should be between 6.25 and 12.5KHz */ + if (i2s_info_p->initialized == 0) { + __raw_writel(I2S_DMA0_TX_DEPTH(4), + I2S_DMA1(i2s_info_p->iomem)); + __lpc3xxx_find_clkdiv(&clkx, &clky, 9000, 2, + i2s_info_p->clkrate); + __raw_writel(((clkx << 8) | clky), I2S_TX_RATE(i2s_info_p->iomem)); + __raw_writel(0x83C1, I2S_DAO(i2s_info_p->iomem)); + + } + + i2s_info_p->initialized = 1; + } + + i2s_info_p->dma_flags |= dmamask; + + return 0; +} + +static void lpc3xxx_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[rtd->dai->cpu_dai->id]; + u32 dmamask, tmp; + + if (i2s_info_p->initialized == 0) { + /* Nothing is enabled! */ + pr_warning("%s: Shutdown when nothing is enabled!\n", + I2S_NAME); + return; + } + + /* Disable I2S based on stream */ + spin_lock_irq(&i2s_info_p->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dmamask = I2S_DMA_XMIT; + tmp = __raw_readl(I2S_DAO(i2s_info_p->iomem)); + tmp |= I2S_STOP; + __raw_writel(tmp, I2S_DAO(i2s_info_p->iomem)); + __raw_writel(0, I2S_TX_RATE(i2s_info_p->iomem)); + } + else { + dmamask = I2S_DMA_RECV; + tmp = __raw_readl(I2S_DAI(i2s_info_p->iomem)); + tmp |= I2S_STOP; + __raw_writel(tmp, I2S_DAI(i2s_info_p->iomem)); + __raw_writel(0, I2S_RX_RATE(i2s_info_p->iomem)); + } + +#if defined(CONFIG_SND_LPC32XX_SLAVE_TX_CLK_TO_RX) + /* Slave the RX WSI signal to the TX WSI signal */ + tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); + tmp &= ~(1 << 6); + __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL); +#endif + + spin_unlock_irq(&i2s_info_p->lock); + + /* If both streams are shut down, then disable I2S to save power */ + i2s_info_p->dma_flags &= ~dmamask; + if (i2s_info_p->dma_flags == 0) { + clk_disable(i2s_info_p->clk); + clk_put(i2s_info_p->clk); + i2s_info_p->initialized = 0; + } +} + +static int lpc3xxx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[cpu_dai->id]; + + /* Will use in HW params later */ + i2s_info_p->freq = freq; + + return 0; +} + +static int lpc3xxx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[cpu_dai->id]; + + /* Will use in HW params later */ + i2s_info_p->daifmt = fmt; + + return 0; +} + +static int lpc3xxx_i2s_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[cpu_dai->id]; + + /* This function doesn't help, but save the value anyways. + HW params will determine the correct clock divider based + on the frequency */ + i2s_info_p->clkdiv = div; + + return 0; +} + +static int lpc3xxx_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; + int id = rtd->dai->cpu_dai->id; + struct lpc3xxx_i2s_info *i2s_info_p; + int xfersize; + u32 tmp, tmp2, clkx, clky; + + (void) tmp2; + i2s_info_p = &i2s_info[id]; + + /* Build the I2S setup word */ + tmp = 0; + + if ((i2s_info_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBM_CFM) { + tmp |= I2S_WS_SEL; + } + + switch (i2s_info_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SNDRV_PCM_FMTBIT_S8: + tmp |= I2S_WW8 | I2S_WS_HP(I2S_WW8_HP); + xfersize = 1; + break; + + case SNDRV_PCM_FMTBIT_S16: + case SND_SOC_DAIFMT_I2S: + tmp |= I2S_WW16 | I2S_WS_HP(I2S_WW16_HP); + xfersize = 2; + break; + + case SNDRV_PCM_FMTBIT_S32: + tmp |= I2S_WW32 | I2S_WS_HP(I2S_WW32_HP); + xfersize = 4; + break; + + default: + pr_warning("%s: Unsupported audio data format\n", + I2S_NAME); + return -EINVAL; + } + + /* Mono or stereo? */ + if (params_channels(params) == 1) { + tmp |= I2S_MONO; + } + + /* Find the best clock dividers to generate the requested + frequency */ + __lpc3xxx_find_clkdiv(&clkx, &clky, i2s_info_p->freq, xfersize, i2s_info_p->clkrate); + + pr_debug("Desired clock rate : %d\n", i2s_info_p->freq); + pr_debug("Base clock rate : %d\n", i2s_info_p->clkrate); + pr_debug("Transfer size (bytes) : %d\n", xfersize); + pr_debug("Clock divider (x) : %d\n", clkx); + pr_debug("Clock divider (y) : %d\n", clky); + pr_debug("Channels : %d\n", params_channels(params)); + pr_debug("Data format : %d\n", i2s_info_p->daifmt); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /* Enable DAO support, correct clock rate, and DMA */ + __raw_writel(I2S_DMA1_TX_EN | I2S_DMA0_TX_DEPTH(4), + I2S_DMA1(i2s_info_p->iomem)); + __raw_writel(((clkx << 8) | clky), + I2S_TX_RATE(i2s_info_p->iomem)); + __raw_writel(tmp, I2S_DAO(i2s_info_p->iomem)); + + pr_debug("TX DMA1 : 0x%x\n", + __raw_readl(I2S_DMA1(i2s_info_p->iomem))); + pr_debug("TX dividers : 0x%x\n", + __raw_readl(I2S_TX_RATE(i2s_info_p->iomem))); + pr_debug("TX DAO : 0x%x\n", + __raw_readl(I2S_DAO(i2s_info_p->iomem))); + } + else { + /* Enable DAI support, correct clock rate, and DMA */ + __raw_writel(I2S_DMA0_RX_EN | I2S_DMA1_RX_DEPTH(4), + I2S_DMA0(i2s_info_p->iomem)); + __raw_writel(((clkx << 8) | clky), I2S_RX_RATE(i2s_info_p->iomem)); + +#if defined(CONFIG_SND_LPC32XX_SLAVE_TX_CLK_TO_RX) + /* Slave the RX WS signal to the TX WS signal */ + tmp2 = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); + tmp2 |= (1 << 6); + __raw_writel(tmp2, LPC32XX_CLKPWR_I2S_CLK_CTRL); + + /* The DAO interface needs to be enabled to route the clock from + RX to TX */ + __raw_writel((tmp & ~I2S_WS_SEL), I2S_DAO(i2s_info_p->iomem)); +#endif + + __raw_writel(tmp, I2S_DAI(i2s_info_p->iomem)); + + pr_debug("RX DMA0 : 0x%x\n", + __raw_readl(I2S_DMA0(i2s_info_p->iomem))); + pr_debug("RX dividers : 0x%x\n", + __raw_readl(I2S_RX_RATE(i2s_info_p->iomem))); + pr_debug("RX DAI : 0x%x\n", + __raw_readl(I2S_DAI(i2s_info_p->iomem))); + } + + return 0; +} + +static int lpc3xxx_i2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + /* Nothing to do here */ + return 0; +} + +static int lpc3xxx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int id = rtd->dai->cpu_dai->id; + struct lpc3xxx_i2s_info *i2s_info_p; + u32 tmp; + int ret = 0; + + i2s_info_p = &i2s_info[id]; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + tmp = __raw_readl(I2S_DAO(i2s_info_p->iomem)); + tmp |= I2S_STOP; + __raw_writel(tmp, I2S_DAO(i2s_info_p->iomem)); + } + break; + + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + tmp = __raw_readl(I2S_DAO(i2s_info_p->iomem)); + tmp &= ~I2S_STOP; + __raw_writel(tmp, I2S_DAO(i2s_info_p->iomem)); + } + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +#ifdef CONFIG_PM +static int lpc3xxx_i2s_suspend(struct snd_soc_dai *cpu_dai) +{ + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[cpu_dai->id]; + + if (!cpu_dai->active) + return 0; + + /* Save DA0, DAI, and IRQ register states */ + i2s_info_p->dao_save = __raw_readl(I2S_DAO(i2s_info_p->iomem)); + i2s_info_p->dai_save = __raw_readl(I2S_DAI(i2s_info_p->iomem)); + i2s_info_p->irq_save = __raw_readl(I2S_IRQ(i2s_info_p->iomem)); + + /* Disable system clock */ + clk_disable(i2s_info_p->clk); + + return 0; +} + +static int lpc3xxx_i2s_resume(struct snd_soc_dai *cpu_dai) +{ + struct lpc3xxx_i2s_info *i2s_info_p = &i2s_info[cpu_dai->id]; + + if (!cpu_dai->active) + return 0; + + /* Restore system clock */ + clk_enable(i2s_info_p->clk); + + /* Restore saved DA0, DAI, and IRQ register states */ + __raw_writel(i2s_info_p->dao_save, I2S_DAO(i2s_info_p->iomem)); + __raw_writel(i2s_info_p->dai_save, I2S_DAI(i2s_info_p->iomem)); + __raw_writel(i2s_info_p->irq_save, I2S_IRQ(i2s_info_p->iomem)); + + return 0; +} + +#else +# define lpc3xxx_i2s_suspend NULL +# define lpc3xxx_i2s_resume NULL +#endif + +static struct snd_soc_dai_ops lpc3xxx_i2s_dai_ops = { + .startup = lpc3xxx_i2s_startup, + .shutdown = lpc3xxx_i2s_shutdown, + .prepare = lpc3xxx_i2s_prepare, + .trigger = lpc3xxx_i2s_trigger, + .hw_params = lpc3xxx_i2s_hw_params, + .set_sysclk = lpc3xxx_i2s_set_dai_sysclk, + .set_fmt = lpc3xxx_i2s_set_dai_fmt, + .set_clkdiv = lpc3xxx_i2s_set_dai_clkdiv, +}; + + +struct snd_soc_dai lpc3xxx_i2s_dai[NUM_I2S_DEVICES] = { + { + .name = "lpc3xxx-i2s0", + .id = 0, + .suspend = lpc3xxx_i2s_suspend, + .resume = lpc3xxx_i2s_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = LPC3XXX_I2S_RATES, + .formats = LPC3XXX_I2S_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = LPC3XXX_I2S_RATES, + .formats = LPC3XXX_I2S_FORMATS, + }, + .ops = &lpc3xxx_i2s_dai_ops, + .private_data = &i2s_info[0], + }, + { + .name = "lpc3xxx-i2s1", + .id = 1, + .suspend = lpc3xxx_i2s_suspend, + .resume = lpc3xxx_i2s_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = LPC3XXX_I2S_RATES, + .formats = LPC3XXX_I2S_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = LPC3XXX_I2S_RATES, + .formats = LPC3XXX_I2S_FORMATS, + }, + .ops = &lpc3xxx_i2s_dai_ops, + .private_data = &i2s_info[1], + }, +}; +EXPORT_SYMBOL_GPL(lpc3xxx_i2s_dai); + +static int __init lpc3xxx_i2s_dai_init(void) +{ + return snd_soc_register_dais(&lpc3xxx_i2s_dai[0],2); +} +module_init(lpc3xxx_i2s_dai_init); + +static void __exit lpc3xxx_i2s_dai_exit(void) +{ + snd_soc_unregister_dais(&lpc3xxx_i2s_dai[0],2); +} +module_exit(lpc3xxx_i2s_dai_exit) + +MODULE_AUTHOR("Kevin Wells "); +MODULE_DESCRIPTION("ASoC LPC3XXX I2S interface"); +MODULE_LICENSE("GPL"); diff -purN linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-i2s.h linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-i2s.h --- linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-i2s.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-i2s.h 2010-10-15 14:10:00.138525452 +0100 @@ -0,0 +1,53 @@ +/* + * sound/soc/lpc3xxx/lpc3xxx-i2s.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SOUND_SOC_LPC3XXX_I2S_H +#define __SOUND_SOC_LPC3XXX_I2S_H + +#include +#include +#include + +#define NUM_I2S_DEVICES 2 + +#define I2S_DMA_XMIT 0x1 +#define I2S_DMA_RECV 0x2 + +struct lpc3xxx_i2s_info { + char *name; + spinlock_t lock; + void *iomem; + unsigned short initialized; + u32 dma_flags; + char *clkname; + struct clk *clk; + u32 clkrate; + u32 baseio; + int freq; + unsigned short daifmt; + int clkdiv; + u32 dao_save, dai_save, irq_save; +}; + +extern struct snd_soc_dai lpc3xxx_i2s_dai[]; + +#endif diff -purN linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-pcm.c linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-pcm.c --- linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-pcm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-pcm.c 2010-10-15 14:10:00.138525452 +0100 @@ -0,0 +1,514 @@ +/* + * sound/soc/lpc3xxx/lpc3xxx-pcm.c + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include "lpc3xxx-pcm.h" + +#define SND_NAME "lpc3xxx-audio" +static u64 lpc3xxx_pcm_dmamask = 0xffffffff; + +#define NUMLINKS (3) /* 3 DMA buffers */ + +static const struct snd_pcm_hardware lpc3xxx_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME), + .formats = (SND_SOC_DAIFMT_I2S), + .period_bytes_min = 128, + .period_bytes_max = 2048, + .periods_min = 2, + .periods_max = 1024, + .buffer_bytes_max = 128 * 1024 +}; + +struct lpc3xxx_dma_data { + dma_addr_t dma_buffer; /* physical address of DMA buffer */ + dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ + size_t period_size; + + /* DMA configuration and support */ + int dmach; + struct dma_config dmacfg; + volatile dma_addr_t period_ptr; /* physical address of next period */ + volatile dma_addr_t dma_cur; + u32 llptr; /* Saved for debug only, not used */ +}; + +static int lpc3xxx_pcm_allocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *dmabuf = &substream->dma_buffer; + size_t size = lpc3xxx_pcm_hardware.buffer_bytes_max; + + dmabuf->dev.type = SNDRV_DMA_TYPE_DEV; + dmabuf->dev.dev = pcm->card->dev; + dmabuf->private_data = NULL; + dmabuf->area = dma_alloc_writecombine(pcm->card->dev, size, + &dmabuf->addr, GFP_KERNEL); + + if (!dmabuf->area) + return -ENOMEM; + + dmabuf->bytes = size; + return 0; +} + +/* + * DMA ISR - occurs when a new DMA buffer is needed + */ +static void lpc3xxx_pcm_dma_irq(int channel, int cause, + struct snd_pcm_substream *substream) { + struct snd_pcm_runtime *rtd = substream->runtime; + struct lpc3xxx_dma_data *prtd = rtd->private_data; + static int count = 0; + + count++; + + /* A DMA interrupt occurred - for most cases, this will be the end + of a transmitted buffer in the DMA link list, but errors are also + handled. */ + if (cause & DMA_ERR_INT) { + /* DMA error - this should never happen, but you just never + know. If it does happen, the driver will continue without + any problems except for maybe an audio glitch or pop. */ + pr_debug("%s: DMA error %s (count=%d)\n", SND_NAME, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + "underrun" : "overrun", count); + } + /* Dequeue buffer from linked list */ + lpc32xx_get_free_llist_entry(channel); + prtd->dma_cur += prtd->period_size; + if (prtd->dma_cur >= prtd->dma_buffer_end) { + prtd->dma_cur = prtd->dma_buffer; + } + + /* Re-queue buffer another buffer */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + lpc32xx_dma_queue_llist_entry(prtd->dmach, (void *) prtd->period_ptr, +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + (void *) I2S_TX_FIFO(LPC32XX_I2S1_BASE), +#else + (void *) I2S_TX_FIFO(LPC32XX_I2S0_BASE), +#endif + prtd->period_size); + } + else { + lpc32xx_dma_queue_llist_entry(prtd->dmach, +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + (void *) I2S_RX_FIFO(LPC32XX_I2S1_BASE), +#else + (void *) I2S_RX_FIFO(LPC32XX_I2S0_BASE), +#endif + (void *) prtd->period_ptr, prtd->period_size); + } + prtd->period_ptr += prtd->period_size; + if (prtd->period_ptr >= prtd->dma_buffer_end) + prtd->period_ptr = prtd->dma_buffer; + + /* This only needs to be called once, even if more than 1 period has passed */ + snd_pcm_period_elapsed(substream); +} + +/* + * PCM operations + */ +static int lpc3xxx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lpc3xxx_dma_data *prtd = runtime->private_data; + + /* this may get called several times by oss emulation + * with different params + */ + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + runtime->dma_bytes = params_buffer_bytes(params); + + prtd->dma_buffer = runtime->dma_addr; + prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; + prtd->period_size = params_period_bytes(params); + + return 0; +} + +static int lpc3xxx_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct lpc3xxx_dma_data *prtd = substream->runtime->private_data; + + /* Return the DMA channel */ + if (prtd->dmach != -1) { + lpc32xx_dma_ch_disable(prtd->dmach); + lpc32xx_dma_dealloc_llist(prtd->dmach); + lpc32xx_dma_ch_put(prtd->dmach); + prtd->dmach = -1; + } + + return 0; +} + +static int lpc3xxx_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct lpc3xxx_dma_data *prtd = substream->runtime->private_data; + + /* Setup DMA channel */ + if (prtd->dmach == -1) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + prtd->dmach = DMA_CH_I2S_TX; + prtd->dmacfg.ch = DMA_CH_I2S_TX; + prtd->dmacfg.tc_inten = 1; + prtd->dmacfg.err_inten = 1; + prtd->dmacfg.src_size = 4; + prtd->dmacfg.src_inc = 1; + prtd->dmacfg.src_ahb1 = 1; + prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4; + prtd->dmacfg.src_prph = 0; + prtd->dmacfg.dst_size = 4; + prtd->dmacfg.dst_inc = 0; + prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4; + prtd->dmacfg.dst_ahb1 = 0; +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S1_DMA1); +#else + prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S0_DMA1); +#endif + prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_M2P; + if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_tx", + &lpc3xxx_pcm_dma_irq, substream) < 0) { + pr_debug(KERN_ERR "Error setting up I2S TX DMA channel\n"); + return -ENODEV; + } + + /* Allocate a linked list for audio buffers */ + prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS); + if (prtd->llptr == 0) { + lpc32xx_dma_ch_put(prtd->dmach); + prtd->dmach = -1; + pr_debug(KERN_ERR "Error allocating list buffer (I2S TX)\n"); + return -ENOMEM; + } + } + else { + prtd->dmach = DMA_CH_I2S_RX; + prtd->dmacfg.ch = DMA_CH_I2S_RX; + prtd->dmacfg.tc_inten = 1; + prtd->dmacfg.err_inten = 1; + prtd->dmacfg.src_size = 4; + prtd->dmacfg.src_inc = 0; + prtd->dmacfg.src_ahb1 = 1; + prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4; +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S1_DMA0); +#else + prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S0_DMA0); +#endif + prtd->dmacfg.dst_size = 4; + prtd->dmacfg.dst_inc = 1; + prtd->dmacfg.dst_ahb1 = 0; + prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4; + prtd->dmacfg.dst_prph = 0; + prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_P2M; + if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_rx", + &lpc3xxx_pcm_dma_irq, substream) < 0) { + pr_debug(KERN_ERR "Error setting up I2S RX DMA channel\n"); + return -ENODEV; + } + + /* Allocate a linked list for audio buffers */ + prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS); + if (prtd->llptr == 0) { + lpc32xx_dma_ch_put(prtd->dmach); + prtd->dmach = -1; + pr_debug(KERN_ERR "Error allocating list buffer (I2S RX)\n"); + return -ENOMEM; + } + } + } + + return 0; +} + +static int lpc3xxx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_pcm_runtime *rtd = substream->runtime; + struct lpc3xxx_dma_data *prtd = rtd->private_data; + int i, ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + prtd->period_ptr = prtd->dma_cur = prtd->dma_buffer; + lpc32xx_dma_flush_llist(prtd->dmach); + + /* Queue a few buffers to start DMA */ + for (i = 0; i < NUMLINKS; i++) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + lpc32xx_dma_queue_llist_entry(prtd->dmach, (void *) prtd->period_ptr, +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + (void *) I2S_TX_FIFO(LPC32XX_I2S1_BASE), +#else + (void *) I2S_TX_FIFO(LPC32XX_I2S0_BASE), +#endif + prtd->period_size); + } + else { + lpc32xx_dma_queue_llist_entry(prtd->dmach, +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + (void *) I2S_RX_FIFO(LPC32XX_I2S1_BASE), +#else + (void *) I2S_RX_FIFO(LPC32XX_I2S0_BASE), +#endif + (void *) prtd->period_ptr, prtd->period_size); + + } + + prtd->period_ptr += prtd->period_size; + } + break; + + case SNDRV_PCM_TRIGGER_STOP: + lpc32xx_dma_flush_llist(prtd->dmach); + lpc32xx_dma_ch_disable(prtd->dmach); + break; + + case SNDRV_PCM_TRIGGER_SUSPEND: + break; + + case SNDRV_PCM_TRIGGER_RESUME: + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + lpc32xx_dma_ch_pause_unpause(prtd->dmach, 1); + break; + + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + lpc32xx_dma_ch_pause_unpause(prtd->dmach, 0); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static snd_pcm_uframes_t lpc3xxx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lpc3xxx_dma_data *prtd = runtime->private_data; + snd_pcm_uframes_t x; + + /* Return an offset into the DMA buffer for the next data */ + x = bytes_to_frames(runtime, (prtd->dma_cur - runtime->dma_addr)); + if (x >= runtime->buffer_size) + x = 0; + + return x; +} + +static int lpc3xxx_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lpc3xxx_dma_data *prtd; + int ret = 0; + + snd_soc_set_runtime_hwparams(substream, &lpc3xxx_pcm_hardware); + + /* ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + goto out; + + prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + if (prtd == NULL) { + ret = -ENOMEM; + goto out; + } + runtime->private_data = prtd; + prtd->dmach = -1; + +out: + return ret; +} + +static int lpc3xxx_pcm_close(struct snd_pcm_substream *substream) +{ + struct lpc3xxx_dma_data *prtd = substream->runtime->private_data; + + kfree(prtd); + return 0; +} + +static int lpc3xxx_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops lpc3xxx_pcm_ops = { + .open = lpc3xxx_pcm_open, + .close = lpc3xxx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = lpc3xxx_pcm_hw_params, + .hw_free = lpc3xxx_pcm_hw_free, + .prepare = lpc3xxx_pcm_prepare, + .trigger = lpc3xxx_pcm_trigger, + .pointer = lpc3xxx_pcm_pointer, + .mmap = lpc3xxx_pcm_mmap, +}; + +/* + * ASoC platform driver + */ +static int lpc3xxx_pcm_new(struct snd_card *card, + struct snd_soc_dai *dai, + struct snd_pcm *pcm) +{ + int ret = 0; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &lpc3xxx_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->playback.channels_min) { + ret = lpc3xxx_pcm_allocate_dma_buffer( + pcm, SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->capture.channels_min) { + pr_debug("%s: Allocating PCM capture DMA buffer\n", SND_NAME); + ret = lpc3xxx_pcm_allocate_dma_buffer( + pcm, SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } + +out: + return ret; +} + +static void lpc3xxx_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (substream == NULL) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + + buf->area = NULL; + } +} + +#if defined(CONFIG_PM) +static int lpc3xxx_pcm_suspend(struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = dai->runtime; + struct lpc3xxx_dma_data *prtd; + + if (runtime == NULL) + return 0; + + prtd = runtime->private_data; + + /* Enable the DMA channel */ + lpc32xx_dma_ch_enable(prtd->dmach); + + return 0; +} + +static int lpc3xxx_pcm_resume(struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = dai->runtime; + struct lpc3xxx_dma_data *prtd; + + if (runtime == NULL) + return 0; + + prtd = runtime->private_data; + + /* Disable the DMA channel */ + lpc32xx_dma_ch_disable(prtd->dmach); + + return 0; +} + +#else +#define lpc3xxx_pcm_suspend NULL +#define lpc3xxx_pcm_resume NULL +#endif + +struct snd_soc_platform lpc3xxx_soc_platform = { + .name = SND_NAME, + .pcm_ops = &lpc3xxx_pcm_ops, + .pcm_new = lpc3xxx_pcm_new, + .pcm_free = lpc3xxx_pcm_free_dma_buffers, + .suspend = lpc3xxx_pcm_suspend, + .resume = lpc3xxx_pcm_resume, +}; +EXPORT_SYMBOL_GPL(lpc3xxx_soc_platform); + +static int __init lpc3xxx_soc_platform_init(void) +{ + return snd_soc_register_platform(&lpc3xxx_soc_platform); +} +module_init(lpc3xxx_soc_platform_init); + +static void __exit lpc3xxx_soc_platform_exit(void) +{ + snd_soc_unregister_platform(&lpc3xxx_soc_platform); +} +module_exit(lpc3xxx_soc_platform_exit) + +MODULE_AUTHOR("Kevin Wells "); +MODULE_DESCRIPTION("NXP LPC3XXX PCM module"); +MODULE_LICENSE("GPL"); diff -purN linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-pcm.h linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-pcm.h --- linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-pcm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-pcm.h 2010-10-15 14:10:00.138525452 +0100 @@ -0,0 +1,29 @@ +/* + * sound/soc/lpc3xxx/lpc3xxx-pcm.h + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SOUND_SOC_LPC3XXX_PCM_H +#define __SOUND_SOC_LPC3XXX_PCM_H + +extern struct snd_soc_platform lpc3xxx_soc_platform; + +#endif + diff -purN linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-uda1380.c linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-uda1380.c --- linux-2.6.34/sound/soc/lpc3xxx/lpc3xxx-uda1380.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/lpc3xxx-uda1380.c 2010-10-15 14:10:00.138525452 +0100 @@ -0,0 +1,222 @@ +/* + * sound/soc/lpc3xxx/lpc3xxx-uda1380.c + * + * Author: Kevin Wells + * + * Copyright (C) 2008 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../codecs/uda1380.h" +#include "lpc3xxx-pcm.h" +#include "lpc3xxx-i2s.h" + +#define SND_MODNAME "lpc3xxx_uda1380" + +static int phy3250_uda1380_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 fmt = SND_SOC_DAIFMT_I2S; + int ret; + + /* The perspective is from the CODEC side, so slave mode means that + the i2s interface is the master. For the UDA1380 and playback, + the CODEC is always a slave and i2s is always a master. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + fmt |= SND_SOC_DAIFMT_CBS_CFS; + } + else { + +#if defined(CONFIG_SND_LPC32XX_USEI2S_SLAVE_MODERX) + fmt |= SND_SOC_DAIFMT_CBM_CFM; +#else + fmt |= SND_SOC_DAIFMT_CBS_CFS; +#endif + } + + /* Set the CPU I2S rate clock (first) */ + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, params_rate(params), + SND_SOC_CLOCK_OUT); + if (ret < 0) { + pr_warning("%s: " + "Failed to set I2S clock (%d)\n", + SND_MODNAME, ret); + return ret; + } + + /* Set CPU and CODEC DAI format */ + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_warning("%s: " + "Failed to set CPU DAI format (%d)\n", + SND_MODNAME, ret); + return ret; + } + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) { + pr_warning("%s: " + "Failed to set CODEC DAI format (%d)\n", + SND_MODNAME, ret); + return ret; + } + + return 0; +} + +static struct snd_soc_ops phy3250_uda1380_ops = { + .hw_params = phy3250_uda1380_hw_params, +}; + +static const struct snd_soc_dapm_widget phy3250_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), +}; + +static const struct snd_soc_dapm_route intercon[] = { + /* Headphone connected to VOUTRHP, VOUTLHP */ + {"Headphone Jack", NULL, "VOUTRHP"}, + {"Headphone Jack", NULL, "VOUTLHP"}, + + /* Line Out connected to VOUTR, VOUTL */ + {"Line Out", NULL, "VOUTR"}, + {"Line Out", NULL, "VOUTL"}, + + /* Mic connected to VINM */ + {"VINM", NULL, "Mic Jack"}, + + /* Line In connected to VINR, VINL */ + {"VINL", NULL, "Line In"}, + {"VINR", NULL, "Line In"}, +}; + +static int phy3250_uda1380_init(struct snd_soc_codec *codec) +{ + /* Add widgets */ + snd_soc_dapm_new_controls(codec, phy3250_dapm_widgets, + ARRAY_SIZE(phy3250_dapm_widgets)); + + /* Set up davinci-evm specific audio path audio_map */ + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + + /* Always connected pins */ + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Line Out"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Line In"); + + snd_soc_dapm_sync(codec); + + return 0; +} + +static struct snd_soc_dai_link phy3250_uda1380_dai[] = { +{ + .name = "UDA1380", + .stream_name = "UDA1380", +#if defined(CONFIG_SND_LPC32XX_USEI2S1) + .cpu_dai = &lpc3xxx_i2s_dai[1], +#else + .cpu_dai = &lpc3xxx_i2s_dai[0], +#endif + .codec_dai = &uda1380_dai[UDA1380_DAI_DUPLEX], + .init = phy3250_uda1380_init, + .ops = &phy3250_uda1380_ops, +}, +}; + +static struct snd_soc_card phy3250_snd_soc_card = { + .name = "LPC32XX", + .platform = &lpc3xxx_soc_platform, + .dai_link = &phy3250_uda1380_dai[0], + .num_links = ARRAY_SIZE(phy3250_uda1380_dai), +}; + +static struct snd_soc_device phy3250_uda1380_snd_devdata = { + .card = &phy3250_snd_soc_card, + .codec_dev = &soc_codec_dev_uda1380, +}; + +static struct platform_device *phy3250_snd_device; +static int __init phy3250_asoc_init(void) +{ + int ret = 0; + + /* + * Create and register platform device + */ + phy3250_snd_device = platform_device_alloc("soc-audio", 0); + if (phy3250_snd_device == NULL) { + return -ENOMEM; + } + + platform_set_drvdata(phy3250_snd_device, &phy3250_uda1380_snd_devdata); + phy3250_uda1380_snd_devdata.dev = &phy3250_snd_device->dev; + + ret = platform_device_add(phy3250_snd_device); + if (ret) { + pr_warning("%s: platform_device_add failed (%d)\n", + SND_MODNAME, ret); + goto err_device_add; + } + + return 0; + +err_device_add: + if (phy3250_snd_device != NULL) { + platform_device_put(phy3250_snd_device); + phy3250_snd_device = NULL; + } + + return ret; +} + +static void __exit phy3250_asoc_exit(void) +{ + platform_device_unregister(phy3250_snd_device); + phy3250_snd_device = NULL; +} + +module_init(phy3250_asoc_init); +module_exit(phy3250_asoc_exit); + +MODULE_AUTHOR("Kevin Wells "); +MODULE_DESCRIPTION("ASoC machine driver for LPC3XXX/UDA1380"); +MODULE_LICENSE("GPL"); diff -purN linux-2.6.34/sound/soc/lpc3xxx/Makefile linux-2.6.34-dev/sound/soc/lpc3xxx/Makefile --- linux-2.6.34/sound/soc/lpc3xxx/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/lpc3xxx/Makefile 2010-10-15 14:10:00.128530188 +0100 @@ -0,0 +1,10 @@ +# LPC3XXX Platform Support +snd-soc-lpc3xxx-objs := lpc3xxx-pcm.o +snd-soc-lpc3xxx-i2s-objs := lpc3xxx-i2s.o + +obj-$(CONFIG_SND_LPC3XXX_SOC) += snd-soc-lpc3xxx.o snd-soc-lpc3xxx-i2s.o + +# LPC3XXX Machine Support +snd-soc-lpc3xxx-uda1380-objs := lpc3xxx-uda1380.o + +obj-$(CONFIG_SND_LPC3XXX_SOC_I2S_UDA1380) += snd-soc-lpc3xxx-uda1380.o diff -purN linux-2.6.34/sound/soc/Makefile linux-2.6.34-dev/sound/soc/Makefile --- linux-2.6.34/sound/soc/Makefile 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/Makefile 2010-10-15 14:10:00.128530188 +0100 @@ -14,3 +14,4 @@ obj-$(CONFIG_SND_SOC) += s3c24xx/ obj-$(CONFIG_SND_SOC) += s6000/ obj-$(CONFIG_SND_SOC) += sh/ obj-$(CONFIG_SND_SOC) += txx9/ +obj-$(CONFIG_SND_SOC) += lpc3xxx/ diff -purN linux-2.6.34/sound/soc/soc-core.c linux-2.6.34-dev/sound/soc/soc-core.c --- linux-2.6.34/sound/soc/soc-core.c 2010-05-16 22:17:36.000000000 +0100 +++ linux-2.6.34-dev/sound/soc/soc-core.c 2010-10-15 14:10:00.138525452 +0100 @@ -58,7 +58,7 @@ static int snd_soc_unregister_card(struc * It can be used to eliminate pops between different playback streams, e.g. * between two audio tracks. */ -static int pmdown_time = 5000; +static int pmdown_time = 500; module_param(pmdown_time, int, 0); MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");