aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-2.6.33
diff options
context:
space:
mode:
authorLeon Woestenberg <leon@sidebranch.com>2011-01-27 21:03:15 +0100
committerLeon Woestenberg <leon@sidebranch.com>2011-01-27 21:03:15 +0100
commit9b5df85143a13d43ea64ae2321f6bf388c1395bd (patch)
tree8a844fdb122dd02906192cf1e6a3dad95e008792 /recipes/linux/linux-2.6.33
parent7298be1f35f88c4646a47a59e2ac96e5efa5b39a (diff)
downloadopenembedded-9b5df85143a13d43ea64ae2321f6bf388c1395bd.tar.gz
adb4000.conf: New machine, kernel and u-boot support.
STK ADB4000 is a development board with a SAM9G45 SODIMM CPU module. These patches are from the manufacturer (In-Circuit). Resulting kernel boots on the board. Signed-off-by: Leon Woestenberg <leon@sidebranch.com>
Diffstat (limited to 'recipes/linux/linux-2.6.33')
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/defconfig1745
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0001-misc-fpga_sram-added-driver-for-a-memory-connected-F.patch359
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0002-tfp410-added-driver-for-tfp410-DVI-Controller.patch270
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0003-drivers-at91_mci-modified-MMC-Host-to-work-on-G45.patch572
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0004-.gitignore-ignore-arm-image-output.patch21
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0005-arm-mach-at91-Add-support-for-icnova-boards.patch1357
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0006-ICnova-Add-support-for-ADB1004revB-and-5In-Displays.patch289
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0007-atmel_tsadcc-adding-support-for-pressure-measurement.patch215
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0008-atmel_serial-adding-support-for-RS485.patch500
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0009-ICnova-add-support-for-ADB3000-revB.patch117
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0010-atmel-pwm-Making-driver-selectable-for-SAM9G45.patch26
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0011-hwmon-atm_pwm-adding-new-Userspace-atmel-pwm-interfa.patch300
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0012-ICnova-configuring-the-buzzer.patch38
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0013-sound-soc-adding-ssm2603-attached-to-atmel-ssc.patch337
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0014-ICnova-ADB1000-Adding-BPP-to-16.patch27
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0015-ADS7846-Adding-option-to-support-fuzz-on-input.patch47
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0016-ADB4000-Adding-support-for-the-IO-Processor.patch1785
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0017-AT91-raising-the-number-of-GPIOs-to-support-addition.patch25
-rw-r--r--recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0018-ICnova-Adding-ADB4000.patch448
19 files changed, 8478 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.33/adb4000/defconfig b/recipes/linux/linux-2.6.33/adb4000/defconfig
new file mode 100644
index 0000000000..3df5b86d87
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/defconfig
@@ -0,0 +1,1745 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33
+# Thu Jan 27 17:47:10 2011
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_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 is not set
+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 is not set
+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 is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# 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
+
+#
+# Kernel Performance Events And Counters
+#
+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
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# 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=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# 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=y
+# 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_NOMADIK 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_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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_HAVE_AT91_USART3=y
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9G10 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+CONFIG_ARCH_AT91SAM9G45=y
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9G45 Board Type
+#
+# CONFIG_MACH_AT91SAM9G45EKES is not set
+# CONFIG_MACH_ICNOVA_ADB1000 is not set
+# CONFIG_MACH_ICNOVA_ADB1002 is not set
+# CONFIG_MACH_ICNOVA_ADB1004 is not set
+# CONFIG_MACH_ICNOVA_ADB3000 is not set
+CONFIG_MACH_ICNOVA_ADB4000=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 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
+
+#
+# Bus support
+#
+# 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 is not set
+# 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_LEDS=y
+CONFIG_LEDS_CPU=y
+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=" debug "
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+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_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=y
+# 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=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=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER 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=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+# CONFIG_CFG80211_DEFAULT_PS is not set
+# CONFIG_CFG80211_DEBUGFS is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+CONFIG_LIB80211_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+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_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 is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# 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=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# 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=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+# CONFIG_SPI_COMM is not set
+# CONFIG_SUPERVISOR_ATOI is not set
+# CONFIG_FPGA_SRAM is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_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=y
+# 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_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_COMMON=m
+# CONFIG_ATH_DEBUG is not set
+CONFIG_AR9170_USB=m
+CONFIG_AR9170_LEDS=y
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800_LIB=m
+CONFIG_RT2X00_LIB_USB=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_HT=y
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+# CONFIG_RT2X00_DEBUG is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW 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_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=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# 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 is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 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=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+CONFIG_MOUSE_GPIO=y
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C 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_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_ATMEL_TSADCC is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+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 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# 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:
+#
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+CONFIG_W1_MASTER_GPIO=y
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+CONFIG_HAVE_FB_ATMEL=y
+# 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_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+# CONFIG_BACKLIGHT_GENERIC 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=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+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 is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED 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 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_BERRY_CHARGE 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_SISUSBVGA 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_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=m
+# 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_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE 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=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# 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_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# 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
+#
+
+#
+# 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_AT91SAM9=m
+CONFIG_RTC_DRV_AT91SAM9_RTT=0
+CONFIG_RTC_DRV_AT91SAM9_GPBR=0
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_AT_HDMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+CONFIG_ASYNC_TX_DMA=y
+# CONFIG_DMATEST 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=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_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 is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# 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=y
+# 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=y
+# 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_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG 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_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# 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 is not set
+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=y
+# 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=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=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 is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# 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=y
+# 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=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0001-misc-fpga_sram-added-driver-for-a-memory-connected-F.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0001-misc-fpga_sram-added-driver-for-a-memory-connected-F.patch
new file mode 100644
index 0000000000..f7238837c5
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0001-misc-fpga_sram-added-driver-for-a-memory-connected-F.patch
@@ -0,0 +1,359 @@
+From 8e60a6bc5c5fb74ed5d42a1f72d1847385b84a29 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 11:35:36 +0100
+Subject: [PATCH 01/18] [misc/fpga_sram] added driver for a memory-connected FPGA
+
+The ICnova SAM9G45+XC700AN OEM has a FPGA connected to the
+ARM-Chip via the Memory Interface. This driver can be used to
+communicate on the ARM-Site.
+---
+ drivers/misc/Kconfig | 6 +
+ drivers/misc/Makefile | 1 +
+ drivers/misc/fpga_sram.c | 309 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 316 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/misc/fpga_sram.c
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index e3551d2..072c8a4 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -297,4 +297,10 @@ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+ source "drivers/misc/iwmc3200top/Kconfig"
+
++config FPGA_SRAM
++ tristate "FPGA-SRAM Interface"
++ help
++ Enable this if you need a SRAM-like interface somewhere in your
++ mapping.
++
+ endif # MISC_DEVICES
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 049ff24..61fe337 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -26,5 +26,6 @@ obj-$(CONFIG_DS1682) += ds1682.o
+ obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
+ obj-$(CONFIG_C2PORT) += c2port/
+ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
++obj-$(CONFIG_FPGA_SRAM) += fpga_sram.o
+ obj-y += eeprom/
+ obj-y += cb710/
+diff --git a/drivers/misc/fpga_sram.c b/drivers/misc/fpga_sram.c
+new file mode 100644
+index 0000000..ca98598
+--- /dev/null
++++ b/drivers/misc/fpga_sram.c
+@@ -0,0 +1,309 @@
++/*
++ * main.c -- the bare fpga_sram char module
++ *
++ * Based on scull
++ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
++ * Copyright (C) 2001 O'Reilly & Associates
++ *
++ * The source code in this file can be freely used, adapted,
++ * and redistributed in source or binary form, so long as an
++ * acknowledgment appears in derived source files. The citation
++ * should list that the code comes from the book "Linux Device
++ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
++ * by O'Reilly & Associates. No warranty is attached;
++ * we cannot take responsibility for errors or fitness for use.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++
++#include <linux/kernel.h> /* printk() */
++#include <linux/slab.h> /* kmalloc() */
++#include <linux/fs.h> /* everything... */
++#include <linux/errno.h> /* error codes */
++#include <linux/types.h> /* size_t */
++#include <linux/proc_fs.h>
++#include <linux/fcntl.h> /* O_ACCMODE */
++#include <linux/seq_file.h>
++#include <linux/cdev.h>
++
++#include <asm/system.h> /* cli(), *_flags */
++#include <asm/uaccess.h> /* copy_*_user */
++
++#define FPGA_MAJOR 0
++#define FPGA_NR_DEVS 1
++
++
++struct fpga_sram_drv;
++
++struct fpga_sram_dev {
++ struct fpga_sram_drv *drv;
++ struct cdev cdev;
++};
++
++struct fpga_sram_drv {
++ struct fpga_sram_dev *devices;
++ void *start;
++ int size;
++ int major;
++ int devs;
++};
++
++static int fpga_sram_major = FPGA_MAJOR;
++static int fpga_sram_minor = 0;
++static int fpga_sram_nr_devs = FPGA_NR_DEVS;
++
++module_param(fpga_sram_major, int, S_IRUGO);
++module_param(fpga_sram_minor, int, S_IRUGO);
++//module_param(fpga_sram_nr_devs, int, S_IRUGO);
++
++MODULE_AUTHOR("Benjamin Tietz");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/*
++ * Open and close
++ */
++
++static int fpga_sram_open(struct inode *inode, struct file *filp)
++{
++ struct fpga_sram_dev *dev; /* device information */
++
++ dev = container_of(inode->i_cdev, struct fpga_sram_dev, cdev);
++
++ filp->private_data = dev; /* for other methods */
++
++ return 0; /* success */
++}
++
++static int fpga_sram_release(struct inode *inode, struct file *filp)
++{
++ return 0;
++}
++
++/*
++ * Data management: read and write
++ */
++
++static ssize_t fpga_sram_read(struct file *filp, char __user *buf,
++ size_t count, loff_t *f_pos)
++{
++ struct fpga_sram_dev *dev = filp->private_data;
++ ssize_t res;
++
++ if((count + *f_pos) > dev->drv->size) count = dev->drv->size - *f_pos;
++ if(( res = copy_to_user(buf, dev->drv->start + *f_pos, count)) < 0)
++ return res;
++ return count;
++}
++
++static ssize_t fpga_sram_write(struct file *filp, const char __user *buf,
++ size_t count, loff_t *f_pos)
++{
++ struct fpga_sram_dev *dev = filp->private_data;
++ ssize_t res;
++
++ if((count + *f_pos) > dev->drv->size) count = dev->drv->size - *f_pos;
++ if(( res = copy_from_user(dev->drv->start + *f_pos, buf, count)) < 0)
++ return res;
++ return count;
++}
++
++/*
++ * The "extended" operations -- only seek
++ */
++
++static loff_t fpga_sram_llseek(struct file *filp, loff_t off, int whence)
++{
++ struct fpga_sram_dev *dev = filp->private_data;
++ loff_t newpos;
++
++ switch(whence) {
++ case 0: /* SEEK_SET */
++ newpos = off;
++ break;
++
++ case 1: /* SEEK_CUR */
++ newpos = filp->f_pos + off;
++ break;
++
++ case 2: /* SEEK_END */
++ newpos = dev->drv->size + off;
++ break;
++
++ default: /* can't happen */
++ return -EINVAL;
++ }
++ if ( newpos >= dev->drv->size) return -EINVAL;
++ if (newpos < 0) return -EINVAL;
++ filp->f_pos = newpos;
++ return newpos;
++}
++
++
++
++static struct file_operations fpga_sram_fops = {
++ .owner = THIS_MODULE,
++ .llseek = fpga_sram_llseek,
++ .read = fpga_sram_read,
++ .write = fpga_sram_write,
++ .open = fpga_sram_open,
++ .release = fpga_sram_release,
++};
++
++/*
++ * Finally, the module stuff
++ */
++
++/*
++ * The cleanup function is used to handle initialization failures as well.
++ * Thefore, it must be careful to work correctly even if some of the items
++ * have not been initialized
++ */
++static int __exit fpga_sram_destroy(struct platform_device *pdev)
++{
++ int i;
++ struct fpga_sram_drv *drv = platform_get_drvdata(pdev);
++ dev_t devno = MKDEV(drv->major, fpga_sram_minor);
++
++ /* Get rid of our char dev entries */
++ if(drv->devices) {
++ for (i = 0; i < drv->devs; i++) {
++ cdev_del(&drv->devices[i].cdev);
++ }
++ kfree(drv->devices);
++ }
++
++ /* cleanup_module is never called if registering failed */
++ unregister_chrdev_region(devno, drv->devs);
++ kfree(drv->devices);
++
++ return 0;
++}
++
++
++/*
++ * Set up the char_dev structure for this device.
++ */
++static void fpga_sram_setup_cdev(struct fpga_sram_dev *dev, int index)
++{
++ int err, devno = MKDEV(dev->drv->major, fpga_sram_minor + index);
++
++ cdev_init(&dev->cdev, &fpga_sram_fops);
++ dev->cdev.owner = THIS_MODULE;
++ dev->cdev.ops = &fpga_sram_fops;
++ err = cdev_add (&dev->cdev, devno, 1);
++ /* Fail gracefully if need be */
++ if (err)
++ pr_info("Error %d adding fpga_sram%d", err, index);
++}
++
++
++static int fpga_sram_probe(struct platform_device *pdev)
++{
++ struct fpga_sram_drv *drv;
++ struct resource *fmem;
++
++ dev_t dev = 0;
++ int result;
++ int i;
++
++ /*
++ * allocate the devices -- we can't have them static, as the number
++ * can be specified at load time
++ */
++ drv = kzalloc(sizeof(*drv), GFP_KERNEL);
++ if(!drv) {
++ result = -ENOMEM;
++ goto drv_mem_err;
++ }
++ drv->devs = fpga_sram_nr_devs;
++
++ drv->devices = kzalloc(drv->devs * sizeof(*drv->devices), GFP_KERNEL);
++ if (!drv->devices) {
++ result = -ENOMEM;
++ goto dev_mem_err; /* Make this more graceful */
++ }
++
++ platform_set_drvdata(pdev, drv);
++
++ /*
++ * Get a range of minor numbers to work with, asking for a dynamic
++ * major unless directed otherwise at load time.
++ */
++ if (fpga_sram_major) {
++ dev = MKDEV(fpga_sram_major, fpga_sram_minor);
++ result = register_chrdev_region(dev, drv->devs, "fpga_sram");
++ drv->major = fpga_sram_major;
++ } else {
++ result = alloc_chrdev_region(&dev, fpga_sram_minor,
++ drv->devs, "fpga_sram");
++ drv->major = MAJOR(dev);
++ }
++ if (result < 0) {
++ dev_warn(&pdev->dev, "can't get major %d\n", fpga_sram_major);
++ goto major_err;
++ }
++
++ fmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if(!fmem) {
++ result = -ENXIO;
++ dev_warn(&pdev->dev, "No memory to work with\n");
++ goto res_err;
++ }
++
++ drv->size = fmem->end - fmem->start + 1;
++
++#if 0
++ if(!request_mem_region(fmem->start, drv->size, "fpga_sram")) {
++ dev_warn(&pdev->dev, "can't request mem_region");
++ goto res_err;
++ }
++#endif
++
++ drv->start = ioremap(fmem->start, drv->size);
++ if(!drv->start) {
++ dev_warn(&pdev->dev, "Can't allocate resource (%i)\n", result);
++ goto res_err;
++ }
++
++ for(i=0; i< drv->devs; i++) {
++ drv->devices[i].drv = drv;
++ fpga_sram_setup_cdev(&drv->devices[i], i);
++ }
++
++ return 0; /* succeed */
++
++ release_mem_region(fmem->start, drv->size);
++res_err:
++ unregister_chrdev_region(dev, drv->devs);
++major_err:
++ kfree(drv->devices);
++dev_mem_err:
++ kfree(drv);
++drv_mem_err:
++ return result;
++}
++
++static struct platform_driver fpga_sram_driver = {
++ .driver = {
++ .name = "fpga_sram",
++ .owner = THIS_MODULE,
++ },
++ .remove = __exit_p(fpga_sram_destroy),
++};
++
++static int __init fpga_sram_init_module(void) {
++ return platform_driver_probe(&fpga_sram_driver, fpga_sram_probe);
++}
++
++static void __exit fpga_sram_cleanup_module(void) {
++ platform_driver_unregister(&fpga_sram_driver);
++}
++
++module_init(fpga_sram_init_module);
++module_exit(fpga_sram_cleanup_module);
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0002-tfp410-added-driver-for-tfp410-DVI-Controller.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0002-tfp410-added-driver-for-tfp410-DVI-Controller.patch
new file mode 100644
index 0000000000..172c246b02
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0002-tfp410-added-driver-for-tfp410-DVI-Controller.patch
@@ -0,0 +1,270 @@
+From 29e785edcbd8e97eadc37bfbb7e22a66c3bbac6d Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 12:42:21 +0100
+Subject: [PATCH 02/18] [tfp410] added driver for tfp410 DVI-Controller
+
+This chip can be configured via I2C.
+Currently the gpio is coded into this driver.
+---
+ drivers/video/backlight/Kconfig | 6 +
+ drivers/video/backlight/Makefile | 1 +
+ drivers/video/backlight/tfp410.c | 218 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 225 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/video/backlight/tfp410.c
+
+diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
+index 09bfa96..acf8a64 100644
+--- a/drivers/video/backlight/Kconfig
++++ b/drivers/video/backlight/Kconfig
+@@ -91,6 +91,12 @@ config LCD_TOSA
+ If you have an Sharp SL-6000 Zaurus say Y to enable a driver
+ for its LCD.
+
++config LCD_TFP410
++ tristate "TFP410 support"
++ depends on LCD_CLASS_DEVICE && I2C
++ default n
++
++
+ config LCD_HP700
+ tristate "HP Jornada 700 series LCD Driver"
+ depends on LCD_CLASS_DEVICE
+diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
+index 9a40554..846c2cc 100644
+--- a/drivers/video/backlight/Makefile
++++ b/drivers/video/backlight/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
+ obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
+ obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
+ obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
++obj-$(CONFIG_LCD_TFP410) += tfp410.o
+
+ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
+ obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
+diff --git a/drivers/video/backlight/tfp410.c b/drivers/video/backlight/tfp410.c
+new file mode 100644
+index 0000000..347a700
+--- /dev/null
++++ b/drivers/video/backlight/tfp410.c
+@@ -0,0 +1,218 @@
++/*
++ * Driver for the TFP410 DVI-Chip
++ *
++ * This currently just enables the chip
++ *
++ */
++
++#include <linux/i2c.h>
++#include <linux/sysfs.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/delay.h>
++#include <mach/gpio.h>
++
++#define TFP_VEN_ID 0x00
++#define TFP_VEN_ID1 0x01
++#define TFP_VEN_ID_TFP 0x014C
++#define TFP_DEV_ID 0x02
++#define TFP_DEV_ID1 0x03
++#define TFP_DEV_ID_TFP 0x0410
++#define TFP_REV_ID 0x04
++#define TFP_CTL1 0x08
++#define TFP_CTL1_nPD (1<<0)
++#define TFP_CTL1_EDGE (1<<1)
++#define TFP_CTL1_BSEL (1<<2)
++#define TFP_CTL1_DSEL (1<<3)
++#define TFP_CTL1_HEN (1<<4)
++#define TFP_CTL1_VEN (1<<5)
++#define TFP_CTL1_TDIS (1<<6)
++#define TFP_CTL2 0x09
++#define TFP_CTL2_MDI (1<<0)
++#define TFP_CTL2_HTPLG (1<<1)
++#define TFP_CTL2_RSEN (1<<2)
++#define TFP_CTL2_TSEL (1<<3)
++#define TFP_CTL2_MSEL(x) ((x)<<4)
++#define TFP_MSEL_DIS 0x00
++#define TFP_MSEL_MDI 0x01
++#define TFP_MSEL_RSEN 0x02
++#define TFP_MSEL_HTPLG 0x03
++#define TFP_CTL2_VLOW (1<<7)
++#define TFP_CTL3 0x0A
++#define TFP_CTL3_CTL(x) ((x)<<1)
++#define TFP_CTL3_DKEN (1<<4)
++#define TFP_CTL3_DK(x) ((x)<<5)
++#define TFP_CFG 0x0B
++#define TFP_DE_DLY 0x32
++#define TFP_DE_CTL 0x33
++#define TFP_DE_CTL_DLY8 (1<<0)
++#define TFP_DE_CTL_HS_POL (1<<4)
++#define TFP_DE_CTL_VS_POL (1<<5)
++#define TFP_DE_CTL_DE_GEN (1<<6)
++#define TFP_DE_TOP 0x34
++#define TFP_DE_CNT 0x36
++#define TFP_DE_CNT1 0x37
++#define TFP_DE_LIN 0x38
++#define TFP_DE_LIN1 0x39
++#define TFP_H_RES 0x3A
++#define TFP_H_RES1 0x3B
++#define TFP_V_RES 0x3C
++#define TFP_V_RES1 0x3D
++
++
++static inline int tfp410_write_byte(struct i2c_client *client,
++ char reg, char data) {
++ return i2c_smbus_write_byte_data(client,reg,data);
++}
++
++static inline int tfp410_write_word(struct i2c_client *client,
++ char reg, short data) {
++ int ret;
++ ret = i2c_smbus_write_byte_data(client,reg,(data & 0x00FF));
++ if(ret < 0) return ret;
++ ret = i2c_smbus_write_byte_data(client,reg+1,(data >> 8));
++ if(ret < 0) return ret;
++ return 2;
++}
++
++static inline int tfp410_write_dword(struct i2c_client *client,
++ char reg, long data) {
++ int ret;
++ ret = i2c_smbus_write_byte_data(client,reg+0,((data >> 0) & 0x00FF));
++ if(ret < 0) return ret;
++ ret = i2c_smbus_write_byte_data(client,reg+1,((data >> 8) & 0x00FF));
++ if(ret < 0) return ret;
++ ret = i2c_smbus_write_byte_data(client,reg+2,((data >> 16) & 0x00FF));
++ if(ret < 0) return ret;
++ ret = i2c_smbus_write_byte_data(client,reg+3,((data >> 24) & 0x00FF));
++ if(ret < 0) return ret;
++ return 2;
++}
++
++static inline int tfp410_read_byte(struct i2c_client *client, char reg) {
++ return i2c_smbus_read_byte_data(client, reg);
++}
++
++static inline int tfp410_read_word(struct i2c_client *client, char reg) {
++ int ret, ret2;
++
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if(ret < 0) return ret;
++ ret2 = i2c_smbus_read_byte_data(client, reg+1);
++ if(ret2 < 0) return ret2;
++ return (ret & 0x00FF) | (ret2 << 8);
++}
++
++static ssize_t dump_regs(struct device *dev, struct device_attribute *attr,
++ char *buf) {
++ struct i2c_client *client = to_i2c_client(dev);
++
++ return sprintf(buf,
++ "Vendor: %04x\nDevice: %04x\nRevision: %02x\n"
++ "CTL1: %02x\nCTL2: %02x\nCTL3: %02x\nCFG: %02x\n"
++ "DE_DLY: %04x\nDE_CTL: %02x\nDE_TOP: %02x\n"
++ "DE_CNT: %04i\nDE_LIN: %04i\n"
++ "H_RES: %04i\nV_RES: %04i\n",
++ tfp410_read_word(client, TFP_VEN_ID),
++ tfp410_read_word(client, TFP_DEV_ID),
++ tfp410_read_byte(client, TFP_REV_ID),
++ tfp410_read_byte(client, TFP_CTL1),
++ tfp410_read_byte(client, TFP_CTL2),
++ tfp410_read_byte(client, TFP_CTL3),
++ tfp410_read_byte(client, TFP_CFG),
++ tfp410_read_byte(client, TFP_DE_DLY),
++ tfp410_read_byte(client, TFP_DE_CTL),
++ tfp410_read_byte(client, TFP_DE_TOP),
++ tfp410_read_word(client, TFP_DE_CNT),
++ tfp410_read_word(client, TFP_DE_LIN),
++ tfp410_read_word(client, TFP_H_RES),
++ tfp410_read_word(client, TFP_V_RES));
++
++}
++
++static SENSOR_DEVICE_ATTR(regs, S_IRUGO, dump_regs, NULL, 0);
++
++static struct attribute *tfp410_attributes[] = {
++ &sensor_dev_attr_regs.dev_attr.attr,
++ NULL,
++};
++
++static const struct attribute_group tfp410_group = {
++ .attrs = tfp410_attributes,
++};
++
++#ifdef CONFIG_ARCH_AT91SAM9G45
++#define TFP410_RESET_PIN 65 // PB1
++#else
++#define TFP410_RESET_PIN 1 // PA1
++#endif
++
++static int tfp410_probe(struct i2c_client *client,
++ const struct i2c_device_id *dev_id) {
++ int ret = 0;
++ int reg;
++ if(!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_BYTE_DATA))
++ goto exit;
++ dev_info(&client->dev, "chip found\n");
++ gpio_request(TFP410_RESET_PIN, "tfp410.reset");
++ gpio_direction_output(TFP410_RESET_PIN, 0);
++ msleep(4);
++ gpio_set_value(TFP410_RESET_PIN, 1);
++ msleep(4);
++ reg = tfp410_read_word(client, TFP_VEN_ID);
++ if(reg != TFP_VEN_ID_TFP) {
++ dev_warn(&client->dev, "VID doesn't match %04x vs. %04x\n",
++ reg, TFP_VEN_ID_TFP);
++ goto exit;
++ }
++ // Init the chip
++ tfp410_write_byte(client, TFP_CTL1,
++ (TFP_CTL1_nPD | tfp410_read_byte(client, TFP_CTL1))
++ & ~TFP_CTL1_TDIS);
++ tfp410_write_byte(client, TFP_DE_CTL,0
++ |TFP_DE_CTL_VS_POL|TFP_DE_CTL_HS_POL
++ );
++ ret = sysfs_create_group(&client->dev.kobj, &tfp410_group);
++ if(ret) goto exit;
++
++
++ return 0;
++
++ sysfs_remove_group(&client->dev.kobj, &tfp410_group);
++exit:
++ return ret;
++}
++
++static int __devexit tfp410_remove(struct i2c_client *client) {
++ sysfs_remove_group(&client->dev.kobj, &tfp410_group);
++ return 0;
++}
++
++static const struct i2c_device_id tfp410_id[] = {
++ { "tfp410", 0x3F },
++ {},
++};
++
++static struct i2c_driver tfp410_driver = {
++ .driver = {
++ .name = "tfp410",
++ },
++ .probe = tfp410_probe,
++ .remove = __devexit_p(tfp410_remove),
++ .id_table = tfp410_id,
++};
++
++static int __init tfp410_init(void) {
++ return i2c_add_driver(&tfp410_driver);
++}
++module_init(tfp410_init);
++
++static void __exit tfp410_exit(void) {
++ i2c_del_driver(&tfp410_driver);
++}
++module_exit(tfp410_exit);
++
++MODULE_AUTHOR("Benjamin Tietz <benjamin.tietz@in-circuit.de>");
++MODULE_DESCRIPTION("TFP410 Display Driver");
++MODULE_LICENSE("GPL");
++
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0003-drivers-at91_mci-modified-MMC-Host-to-work-on-G45.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0003-drivers-at91_mci-modified-MMC-Host-to-work-on-G45.patch
new file mode 100644
index 0000000000..1a0c9409a8
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0003-drivers-at91_mci-modified-MMC-Host-to-work-on-G45.patch
@@ -0,0 +1,572 @@
+From a581d8cc2ec44930b697a602d22ae6a4179a8bf1 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:40:28 +0100
+Subject: [PATCH 03/18] [drivers/at91_mci] modified MMC-Host to work on G45
+
+---
+ arch/arm/mach-at91/at91sam9g45_devices.c | 170 +++++++++++++++++++++++++++-
+ arch/arm/mach-at91/include/mach/at91_mci.h | 24 ++++
+ arch/arm/mach-at91/include/mach/board.h | 8 +-
+ drivers/mmc/host/Kconfig | 2 +-
+ drivers/mmc/host/at91_mci.c | 147 ++++++++++++++++++------
+ 5 files changed, 308 insertions(+), 43 deletions(-)
+
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 809114d..c40e4cd 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -25,6 +25,8 @@
+ #include <mach/at91sam9g45_matrix.h>
+ #include <mach/at91sam9_smc.h>
+ #include <mach/at_hdmac.h>
++#include <mach/atmel-mci.h>
++#include <linux/atmel-mci.h>
+
+ #include "generic.h"
+
+@@ -276,6 +278,168 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {}
+
+
+ /* --------------------------------------------------------------------
++ * MMC / SD
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
++static u64 mmc_dmamask = DMA_BIT_MASK(32);
++static struct mci_platform_data mmc0_data, mmc1_data;
++
++static struct resource mmc0_resources[] = {
++ [0] = {
++ .start = AT91SAM9G45_BASE_MCI0,
++ .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = AT91SAM9G45_ID_MCI0,
++ .end = AT91SAM9G45_ID_MCI0,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device at91sam9g45_mmc0_device = {
++ .name = "atmel_mci",
++ .id = 0,
++ .dev = {
++ .dma_mask = &mmc_dmamask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ .platform_data = &mmc0_data,
++ },
++ .resource = mmc0_resources,
++ .num_resources = ARRAY_SIZE(mmc0_resources),
++};
++
++static struct resource mmc1_resources[] = {
++ [0] = {
++ .start = AT91SAM9G45_BASE_MCI1,
++ .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = AT91SAM9G45_ID_MCI1,
++ .end = AT91SAM9G45_ID_MCI1,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device at91sam9g45_mmc1_device = {
++ .name = "atmel_mci",
++ .id = 1,
++ .dev = {
++ .dma_mask = &mmc_dmamask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ .platform_data = &mmc1_data,
++ },
++ .resource = mmc1_resources,
++ .num_resources = ARRAY_SIZE(mmc1_resources),
++};
++
++/* Consider only one slot : slot 0 */
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
++{
++
++ if (!data)
++ return;
++
++ /* Must have at least one usable slot */
++ if (!data->slot[0].bus_width)
++ return;
++
++#if defined(CONFIG_MMC_ATMELMCI_DMA)
++ {
++ struct mci_dma_data *slave;
++
++ slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
++
++ /* DMA slave channel configuration */
++ slave->sdata.dma_dev = &at_hdmac_device.dev;
++ slave->sdata.reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
++ slave->sdata.cfg = ATC_FIFOCFG_HALFFIFO
++ | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
++ slave->sdata.ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
++ if (mmc_id == 0) /* MCI0 */
++ slave->sdata.cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
++ | ATC_DST_PER(AT_DMA_ID_MCI0);
++
++ else /* MCI1 */
++ slave->sdata.cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
++ | ATC_DST_PER(AT_DMA_ID_MCI1);
++
++ data->dma_slave = slave;
++ }
++#endif
++
++
++ /* input/irq */
++ if (data->slot[0].detect_pin) {
++ at91_set_gpio_input(data->slot[0].detect_pin, 1);
++ at91_set_deglitch(data->slot[0].detect_pin, 1);
++ }
++ if (data->slot[0].wp_pin)
++ at91_set_gpio_input(data->slot[0].wp_pin, 1);
++
++ if (mmc_id == 0) { /* MCI0 */
++
++ /* CLK */
++ at91_set_A_periph(AT91_PIN_PA0, 0);
++
++ /* CMD */
++ at91_set_A_periph(AT91_PIN_PA1, 1);
++
++ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
++ at91_set_A_periph(AT91_PIN_PA2, 1);
++ if (data->slot[0].bus_width == 4) {
++ at91_set_A_periph(AT91_PIN_PA3, 1);
++ at91_set_A_periph(AT91_PIN_PA4, 1);
++ at91_set_A_periph(AT91_PIN_PA5, 1);
++ if (data->slot[0].bus_width == 8) {
++ at91_set_A_periph(AT91_PIN_PA6, 1);
++ at91_set_A_periph(AT91_PIN_PA7, 1);
++ at91_set_A_periph(AT91_PIN_PA8, 1);
++ at91_set_A_periph(AT91_PIN_PA9, 1);
++ }
++ }
++
++ mmc0_data = *data;
++ at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk");
++ platform_device_register(&at91sam9g45_mmc0_device);
++
++ } else { /* MCI1 */
++
++ /* CLK */
++ at91_set_A_periph(AT91_PIN_PA31, 0);
++
++ /* CMD */
++ at91_set_A_periph(AT91_PIN_PA22, 1);
++
++ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
++ at91_set_A_periph(AT91_PIN_PA23, 1);
++ if (data->slot[0].bus_width == 4) {
++ at91_set_A_periph(AT91_PIN_PA24, 1);
++ at91_set_A_periph(AT91_PIN_PA25, 1);
++ at91_set_A_periph(AT91_PIN_PA26, 1);
++ if (data->slot[0].bus_width == 8) {
++ at91_set_A_periph(AT91_PIN_PA27, 1);
++ at91_set_A_periph(AT91_PIN_PA28, 1);
++ at91_set_A_periph(AT91_PIN_PA29, 1);
++ at91_set_A_periph(AT91_PIN_PA30, 1);
++ }
++ }
++
++ mmc1_data = *data;
++ at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk");
++ platform_device_register(&at91sam9g45_mmc1_device);
++
++ }
++}
++
++#else
++void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
++#endif
++
++
++/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+@@ -746,13 +910,17 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+ if (!data)
+ return;
+
+- at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
++ //at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
+
+ at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
+ at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
++#ifndef CONFIG_MACH_ICNOVA_ADB1004
++#ifndef CONFIG_MACH_ICNOVA_ADB3000
+ at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
++#endif
++#endif
+ at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
+ at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
+ at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
+diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h
+index 550d503..6cabe7d 100644
+--- a/arch/arm/mach-at91/include/mach/at91_mci.h
++++ b/arch/arm/mach-at91/include/mach/at91_mci.h
+@@ -79,6 +79,18 @@
+ #define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
+ #define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */
+
++#define AT91_MCI_CSTOR 0x08 /* Complete Signal Timeout Register */
++#define AT91_MCI_CSTOCYC (0xf << 0) /* CS Timeout Cycle Number */
++#define AT91_MCI_CSTOMUL (7 << 4) /* CS Timeout Multiplier */
++#define AT91_MCI_CSTOMUL_1 (0 << 4)
++#define AT91_MCI_CSTOMUL_16 (1 << 4)
++#define AT91_MCI_CSTOMUL_128 (2 << 4)
++#define AT91_MCI_CSTOMUL_256 (3 << 4)
++#define AT91_MCI_CSTOMUL_1K (4 << 4)
++#define AT91_MCI_CSTOMUL_4K (5 << 4)
++#define AT91_MCI_CSTOMUL_64K (6 << 4)
++#define AT91_MCI_CSTOMUL_1M (7 << 4)
++
+ #define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
+ #define AT91_MCR_RDR 0x30 /* Receive Data Register */
+ #define AT91_MCR_TDR 0x34 /* Transmit Data Register */
+@@ -103,6 +115,8 @@
+ #define AT91_MCI_RTOE (1 << 20) /* Reponse Time-out Error */
+ #define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */
+ #define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */
++#define AT91_MCI_FIFOEMPTY (1 << 26) /* FIFO Empty (g45) */
++#define AT91_MCI_XFRDONE (1 << 27) /* Transfer Done (g45) */
+ #define AT91_MCI_OVRE (1 << 30) /* Overrun */
+ #define AT91_MCI_UNRE (1 << 31) /* Underrun */
+
+@@ -110,4 +124,14 @@
+ #define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */
+ #define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */
+
++#define AT91_MCI_HSDMA 0x50 /* DMA-Register on HSMCI */
++#define AT91_MCI_OFFSET (3<<0) /* DMA Write Buffer Offset */
++#define AT91_MCI_CHKSIZE (3<<4) /* DMA Channel Read and Write Chunk Size */
++#define AT91_MCI_CHKSIZE1 (0<<4) /* DMA Channel Read and Write Chunk Size */
++#define AT91_MCI_CHKSIZE4 (1<<4) /* DMA Channel Read and Write Chunk Size */
++#define AT91_MCI_CHKSIZE8 (2<<4) /* DMA Channel Read and Write Chunk Size */
++#define AT91_MCI_CHKSIZE16 (3<<4) /* DMA Channel Read and Write Chunk Size */
++#define AT91_MCI_DMAEN (1<<8) /* DMA Hardware Handshaking Enable */
++#define AT91_MCI_ROPT (1<<12) /* Read Optimization with padding */
++
+ #endif
+diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
+index bb6f6a7..b0d0e12 100644
+--- a/arch/arm/mach-at91/include/mach/board.h
++++ b/arch/arm/mach-at91/include/mach/board.h
+@@ -39,6 +39,7 @@
+ #include <linux/usb/atmel_usba_udc.h>
+ #include <linux/atmel-mci.h>
+ #include <sound/atmel-ac97c.h>
++#include <linux/serial.h>
+
+ /* USB Device */
+ struct at91_udc_data {
+@@ -143,9 +144,10 @@ extern struct platform_device *atmel_default_console_device;
+ extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
+
+ struct atmel_uart_data {
+- short use_dma_tx; /* use transmit DMA? */
+- short use_dma_rx; /* use receive DMA? */
+- void __iomem *regs; /* virtual base address, if any */
++ short use_dma_tx; /* use transmit DMA? */
++ short use_dma_rx; /* use receive DMA? */
++ void __iomem *regs; /* virt. base address, if any */
++ struct serial_rs485 rs485; /* rs485 settings */
+ };
+ extern void __init at91_add_device_serial(void);
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index ce1d288..1454a9d 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -219,7 +219,7 @@ endchoice
+
+ config MMC_ATMELMCI_DMA
+ bool "Atmel MCI DMA support (EXPERIMENTAL)"
+- depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL
++ depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE && EXPERIMENTAL
+ help
+ Say Y here to have the Atmel MCI driver use a DMA engine to
+ do data transfers and thus increase the throughput and
+diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
+index 63924e0..90fda9e 100644
+--- a/drivers/mmc/host/at91_mci.c
++++ b/drivers/mmc/host/at91_mci.c
+@@ -53,6 +53,7 @@
+ Gets the status of the write protect pin, if available.
+ */
+
++#define DEBUG
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+@@ -268,44 +269,77 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
+ return;
+ }
+
+- for (i = 0; i < 2; i++) {
+- /* nothing left to transfer */
+- if (host->transfer_index >= data->sg_len) {
+- pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
+- break;
+- }
+-
+- /* Check to see if this needs filling */
+- if (i == 0) {
+- if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
+- pr_debug("Transfer active in current\n");
+- continue;
+- }
+- }
+- else {
+- if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
+- pr_debug("Transfer active in next\n");
+- continue;
+- }
+- }
++ if(cpu_is_at91sam9g45()) {
++ /*if(at91_mci_read(host, AT91_MCI_HSDMA) & AT91_MCI_DMAEN) {
++ pr_warning("DMA Transfer in progress\n");
++ return;
++ }*/
+
+- /* Setup the next transfer */
+ pr_debug("Using transfer index %d\n", host->transfer_index);
+
+ sg = &data->sg[host->transfer_index++];
+ pr_debug("sg = %p\n", sg);
+
++ i = 0;
++ switch(sg->length) {
++ case 1:
++ i |= AT91_MCI_CHKSIZE1;
++ break;
++ case 4:
++ i |= AT91_MCI_CHKSIZE4;
++ break;
++ case 8:
++ i |= AT91_MCI_CHKSIZE8;
++ break;
++ case 16:
++ i |= AT91_MCI_CHKSIZE16;
++ break;
++ }
++ at91_mci_write(host, AT91_MCI_HSDMA, i|AT91_MCI_DMAEN);
++
+ sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
+
+ pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
++ } else {
++ for (i = 0; i < 2; i++) {
++ /* nothing left to transfer */
++ if (host->transfer_index >= data->sg_len) {
++ pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
++ break;
++ }
+
+- if (i == 0) {
+- at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
+- at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
+- }
+- else {
+- at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
+- at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
++ /* Check to see if this needs filling */
++ if (i == 0) {
++ if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
++ pr_debug("Transfer active in current\n");
++ continue;
++ }
++ }
++ else {
++ if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
++ pr_debug("Transfer active in next\n");
++ continue;
++ }
++ }
++
++ /* Setup the next transfer */
++ pr_debug("Using transfer index %d\n", host->transfer_index);
++
++ sg = &data->sg[host->transfer_index++];
++ pr_debug("sg = %p\n", sg);
++
++ sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
++
++ pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
++
++ if (i == 0) {
++ at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
++ at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
++ }
++ else {
++ at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
++ at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
++ }
+ }
+ }
+
+@@ -358,6 +392,9 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
+
+ kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+ }
++ if (cpu_is_at91sam9g45()) {
++ at91_mci_write(host, AT91_MCI_HSDMA, 0);
++ }
+
+ flush_dcache_page(sg_page(sg));
+
+@@ -368,8 +405,13 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
+ if (host->transfer_index < data->sg_len)
+ at91_mci_pre_dma_read(host);
+ else {
+- at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
+- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
++ if(cpu_is_at91sam9g45()) {
++ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_FIFOEMPTY);
++ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_XFRDONE);
++ } else {
++ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
++ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
++ }
+ }
+
+ pr_debug("post dma read done\n");
+@@ -399,7 +441,11 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
+
+ if (cmd->data->blocks > 1) {
+ pr_debug("multiple write : wait for BLKE...\n");
+- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
++ if(cpu_is_at91sam9g45()) {
++ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_XFRDONE);
++ } else {
++ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
++ }
+ } else
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+ }
+@@ -461,7 +507,7 @@ static void at91_mci_enable(struct at91mci_host *host)
+ at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
+ mr = AT91_MCI_PDCMODE | 0x34a;
+
+- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
++ if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g45())
+ mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
+
+ at91_mci_write(host, AT91_MCI_MR, mr);
+@@ -592,7 +638,8 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
+ /*
+ * Disable the PDC controller
+ */
+- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
++ if(!cpu_is_at91sam9g45())
++ at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+
+ if (cmdr & AT91_MCI_TRCMD_START) {
+ data->bytes_xfered = 0;
+@@ -606,7 +653,11 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
+ host->total_length = 0;
+
+ at91_mci_pre_dma_read(host);
+- ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
++ if(cpu_is_at91sam9g45()) {
++ ier = AT91_MCI_FIFOEMPTY;
++ } else {
++ ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
++ }
+ }
+ else {
+ /*
+@@ -655,8 +706,13 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
+ at91_mci_write(host, AT91_MCI_CMDR, cmdr);
+
+ if (cmdr & AT91_MCI_TRCMD_START) {
+- if (cmdr & AT91_MCI_TRDIR)
+- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
++ if (cmdr & AT91_MCI_TRDIR) {
++ if(cpu_is_at91sam9g45()) {
++ //at91_mci_write(host, AT91_MCI_HSDMA, AT91_MCI_DMAEN);
++ } else {
++ at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
++ }
++ }
+ }
+
+ /* Enable selected interrupts */
+@@ -668,6 +724,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
+ */
+ static void at91_mci_process_next(struct at91mci_host *host)
+ {
++ pr_debug("process next\n");
+ if (!(host->flags & FL_SENT_COMMAND)) {
+ host->flags |= FL_SENT_COMMAND;
+ at91_mci_send_command(host, host->request->cmd);
+@@ -676,6 +733,7 @@ static void at91_mci_process_next(struct at91mci_host *host)
+ host->flags |= FL_SENT_STOP;
+ at91_mci_send_command(host, host->request->stop);
+ } else {
++ pr_debug("del timer\n");
+ del_timer(&host->timer);
+ /* the at91rm9200 mci controller hangs after some transfers,
+ * and the workaround is to reset it after each transfer.
+@@ -742,6 +800,7 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s
+ else
+ cmd->error = 0;
+
++ pr_debug("command_complete");
+ at91_mci_process_next(host);
+ }
+
+@@ -756,6 +815,7 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+
+ mod_timer(&host->timer, jiffies + HZ);
+
++ pr_debug("request\n");
+ at91_mci_process_next(host);
+ }
+
+@@ -862,10 +922,21 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
+ at91_mci_handle_transmitted(host);
+ }
+
+- if (int_status & AT91_MCI_ENDRX) {
++ if ((int_status & AT91_MCI_ENDRX) && !cpu_is_at91sam9g45()) {
+ pr_debug("ENDRX\n");
+ at91_mci_post_dma_read(host);
+ }
++ if ((int_status & AT91_MCI_XFRDONE) && cpu_is_at91sam9g45()) {
++ pr_debug("XFRDONE\n");
++ at91_mci_write(host, AT91_MCI_HSDMA, 0);
++ completed = 1;
++ }
++ if ((int_status & AT91_MCI_FIFOEMPTY) && cpu_is_at91sam9g45()) {
++ pr_debug("FIFOEMPTY\n");
++ at91_mci_post_dma_read(host);
++ if (host->transfer_index >= host->cmd->data->sg_len)
++ completed = 1;
++ }
+
+ if (int_status & AT91_MCI_RXBUFF) {
+ pr_debug("RX buffer full\n");
+@@ -1017,7 +1088,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
+ host->bus_mode = 0;
+ host->board = pdev->dev.platform_data;
+ if (host->board->wire4) {
+- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
++ if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g45())
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+ else
+ dev_warn(&pdev->dev, "4 wire bus mode not supported"
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0004-.gitignore-ignore-arm-image-output.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0004-.gitignore-ignore-arm-image-output.patch
new file mode 100644
index 0000000000..bac891bfd8
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0004-.gitignore-ignore-arm-image-output.patch
@@ -0,0 +1,21 @@
+From 85507d9d515fb864112d5b0785fad0d34c49efc2 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:41:06 +0100
+Subject: [PATCH 04/18] [.gitignore] ignore arm image output
+
+---
+ .gitignore | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/.gitignore b/.gitignore
+index de6344e..e218170 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -71,3 +71,4 @@ GTAGS
+ *.orig
+ *~
+ \#*#
++arch/arm/boot/compressed/*
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0005-arm-mach-at91-Add-support-for-icnova-boards.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0005-arm-mach-at91-Add-support-for-icnova-boards.patch
new file mode 100644
index 0000000000..48b16660e2
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0005-arm-mach-at91-Add-support-for-icnova-boards.patch
@@ -0,0 +1,1357 @@
+From 1584e8044f709bef0e9a30fa0ee18c72e9555f4b Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:48:30 +0100
+Subject: [PATCH 05/18] [arm/mach-at91] Add support for icnova-boards
+
+This patch adds support for the Boards ICnova ADB1000, ADB1002, ADB1004
+and ADB3000; each equipped by an ICnova SAM9G45 OEM.
+The ADB3000 can be equipped by an ICnova SAM9G45+XC700AN OEM, too.
+---
+ arch/arm/mach-at91/Kconfig | 25 ++
+ arch/arm/mach-at91/Makefile | 6 +-
+ arch/arm/mach-at91/board-icnova_adb1000.c | 328 +++++++++++++++++++++++++
+ arch/arm/mach-at91/board-icnova_adb1002.c | 276 +++++++++++++++++++++
+ arch/arm/mach-at91/board-icnova_adb1004.c | 270 +++++++++++++++++++++
+ arch/arm/mach-at91/board-icnova_adb3000.c | 375 +++++++++++++++++++++++++++++
+ 6 files changed, 1279 insertions(+), 1 deletions(-)
+ create mode 100644 arch/arm/mach-at91/board-icnova_adb1000.c
+ create mode 100644 arch/arm/mach-at91/board-icnova_adb1002.c
+ create mode 100644 arch/arm/mach-at91/board-icnova_adb1004.c
+ create mode 100644 arch/arm/mach-at91/board-icnova_adb3000.c
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index 0b2ee95..bc1221d 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -370,6 +370,31 @@ config MACH_AT91SAM9G45EKES
+ "ES" at the end of the name means that this board is an
+ Engineering Sample.
+
++config MACH_ICNOVA_ADB1000
++ bool "In-Circuit ADB1000 G45 Evaluation Kit"
++ help
++ Select this if you are using In-Circuit's ICnova G45 on an ADB1000
++ Development Board.
++
++config MACH_ICNOVA_ADB1002
++ bool "In-Circuit ADB1002 G45 Evaluation Kit"
++ help
++ Select this if you are using In-Circuit's ICnova G45 on an ADB1002
++ Development Board.
++
++config MACH_ICNOVA_ADB1004
++ bool "In-Circuit ADB1004 G45 Evaluation Kit"
++ help
++ Select this if you are using In-Circuit's ICnova G45 on an ADB1004
++ Development Board. The Configration currently supports the version
++ using the 4.3inch Display
++
++config MACH_ICNOVA_ADB3000
++ bool "In-Circuit ADB3000 G45/FPGA Evaluation Kit"
++ help
++ Select this if you are using In-Circuit's ICnova G45 on an ADB3000
++ Development Board.
++
+ endif
+
+ # ----------------------------------------------------------
+diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
+index 709fbad..be44d7f 100644
+--- a/arch/arm/mach-at91/Makefile
++++ b/arch/arm/mach-at91/Makefile
+@@ -17,7 +17,7 @@ obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_d
+ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+- obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
++obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
+
+@@ -65,6 +65,10 @@ obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
+
+ # AT91SAM9G45 board-specific support
+ obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
++obj-$(CONFIG_MACH_ICNOVA_ADB1000) += board-icnova_adb1000.o
++obj-$(CONFIG_MACH_ICNOVA_ADB1002) += board-icnova_adb1002.o
++obj-$(CONFIG_MACH_ICNOVA_ADB1004) += board-icnova_adb1004.o
++obj-$(CONFIG_MACH_ICNOVA_ADB3000) += board-icnova_adb3000.o
+
+ # AT91CAP9 board-specific support
+ obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
+diff --git a/arch/arm/mach-at91/board-icnova_adb1000.c b/arch/arm/mach-at91/board-icnova_adb1000.c
+new file mode 100644
+index 0000000..d07a5c2
+--- /dev/null
++++ b/arch/arm/mach-at91/board-icnova_adb1000.c
+@@ -0,0 +1,328 @@
++/*
++ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ * Covers: * AT91SAM9G45-EKES board
++ * * AT91SAM9M10G45-EK board
++ *
++ * Copyright (C) 2009 Atmel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/ads7846.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++ /* Initialize processor: 12.000 MHz crystal */
++ at91sam9g45_initialize(12000000);
++
++ /* DGBU on ttyS0. (Rx & Tx only) */
++ at91_register_uart(0, 0, 0);
++
++ // For RS485 you might enable ATMEL_UART_RTS instead of 0
++ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
++ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
++ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++ //at91_register_uart(AT91SAM9G45_ID_US3, 4, 0);
++
++ /* set serial console to ttyS0 (ie, DBGU) */
++ at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++ at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++ .ports = 2,
++ .vbus_pin = {AT91_PIN_PC9, AT91_PIN_PC0, },
++};
++
++/*
++ * I2C devices
++ */
++static struct i2c_board_info icnova_i2c[] = {
++ {
++ .type = "m41t82",
++ .addr = 0x68,
++ },
++};
++
++/*
++ * SPI devices.
++ */
++
++#define CONFIG_BOARD_ICNOVA_ADS7846_IRQ AT91_PIN_PB17
++#define CONFIG_BOARD_ICNOVA_ADS7846_CS 2
++static struct ads7846_platform_data ads_info = {
++ .model = 7846,
++ .vref_delay_usecs = 100,
++ .gpio_pendown = CONFIG_BOARD_ICNOVA_ADS7846_IRQ,
++ .x_min = 330,
++ .y_min = 3700,
++ .x_max = 3700,
++ .y_max = 330,
++ .settle_delay_usecs = 50,
++};
++
++static struct spi_board_info ek_spi_devices[] = {
++ {
++ .modalias = "ads7846",
++ .max_speed_hz = 125000 * 26,
++ .chip_select = CONFIG_BOARD_ICNOVA_ADS7846_CS,
++ .platform_data = &ads_info,
++ .bus_num = 0,
++ .controller_data = AT91_PIN_PD25,
++ },
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++ .phy_irq_pin = AT91_PIN_PC6,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++ {
++ .name = "Kernel",
++ .offset = 0,
++ .size = SZ_2M,
++ },
++ {
++ .name = "Root",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = SZ_16M,
++ },
++ {
++ .name = "Data",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(ek_nand_partition);
++ return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++ .ale = 21,
++ .cle = 22,
++ .rdy_pin = AT91_PIN_PC11,
++ .enable_pin = AT91_PIN_PC8,
++ .partition_info = nand_partitions,
++ .bus_width_16 = 0,
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 10,
++ .ncs_write_setup = 0,
++ .nwe_setup = 10,
++
++ .ncs_read_pulse = 50,
++ .nrd_pulse = 30,
++ .ncs_write_pulse = 50,
++ .nwe_pulse = 30,
++
++ .read_cycle = 60,
++ .write_cycle = 60,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
++ .tdf_cycles = 4,
++};
++
++static void __init ek_add_device_nand(void)
++{
++ /* configure chip-select 3 (NAND) */
++ sam9_smc_configure(3, &ek_nand_smc_config);
++
++ at91_add_device_nand(&ek_nand_data);
++}
++
++/*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata ek_mmc_data = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PD29,
++ .wp_pin = AT91_PIN_PD5,
++ }
++};
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++ {
++ .name = "QVGA",
++ .refresh = 50,
++ .xres = 320, .yres = 240,
++ .pixclock = KHZ2PICOS(6500),
++
++ .left_margin = 34, .right_margin = 20,
++ .upper_margin = 9, .lower_margin = 4,
++ .hsync_len = 34, .vsync_len = 9,
++
++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ .vmode = FB_VMODE_NONINTERLACED,
++ },
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++ .manufacturer = "ET",
++ .monitor = "ET035009DH6",
++
++ .modedb = at91_tft_vga_modes,
++ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
++ .hfmin = 10000,
++ .hfmax = 30000,
++ .vfmin = 50,
++ .vfmax = 80,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
++ | ATMEL_LCDC_DISTYPE_TFT \
++ | ATMEL_LCDC_INVCLK \
++ | ATMEL_LCDC_INVDVAL \
++ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++ .lcdcon_is_backlight = true,
++ .default_bpp = 24,
++ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
++ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
++ .default_monspecs = &at91fb_default_monspecs,
++ .guard_time = 9,
++ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++
++/*
++ * LEDs ... these could all be PWM-driven, for variable brightness
++ */
++static struct gpio_led ek_leds[] = {
++ {
++ .name = "pwr",
++ .gpio = AT91_PIN_PD28,
++ .default_trigger = "heartbeat",
++ },
++ {
++ .name = "LED1",
++ .gpio = AT91_PIN_PA22,
++ .default_trigger = "nand-disk",
++ },
++ {
++ .name = "LED2",
++ .gpio = AT91_PIN_PA23,
++ .default_trigger = "mmc0",
++ },
++ {
++ .name = "LED3",
++ .gpio = AT91_PIN_PD23,
++ },
++ {
++ .name = "LED4",
++ .gpio = AT91_PIN_PD26,
++ },
++};
++
++
++static void __init ek_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* USB HS Host */
++ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
++ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++ /* USB HS Device */
++ at91_add_device_usba(NULL);
++ /* SPI */
++ ek_spi_devices[0].irq = gpio_to_irq(CONFIG_BOARD_ICNOVA_ADS7846_IRQ),
++ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++ /* MMC */
++ at91_add_device_mci(0, &ek_mmc_data);
++ /* Ethernet */
++ at91_add_device_eth(&ek_macb_data);
++ /* NAND */
++ ek_add_device_nand();
++ /* I2C */
++ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
++ /* LCD Controller */
++ gpio_request(AT91_PIN_PE1, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE1, 1);
++ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++ gpio_direction_output(AT91_PIN_PE0, 0);
++
++ at91_add_device_lcdc(&ek_lcdc_data);
++ /* LEDs */
++ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++}
++
++MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
++ /* Maintainer: Atmel */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91sam926x_timer,
++ .map_io = ek_map_io,
++ .init_irq = ek_init_irq,
++ .init_machine = ek_board_init,
++MACHINE_END
+diff --git a/arch/arm/mach-at91/board-icnova_adb1002.c b/arch/arm/mach-at91/board-icnova_adb1002.c
+new file mode 100644
+index 0000000..2a81b45
+--- /dev/null
++++ b/arch/arm/mach-at91/board-icnova_adb1002.c
+@@ -0,0 +1,276 @@
++/*
++ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ * Covers: * AT91SAM9G45-EKES board
++ * * AT91SAM9M10G45-EK board
++ *
++ * Copyright (C) 2009 Atmel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++ /* Initialize processor: 12.000 MHz crystal */
++ at91sam9g45_initialize(12000000);
++
++ /* DGBU on ttyS0. (Rx & Tx only) */
++ at91_register_uart(0, 0, 0);
++
++ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
++ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
++ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++
++ /* set serial console to ttyS0 (ie, DBGU) */
++ at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++ at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++ .ports = 2,
++ .vbus_pin = {AT91_PIN_PC9, AT91_PIN_PC0, },
++};
++
++/*
++ * I2C devices
++ */
++static struct i2c_board_info icnova_i2c[] = {
++ {
++ .type = "m41t82",
++ .addr = 0x68,
++ },
++ {
++ .type = "tfp410",
++ .addr = 0x38,
++ },
++};
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++ .phy_irq_pin = AT91_PIN_PC6,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++ {
++ .name = "Kernel",
++ .offset = 0,
++ .size = SZ_2M,
++ },
++ {
++ .name = "Root",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = SZ_16M,
++ },
++ {
++ .name = "Data",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(ek_nand_partition);
++ return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++ .ale = 21,
++ .cle = 22,
++ .rdy_pin = AT91_PIN_PC11,
++ .enable_pin = AT91_PIN_PC8,
++ .partition_info = nand_partitions,
++ .bus_width_16 = 0,
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 10,
++ .ncs_write_setup = 0,
++ .nwe_setup = 10,
++
++ .ncs_read_pulse = 50,
++ .nrd_pulse = 30,
++ .ncs_write_pulse = 50,
++ .nwe_pulse = 30,
++
++ .read_cycle = 60,
++ .write_cycle = 60,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
++ .tdf_cycles = 4,
++};
++
++static void __init ek_add_device_nand(void)
++{
++ /* configure chip-select 3 (NAND) */
++ sam9_smc_configure(3, &ek_nand_smc_config);
++
++ at91_add_device_nand(&ek_nand_data);
++}
++
++/*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata ek_mmc_data = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PD29,
++ }
++};
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++ /* 15 1024x768-75 VESA */
++ { "1024x768-75", 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
++ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
++ /* 16 1024x768-85 VESA */
++ { "1024x768-85", 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
++ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++ .manufacturer = "ET",
++ .monitor = "ET035009DH6",
++
++ .modedb = at91_tft_vga_modes,
++ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
++ .hfmin = 10000,
++ .hfmax = 30000,
++ .vfmin = 50,
++ .vfmax = 80,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
++ | ATMEL_LCDC_DISTYPE_TFT \
++ | ATMEL_LCDC_INVCLK \
++ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++ .lcdcon_is_backlight = true,
++ .default_bpp = 24,
++ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
++ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
++ .default_monspecs = &at91fb_default_monspecs,
++ .guard_time = 9,
++ .lcd_wiring_mode = ATMEL_LCDC_WIRING_BGR,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++
++/*
++ * LEDs ... these could all be PWM-driven, for variable brightness
++ */
++static struct gpio_led ek_leds[] = {
++ {
++ .name = "pwr",
++ .gpio = AT91_PIN_PD28,
++ .default_trigger = "heartbeat",
++ },
++ {
++ .name = "LED1",
++ .gpio = AT91_PIN_PD30,
++ .default_trigger = "mmc0",
++ },
++};
++
++static void __init ek_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* USB HS Host */
++ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
++ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++ /* USB HS Device */
++ at91_add_device_usba(NULL);
++ /* MMC */
++ at91_add_device_mci(0, &ek_mmc_data);
++ /* Ethernet */
++ at91_add_device_eth(&ek_macb_data);
++ /* NAND */
++ ek_add_device_nand();
++ /* I2C */
++ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
++ /* LCD Controller */
++ gpio_request(AT91_PIN_PE1, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE1, 1);
++ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++ gpio_direction_output(AT91_PIN_PE0, 0);
++
++ at91_add_device_lcdc(&ek_lcdc_data);
++ /* LEDs */
++ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++}
++
++MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
++ /* Maintainer: Atmel */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91sam926x_timer,
++ .map_io = ek_map_io,
++ .init_irq = ek_init_irq,
++ .init_machine = ek_board_init,
++MACHINE_END
+diff --git a/arch/arm/mach-at91/board-icnova_adb1004.c b/arch/arm/mach-at91/board-icnova_adb1004.c
+new file mode 100644
+index 0000000..60934db
+--- /dev/null
++++ b/arch/arm/mach-at91/board-icnova_adb1004.c
+@@ -0,0 +1,270 @@
++/*
++ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ * Covers: * AT91SAM9G45-EKES board
++ * * AT91SAM9M10G45-EK board
++ *
++ * Copyright (C) 2009 Atmel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++ /* Initialize processor: 12.000 MHz crystal */
++ at91sam9g45_initialize(12000000);
++
++ /* DGBU on ttyS0. (Rx & Tx only) */
++ at91_register_uart(0, 0, 0);
++
++ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
++ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
++ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++
++ /* set serial console to ttyS0 (ie, DBGU) */
++ at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++ at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++ .ports = 2,
++ .vbus_pin = {AT91_PIN_PC9, AT91_PIN_PC0, },
++};
++
++/*
++ * I2C devices
++ */
++static struct i2c_board_info icnova_i2c[] = {
++ {
++ .type = "m41t82",
++ .addr = 0x68,
++ },
++};
++
++/*
++ * SPI devices.
++ */
++
++static struct spi_board_info ek_spi_devices[] = {
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++ {
++ .name = "Kernel",
++ .offset = 0,
++ .size = SZ_2M,
++ },
++ {
++ .name = "Root",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(ek_nand_partition);
++ return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++ .ale = 21,
++ .cle = 22,
++ .rdy_pin = AT91_PIN_PC11,
++ .enable_pin = AT91_PIN_PC8,
++ .partition_info = nand_partitions,
++ .bus_width_16 = 0,
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 10,
++ .ncs_write_setup = 0,
++ .nwe_setup = 10,
++
++ .ncs_read_pulse = 50,
++ .nrd_pulse = 30,
++ .ncs_write_pulse = 50,
++ .nwe_pulse = 30,
++
++ .read_cycle = 60,
++ .write_cycle = 60,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
++ .tdf_cycles = 4,
++};
++
++static void __init ek_add_device_nand(void)
++{
++ /* configure chip-select 3 (NAND) */
++ sam9_smc_configure(3, &ek_nand_smc_config);
++
++ at91_add_device_nand(&ek_nand_data);
++}
++
++/*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata ek_mmc_data = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PD29,
++ }
++};
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++ {
++ .name = "QVGA",
++ .refresh = 50,
++ .xres = 480, .yres = 272,
++ .pixclock = KHZ2PICOS(10000),
++
++ .left_margin = 43, .right_margin = 11,
++ .upper_margin = 22, .lower_margin = 6,
++ .hsync_len = 34, .vsync_len = 9,
++
++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ .vmode = FB_VMODE_NONINTERLACED,
++ },
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++ .manufacturer = "ET",
++ .monitor = "ET035009DH6",
++
++ .modedb = at91_tft_vga_modes,
++ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
++ .hfmin = 10000,
++ .hfmax = 40000,
++ .vfmin = 50,
++ .vfmax = 120,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
++ | ATMEL_LCDC_DISTYPE_TFT \
++ | ATMEL_LCDC_INVCLK \
++ | ATMEL_LCDC_INVDVAL \
++ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++ .lcdcon_is_backlight = true,
++ .default_bpp = 24,
++ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
++ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
++ .default_monspecs = &at91fb_default_monspecs,
++ .guard_time = 9,
++ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++/*
++ * Touchscreen
++ */
++static struct at91_tsadcc_data ek_tsadcc_data = {
++ .adc_clock = 300000,
++ .pendet_debounce = 0x0d,
++ .ts_sample_hold_time = 0x0a,
++};
++
++
++static void __init ek_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* USB HS Host */
++ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
++ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++ /* USB HS Device */
++ at91_add_device_usba(NULL);
++ /* SPI */
++ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++ /* MMC */
++ at91_add_device_mci(0, &ek_mmc_data);
++ /* NAND */
++ ek_add_device_nand();
++ /* I2C */
++ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
++ /* LCD Controller */
++ gpio_request(AT91_PIN_PB10, "lcdc.ud");
++ gpio_direction_output(AT91_PIN_PB10, 0);
++ gpio_request(AT91_PIN_PB11, "lcdc.lr");
++ gpio_direction_output(AT91_PIN_PB11, 0);
++ gpio_request(AT91_PIN_PE0, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE0, 1);
++ gpio_request(AT91_PIN_PE1, "lcdc.pwr");
++ gpio_direction_output(AT91_PIN_PE1, 0);
++
++ at91_add_device_lcdc(&ek_lcdc_data);
++ /* Touch Screen */
++ at91_add_device_tsadcc(&ek_tsadcc_data);
++}
++
++MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
++ /* Maintainer: Atmel */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91sam926x_timer,
++ .map_io = ek_map_io,
++ .init_irq = ek_init_irq,
++ .init_machine = ek_board_init,
++MACHINE_END
+diff --git a/arch/arm/mach-at91/board-icnova_adb3000.c b/arch/arm/mach-at91/board-icnova_adb3000.c
+new file mode 100644
+index 0000000..6006faa
+--- /dev/null
++++ b/arch/arm/mach-at91/board-icnova_adb3000.c
+@@ -0,0 +1,375 @@
++/*
++ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ * Covers: * AT91SAM9G45-EKES board
++ * * AT91SAM9M10G45-EK board
++ *
++ * Copyright (C) 2009 Atmel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/ads7846.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++#define FPGA_MEM_BASE 0x20000000
++
++static struct resource fpga_res = {
++ .start = FPGA_MEM_BASE,
++ .end = FPGA_MEM_BASE + SZ_1K - 1,
++ .flags = IORESOURCE_MEM,
++};
++
++static struct platform_device fpga_dev = {
++ .name = "fpga_sram",
++ .id = -1,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = &fpga_res,
++ .num_resources = 1,
++};
++
++static struct sam9_smc_config __initdata fpga_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 2,
++ .ncs_write_setup = 0,
++ .nwe_setup = 2,
++
++ .ncs_read_pulse = 10,
++ .nrd_pulse = 5,
++ .ncs_write_pulse = 10,
++ .nwe_pulse = 5,
++
++ .read_cycle = 12,
++ .write_cycle = 12,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_32,
++ .tdf_cycles = 4,
++};
++
++
++static void __init ek_map_io(void)
++{
++ /* Initialize processor: 12.000 MHz crystal */
++ at91sam9g45_initialize(12000000);
++
++ /* DGBU on ttyS0. (Rx & Tx only) */
++ at91_register_uart(0, 0, 0);
++
++ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
++ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
++ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++ at91_register_uart(AT91SAM9G45_ID_US3, 4, 0);
++
++ /* set serial console to ttyS0 (ie, DBGU) */
++ at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++ at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++ .ports = 2,
++ .vbus_pin = {AT91_PIN_PC9, AT91_PIN_PC0, },
++};
++
++/*
++ * I2C devices
++ */
++static struct i2c_board_info icnova_i2c[] = {
++};
++
++/*
++ * SPI devices.
++ */
++
++static struct spi_board_info ek_spi_devices[] = {
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++ .phy_irq_pin = AT91_PIN_PC6,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++ {
++ .name = "Kernel",
++ .offset = 0,
++ .size = SZ_2M,
++ },
++ {
++ .name = "Root",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = SZ_16M,
++ },
++ {
++ .name = "Data",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(ek_nand_partition);
++ return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++ .ale = 21,
++ .cle = 22,
++ .rdy_pin = AT91_PIN_PC11,
++ .enable_pin = AT91_PIN_PC8,
++ .partition_info = nand_partitions,
++ .bus_width_16 = 0,
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 10,
++ .ncs_write_setup = 0,
++ .nwe_setup = 10,
++
++ .ncs_read_pulse = 50,
++ .nrd_pulse = 30,
++ .ncs_write_pulse = 50,
++ .nwe_pulse = 30,
++
++ .read_cycle = 60,
++ .write_cycle = 60,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
++ .tdf_cycles = 4,
++};
++
++static void __init ek_add_device_nand(void)
++{
++ /* configure chip-select 3 (NAND) */
++ sam9_smc_configure(3, &ek_nand_smc_config);
++
++ at91_add_device_nand(&ek_nand_data);
++}
++
++/*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata ek_mmc_data = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PD5,
++ }
++};
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++ {
++ .name = "VGA",
++ .refresh = 50,
++ .xres = 800, .yres = 480,
++ .pixclock = KHZ2PICOS(33260),
++
++ .left_margin = 128, .right_margin = 88,
++ .upper_margin = 27, .lower_margin = 16,
++ .hsync_len = 40, .vsync_len = 2,
++
++ .vmode = FB_VMODE_NONINTERLACED,
++ },
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++ .manufacturer = "ET",
++ .monitor = "ET050000DH6",
++
++ .modedb = at91_tft_vga_modes,
++ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
++ .hfmin = 10000,
++ .hfmax = 30000,
++ .vfmin = 50,
++ .vfmax = 80,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
++ | ATMEL_LCDC_DISTYPE_TFT \
++ | ATMEL_LCDC_INVCLK \
++ | ATMEL_LCDC_INVDVAL \
++ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++ .lcdcon_is_backlight = true,
++ .default_bpp = 24,
++ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
++ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
++ .default_monspecs = &at91fb_default_monspecs,
++ .guard_time = 9,
++ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++
++/*
++ * Touchscreen
++ */
++static struct at91_tsadcc_data ek_tsadcc_data = {
++ .adc_clock = 300000,
++ .pendet_debounce = 0x0d,
++ .ts_sample_hold_time = 0x0a,
++};
++
++/*
++ * LEDs
++ */
++static struct gpio_led ek_leds[] = {
++ {
++ .name = "LED1",
++ .gpio = AT91_PIN_PD28,
++ .default_trigger = "heartbeat",
++ },
++ {
++ .name = "LED2",
++ .gpio = AT91_PIN_PD30,
++ .default_trigger = "nand-disk",
++ },
++ {
++ .name = "LED3",
++ .gpio = AT91_PIN_PD31,
++ .default_trigger = "mmc0",
++ },
++ {
++ .name = "LED4",
++ .gpio = AT91_PIN_PE31,
++ },
++};
++
++
++static void __init ek_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* FPGA */
++ at91_set_gpio_input(AT91_PIN_PC7, 0);
++ at91_set_gpio_input(AT91_PIN_PC10, 0);
++ at91_set_gpio_input(AT91_PIN_PC12, 0);
++ at91_set_gpio_input(AT91_PIN_PA31, 0);
++ at91_set_gpio_input(AT91_PIN_PD10, 0);
++ at91_set_gpio_input(AT91_PIN_PD11, 0);
++ at91_set_gpio_input(AT91_PIN_PD12, 0);
++ at91_set_gpio_input(AT91_PIN_PD13, 0);
++ at91_set_gpio_input(AT91_PIN_PD14, 0);
++ at91_set_gpio_input(AT91_PIN_PD15, 0);
++ at91_set_gpio_output(AT91_PIN_PD29, 1);
++ at91_set_A_periph(AT91_PIN_PC16, 0);
++ at91_set_A_periph(AT91_PIN_PC17, 0);
++ at91_set_A_periph(AT91_PIN_PC18, 0);
++ at91_set_A_periph(AT91_PIN_PC19, 0);
++ at91_set_A_periph(AT91_PIN_PC20, 0);
++ at91_set_A_periph(AT91_PIN_PC21, 0);
++ at91_set_A_periph(AT91_PIN_PC22, 0);
++ at91_set_A_periph(AT91_PIN_PC23, 0);
++ at91_set_A_periph(AT91_PIN_PC24, 0);
++ at91_set_A_periph(AT91_PIN_PC25, 0);
++ at91_set_A_periph(AT91_PIN_PC26, 0);
++ at91_set_A_periph(AT91_PIN_PC27, 0);
++ at91_set_A_periph(AT91_PIN_PC28, 0);
++ at91_set_A_periph(AT91_PIN_PC29, 0);
++ at91_set_A_periph(AT91_PIN_PC30, 0);
++ at91_set_A_periph(AT91_PIN_PC31, 0);
++ /* USB HS Host */
++ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
++ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++ /* USB HS Device */
++ at91_add_device_usba(NULL);
++ /* SPI */
++ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++ /* MMC */
++ at91_add_device_mci(0, &ek_mmc_data);
++ /* Ethernet */
++ at91_add_device_eth(&ek_macb_data);
++ /* NAND */
++ ek_add_device_nand();
++ /* I2C */
++ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
++ /* LCD Controller */
++ gpio_request(AT91_PIN_PE1, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE1, 1);
++ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++ gpio_direction_output(AT91_PIN_PE0, 1);
++ gpio_request(AT91_PIN_PE6, "lcdc.enb");
++ gpio_direction_output(AT91_PIN_PE6, 1);
++
++ at91_add_device_lcdc(&ek_lcdc_data);
++ /* Touch Screen */
++ at91_add_device_tsadcc(&ek_tsadcc_data);
++ /* LEDs */
++ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++ /* FPGA-Interface */
++ sam9_smc_configure(1, &fpga_smc_config);
++ platform_device_register(&fpga_dev);
++}
++
++MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
++ /* Maintainer: Atmel */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91sam926x_timer,
++ .map_io = ek_map_io,
++ .init_irq = ek_init_irq,
++ .init_machine = ek_board_init,
++MACHINE_END
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0006-ICnova-Add-support-for-ADB1004revB-and-5In-Displays.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0006-ICnova-Add-support-for-ADB1004revB-and-5In-Displays.patch
new file mode 100644
index 0000000000..930b81d1cd
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0006-ICnova-Add-support-for-ADB1004revB-and-5In-Displays.patch
@@ -0,0 +1,289 @@
+From f49b7c1f79472aa88dcfd2ff7d892a29953d0918 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:56:13 +0100
+Subject: [PATCH 06/18] [ICnova] Add support for ADB1004revB and 5In Displays
+
+It is now possible to change between an 5In Display and default
+Display in menuconfig, if the board supports it.
+
+The Changes on ADB1004 Revision B are merged now, too.
+---
+ arch/arm/mach-at91/Kconfig | 10 +++
+ arch/arm/mach-at91/at91sam9g45_devices.c | 2 +
+ arch/arm/mach-at91/board-icnova_adb1000.c | 25 ++++++++
+ arch/arm/mach-at91/board-icnova_adb1004.c | 90 ++++++++++++++++++++++++++---
+ 4 files changed, 119 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index bc1221d..3c984e1 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -397,6 +397,16 @@ config MACH_ICNOVA_ADB3000
+
+ endif
+
++config ICNOVA_ET050000
++ depends on MACH_ICNOVA_ADB1000 || MACH_ICNOVA_ADB1004
++ bool "5Inch Display ET050000DH6"
++ help
++ Select this if you have a 5" Display connected to your Board.
++
++config ICNOVA_ADB1004B
++ depends on MACH_ICNOVA_ADB1004
++ bool "ADB1004 is Revision B"
++
+ # ----------------------------------------------------------
+
+ if ARCH_AT91CAP9
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index c40e4cd..0f9955f 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -918,9 +918,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+ at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
+ #ifndef CONFIG_MACH_ICNOVA_ADB1004
+ #ifndef CONFIG_MACH_ICNOVA_ADB3000
++#ifndef CONFIG_ICNOVA_ET050000
+ at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
+ #endif
+ #endif
++#endif
+ at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
+ at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
+ at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
+diff --git a/arch/arm/mach-at91/board-icnova_adb1000.c b/arch/arm/mach-at91/board-icnova_adb1000.c
+index d07a5c2..b292acf 100644
+--- a/arch/arm/mach-at91/board-icnova_adb1000.c
++++ b/arch/arm/mach-at91/board-icnova_adb1000.c
+@@ -206,6 +206,20 @@ static struct mci_platform_data __initdata ek_mmc_data = {
+ */
+ #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+ static struct fb_videomode at91_tft_vga_modes[] = {
++#ifdef CONFIG_ICNOVA_ET050000
++ {
++ .name = "VGA",
++ .refresh = 50,
++ .xres = 800, .yres = 480,
++ .pixclock = KHZ2PICOS(33260),
++
++ .left_margin = 178, .right_margin = 38,
++ .upper_margin = 35, .lower_margin = 8,
++ .hsync_len = 40, .vsync_len = 2,
++
++ .vmode = FB_VMODE_NONINTERLACED,
++ }
++#else
+ {
+ .name = "QVGA",
+ .refresh = 50,
+@@ -219,11 +233,16 @@ static struct fb_videomode at91_tft_vga_modes[] = {
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
++#endif
+ };
+
+ static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "ET",
++#ifdef CONFIG_ICNOVA_ET050000
++ .monitor = "ET050000DH6",
++#else
+ .monitor = "ET035009DH6",
++#endif
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+@@ -309,7 +328,13 @@ static void __init ek_board_init(void)
+ gpio_request(AT91_PIN_PE1, "lcdc.mode");
+ gpio_direction_output(AT91_PIN_PE1, 1);
+ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++#ifdef CONFIG_ICNOVA_ET050000
++ gpio_direction_output(AT91_PIN_PE0, 1);
++ gpio_request(AT91_PIN_PE1, "lcdc.enb");
++ gpio_direction_output(AT91_PIN_PE6, 1);
++#else
+ gpio_direction_output(AT91_PIN_PE0, 0);
++#endif
+
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* LEDs */
+diff --git a/arch/arm/mach-at91/board-icnova_adb1004.c b/arch/arm/mach-at91/board-icnova_adb1004.c
+index 60934db..ffb4eba 100644
+--- a/arch/arm/mach-at91/board-icnova_adb1004.c
++++ b/arch/arm/mach-at91/board-icnova_adb1004.c
+@@ -19,6 +19,9 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/spi/spi.h>
++#ifdef CONFIG_ICNOVA_ADB1004B
++#include <linux/spi/ads7846.h>
++#endif
+ #include <linux/fb.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/input.h>
+@@ -54,9 +57,11 @@ static void __init ek_map_io(void)
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
++ // For RS485 you might enable ATMEL_UART_RTS instead of 0
+ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
+ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
+ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++ //at91_register_uart(AT91SAM9G45_ID_US3, 4, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+@@ -90,7 +95,40 @@ static struct i2c_board_info icnova_i2c[] = {
+ * SPI devices.
+ */
+
++#ifdef CONFIG_ICNOVA_ADB1004B
++#define CONFIG_BOARD_ICNOVA_ADS7846_IRQ AT91_PIN_PB17
++#define CONFIG_BOARD_ICNOVA_ADS7846_CS 2
++static struct ads7846_platform_data ads_info = {
++ .model = 7846,
++ .vref_delay_usecs = 100,
++ .gpio_pendown = CONFIG_BOARD_ICNOVA_ADS7846_IRQ,
++ .x_min = 330,
++ .y_min = 3700,
++ .x_max = 3700,
++ .y_max = 330,
++ .settle_delay_usecs = 50,
++};
++#endif
++
+ static struct spi_board_info ek_spi_devices[] = {
++#ifdef CONFIG_ICNOVA_ADB1004B
++ {
++ .modalias = "ads7846",
++ .max_speed_hz = 125000 * 26,
++ .chip_select = CONFIG_BOARD_ICNOVA_ADS7846_CS,
++ .platform_data = &ads_info,
++ .bus_num = 0,
++ .controller_data = (void *) AT91_PIN_PD25,
++ },
++#endif
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++ .phy_irq_pin = AT91_PIN_PC6,
+ };
+
+
+@@ -159,6 +197,9 @@ static struct mci_platform_data __initdata ek_mmc_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PD29,
++#ifdef CONFIG_ICNOVA_ADB1004B
++ .wp_pin = AT91_PIN_PD5,
++#endif
+ }
+ };
+
+@@ -168,6 +209,20 @@ static struct mci_platform_data __initdata ek_mmc_data = {
+ */
+ #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+ static struct fb_videomode at91_tft_vga_modes[] = {
++#ifdef CONFIG_ICNOVA_ET050000
++ {
++ .name = "VGA",
++ .refresh = 50,
++ .xres = 800, .yres = 480,
++ .pixclock = KHZ2PICOS(33260),
++
++ .left_margin = 178, .right_margin = 38,
++ .upper_margin = 35, .lower_margin = 8,
++ .hsync_len = 40, .vsync_len = 2,
++
++ .vmode = FB_VMODE_NONINTERLACED,
++ },
++#else
+ {
+ .name = "QVGA",
+ .refresh = 50,
+@@ -181,11 +236,16 @@ static struct fb_videomode at91_tft_vga_modes[] = {
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
++#endif
+ };
+
+ static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "ET",
++#ifdef CONFIG_ICNOVA_ET050000
++ .monitor = "ET050000DH6",
++#else
+ .monitor = "ET035009DH6",
++#endif
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+@@ -219,12 +279,13 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+ /*
+ * Touchscreen
+ */
++#ifndef CONFIG_ICNOVA_ADB1004B
+ static struct at91_tsadcc_data ek_tsadcc_data = {
+- .adc_clock = 300000,
+- .pendet_debounce = 0x0d,
+- .ts_sample_hold_time = 0x0a,
++ .adc_clock = 200000,
++ .pendet_debounce = 0x02,
++ .ts_sample_hold_time = 0x0f,
+ };
+-
++#endif
+
+ static void __init ek_board_init(void)
+ {
+@@ -236,26 +297,39 @@ static void __init ek_board_init(void)
+ /* USB HS Device */
+ at91_add_device_usba(NULL);
+ /* SPI */
++#ifdef CONFIG_ICNOVA_ADB1004B
++ ek_spi_devices[0].irq = gpio_to_irq(CONFIG_BOARD_ICNOVA_ADS7846_IRQ),
++#endif
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* MMC */
+ at91_add_device_mci(0, &ek_mmc_data);
++ /* Ethernet */
++ at91_add_device_eth(&ek_macb_data);
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
+ /* LCD Controller */
++ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++#ifdef CONFIG_ICNOVA_ET050000
++ gpio_direction_output(AT91_PIN_PE0, 1);
++ gpio_request(AT91_PIN_PE6, "lcdc.enb");
++ gpio_direction_output(AT91_PIN_PE6, 1);
++#else
++ gpio_direction_output(AT91_PIN_PE0, 0);
+ gpio_request(AT91_PIN_PB10, "lcdc.ud");
+ gpio_direction_output(AT91_PIN_PB10, 0);
+ gpio_request(AT91_PIN_PB11, "lcdc.lr");
+ gpio_direction_output(AT91_PIN_PB11, 0);
+- gpio_request(AT91_PIN_PE0, "lcdc.mode");
+- gpio_direction_output(AT91_PIN_PE0, 1);
+- gpio_request(AT91_PIN_PE1, "lcdc.pwr");
+- gpio_direction_output(AT91_PIN_PE1, 0);
++#endif
++ gpio_request(AT91_PIN_PE1, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE1, 1);
+
+ at91_add_device_lcdc(&ek_lcdc_data);
++#ifndef CONFIG_ICNOVA_ADB1004B
+ /* Touch Screen */
+ at91_add_device_tsadcc(&ek_tsadcc_data);
++#endif
+ }
+
+ MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0007-atmel_tsadcc-adding-support-for-pressure-measurement.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0007-atmel_tsadcc-adding-support-for-pressure-measurement.patch
new file mode 100644
index 0000000000..f7970fe86a
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0007-atmel_tsadcc-adding-support-for-pressure-measurement.patch
@@ -0,0 +1,215 @@
+From e301c6a08d806a0afe79681c5ff55282def3f0ba Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:57:22 +0100
+Subject: [PATCH 07/18] [atmel_tsadcc] adding support for pressure-measurement
+
+Needed for a properly working tslib.
+---
+ drivers/input/touchscreen/atmel_tsadcc.c | 123 ++++++++++++++++++++----------
+ 1 files changed, 84 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
+index 3d9b516..722fba5 100644
+--- a/drivers/input/touchscreen/atmel_tsadcc.c
++++ b/drivers/input/touchscreen/atmel_tsadcc.c
+@@ -12,6 +12,7 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
++#define DEBUG
+ #include <linux/init.h>
+ #include <linux/err.h>
+ #include <linux/kernel.h>
+@@ -25,6 +26,8 @@
+ #include <mach/board.h>
+ #include <mach/cpu.h>
+
++#define CONFIG_ATMEL_TSADCC_PRESS 1
++
+ /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
+
+ #define ATMEL_TSADCC_CR 0x00 /* Control register */
+@@ -74,6 +77,9 @@
+ #define ATMEL_TSADCC_RXBUFF (1 << 19) /* TX Buffer full */
+ #define ATMEL_TSADCC_PENCNT (1 << 20) /* Pen contact */
+ #define ATMEL_TSADCC_NOCNT (1 << 21) /* No contact */
++#define ATMEL_TSADCC_EOCXP (1 << 24) /* End of conversion Xposition */
++#define ATMEL_TSADCC_EOCZ1 (1 << 25) /* End of conversion Z1 */
++#define ATMEL_TSADCC_EOCZ2 (1 << 26) /* End of conversion Z2 */
+
+ #define ATMEL_TSADCC_LCDR 0x20 /* Last Converted Data register */
+ #define ATMEL_TSADCC_DATA (0x3ff << 0) /* Channel data */
+@@ -103,6 +109,7 @@ struct atmel_tsadcc {
+ int irq;
+ unsigned int prev_absx;
+ unsigned int prev_absy;
++ unsigned int prev_press;
+ unsigned char bufferedmeasure;
+ };
+
+@@ -110,6 +117,47 @@ static void __iomem *tsc_base;
+
+ #define atmel_tsadcc_read(reg) __raw_readl(tsc_base + (reg))
+ #define atmel_tsadcc_write(reg, val) __raw_writel((val), tsc_base + (reg))
++#ifdef CONFIG_ATMEL_TSADCC_PRESS
++#define ATMEL_TSADCC_IRQ_MASK \
++ (ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_EOC(1) | ATMEL_TSADCC_EOCXP | ATMEL_TSADCC_NOCNT)
++#else
++#define ATMEL_TSADCC_IRQ_MASK \
++ (ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_EOC(1) | ATMEL_TSADCC_NOCNT)
++#endif
++
++
++static inline void atmel_tsadcc_irq_nocnt(struct input_dev *input_dev) {
++ unsigned int reg;
++ /* Contact lost */
++ reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC;
++
++ atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
++ atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
++ atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_IRQ_MASK);
++ atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
++
++ input_report_abs(input_dev, ABS_PRESSURE, 0);
++ input_report_key(input_dev, BTN_TOUCH, 0);
++ input_sync(input_dev);
++ return;
++}
++
++static inline void atmel_tsadcc_irq_pencnt(struct input_dev *input_dev) {
++ unsigned int reg;
++ /* Pen detected */
++ reg = atmel_tsadcc_read(ATMEL_TSADCC_MR);
++ reg &= ~ATMEL_TSADCC_PENDBC;
++
++ atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT);
++ atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
++ atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_IRQ_MASK);
++ atmel_tsadcc_write(ATMEL_TSADCC_TRGR,
++ ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16));
++ return;
++}
++
++#define atmel_tsadcc_irq_posresult(reg0, reg1) \
++ ((atmel_tsadcc_read(reg1) << 10) / atmel_tsadcc_read(reg0))
+
+ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
+ {
+@@ -117,59 +165,48 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
+ struct input_dev *input_dev = ts_dev->input;
+
+ unsigned int status;
+- unsigned int reg;
++
++ unsigned int z1, z2, xp;
+
+ status = atmel_tsadcc_read(ATMEL_TSADCC_SR);
+ status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR);
+
+ if (status & ATMEL_TSADCC_NOCNT) {
+- /* Contact lost */
+- reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC;
+-
+- atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+- atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
+- atmel_tsadcc_write(ATMEL_TSADCC_IDR,
+- ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
+- atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
+-
+- input_report_key(input_dev, BTN_TOUCH, 0);
++ atmel_tsadcc_irq_nocnt(input_dev);
+ ts_dev->bufferedmeasure = 0;
+- input_sync(input_dev);
+-
++ pr_debug("no contact\n");
+ } else if (status & ATMEL_TSADCC_PENCNT) {
+- /* Pen detected */
+- reg = atmel_tsadcc_read(ATMEL_TSADCC_MR);
+- reg &= ~ATMEL_TSADCC_PENDBC;
+-
+- atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT);
+- atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+- atmel_tsadcc_write(ATMEL_TSADCC_IER,
+- ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
+- atmel_tsadcc_write(ATMEL_TSADCC_TRGR,
+- ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16));
+-
++ atmel_tsadcc_irq_pencnt(input_dev);
++ pr_debug("contact\n");
++#ifdef CONFIG_ATMEL_TSADCC_PRESS
++ } else if (status & ATMEL_TSADCC_EOCXP) {
++ z1 = atmel_tsadcc_read(ATMEL_TSADCC_Z1DAT);
++ z2 = atmel_tsadcc_read(ATMEL_TSADCC_Z2DAT);
++ xp = atmel_tsadcc_read(ATMEL_TSADCC_XPOS);
++ pr_debug("z = %i/%i*%i\n", z2, z1, xp);
++ ts_dev->prev_press = ((z2 - z1) * xp)/z1;
++#endif
++ } else if (status & ATMEL_TSADCC_EOC(1)) {
++ ts_dev->prev_absy = atmel_tsadcc_irq_posresult(
++ ATMEL_TSADCC_CDR0, ATMEL_TSADCC_CDR1);
+ } else if (status & ATMEL_TSADCC_EOC(3)) {
+- /* Conversion finished */
+-
+- if (ts_dev->bufferedmeasure) {
++ ts_dev->prev_absx = atmel_tsadcc_irq_posresult(
++ ATMEL_TSADCC_CDR2, ATMEL_TSADCC_CDR3);
++ //if (ts_dev->bufferedmeasure) {
+ /* Last measurement is always discarded, since it can
+ * be erroneous.
+ * Always report previous measurement */
++ pr_debug("send x=%i, y=%i, z=%i\n", ts_dev->prev_absx,
++ ts_dev->prev_absy, ts_dev->prev_press);
+ input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
+ input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
++ input_report_abs(input_dev, ABS_PRESSURE,
++ 3072 - ts_dev->prev_press);
+ input_report_key(input_dev, BTN_TOUCH, 1);
+ input_sync(input_dev);
+- } else
+- ts_dev->bufferedmeasure = 1;
+-
+- /* Now make new measurement */
+- ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
+- ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
+-
+- ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
+- ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
++ //} else
++ // ts_dev->bufferedmeasure = 1;
+ }
+-
+ return IRQ_HANDLED;
+ }
+
+@@ -254,8 +291,11 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ input_dev->dev.parent = &pdev->dev;
+
+ __set_bit(EV_ABS, input_dev->evbit);
++ __set_bit(EV_KEY, input_dev->evbit);
++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 3072, 0, 0);
+
+ input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
+@@ -284,9 +324,14 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+
+ dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
+
++ ts_dev->prev_press = 1024;
++
+ reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE |
+- ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */
+- ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */
++ // (ATMEL_TSADCC_SLEEP) |
++#ifdef CONFIG_ATMEL_TSADCC_PRESS
++ (ATMEL_TSADCC_PRES) |
++#endif
++ (ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */
+ (prsc << 8) |
+ ((0x26 << 16) & ATMEL_TSADCC_STARTUP) |
+ ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0008-atmel_serial-adding-support-for-RS485.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0008-atmel_serial-adding-support-for-RS485.patch
new file mode 100644
index 0000000000..03cc5fab37
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0008-atmel_serial-adding-support-for-RS485.patch
@@ -0,0 +1,500 @@
+From 68cb211d548457278f6d5f16eb6a42bb4d67a024 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 13:58:30 +0100
+Subject: [PATCH 08/18] [atmel_serial] adding support for RS485
+
+---
+ arch/arm/include/asm/ioctls.h | 3 +
+ drivers/serial/atmel_serial.c | 238 +++++++++++++++++++++++++++++++++++------
+ include/linux/atmel_serial.h | 5 +
+ 3 files changed, 211 insertions(+), 35 deletions(-)
+
+diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h
+index a91d8a1..7f0b6d1 100644
+--- a/arch/arm/include/asm/ioctls.h
++++ b/arch/arm/include/asm/ioctls.h
+@@ -53,6 +53,9 @@
+ #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+
++#define TIOCGRS485 0x542E
++#define TIOCSRS485 0x542F
++
+ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+ #define FIOCLEX 0x5451
+ #define FIOASYNC 0x5452
+diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
+index 9d948bc..23f201f 100644
+--- a/drivers/serial/atmel_serial.c
++++ b/drivers/serial/atmel_serial.c
+@@ -38,12 +38,15 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/atmel_pdc.h>
+ #include <linux/atmel_serial.h>
++#include <linux/uaccess.h>
+
+ #include <asm/io.h>
+
+ #include <asm/mach/serial_at91.h>
+ #include <mach/board.h>
+
++#include <asm/gpio.h>
++
+ #ifdef CONFIG_ARM
+ #include <mach/cpu.h>
+ #include <mach/gpio.h>
+@@ -59,6 +62,9 @@
+
+ #include <linux/serial_core.h>
+
++static void atmel_start_rx(struct uart_port *port);
++static void atmel_stop_rx(struct uart_port *port);
++
+ #ifdef CONFIG_SERIAL_ATMEL_TTYAT
+
+ /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we
+@@ -93,6 +99,7 @@
+ #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR)
+ #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR)
+ #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR)
++#define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR)
+
+ /* PDC registers */
+ #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
+@@ -147,6 +154,12 @@ struct atmel_uart_port {
+ unsigned int irq_status_prev;
+
+ struct circ_buf rx_ring;
++
++ struct serial_rs485 rs485; /* rs485 settings */
++ unsigned int tx_done_mask;
++
++ int txe_gpio;
++ int active_low;
+ };
+
+ static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
+@@ -187,6 +200,49 @@ static bool atmel_use_dma_tx(struct uart_port *port)
+ }
+ #endif
+
++static void atmel_txe(struct uart_port *port, int onoff) {
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
++ if(!gpio_is_valid(atmel_port->txe_gpio))
++ return;
++ if(atmel_port->active_low)
++ onoff = !onoff;
++ gpio_set_value(atmel_port->txe_gpio, onoff);
++}
++
++/* Enable or disable the rs485 support */
++void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
++{
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
++ unsigned long flags;
++ unsigned int mode;
++
++ spin_lock_irqsave(&port->lock, flags);
++
++ mode = UART_GET_MR(port);
++
++ /* Resetting serial mode to RS232 (0x0) */
++ mode &= ~ATMEL_US_USMODE;
++
++ atmel_port->rs485 = *rs485conf;
++
++ if (rs485conf->flags & SER_RS485_ENABLED) {
++ dev_dbg(port->dev, "Setting UART to RS485\n");
++ atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
++ UART_PUT_TTGR(port, rs485conf->delay_rts_before_send);
++ mode |= ATMEL_US_USMODE_RS485;
++ } else {
++ dev_dbg(port->dev, "Setting UART to RS232\n");
++ if (atmel_use_dma_tx(port))
++ atmel_port->tx_done_mask = ATMEL_US_ENDTX |
++ ATMEL_US_TXBUFE;
++ else
++ atmel_port->tx_done_mask = ATMEL_US_TXRDY;
++ }
++ UART_PUT_MR(port, mode);
++
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
+ /*
+ * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
+ */
+@@ -202,6 +258,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
+ {
+ unsigned int control = 0;
+ unsigned int mode;
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+ #ifdef CONFIG_ARCH_AT91RM9200
+ if (cpu_is_at91rm9200()) {
+@@ -236,6 +293,17 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
+ mode |= ATMEL_US_CHMODE_LOC_LOOP;
+ else
+ mode |= ATMEL_US_CHMODE_NORMAL;
++
++ /* Resetting serial mode to RS232 (0x0) */
++ mode &= ~ATMEL_US_USMODE;
++
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
++ dev_dbg(port->dev, "Setting UART to RS485\n");
++ UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
++ mode |= ATMEL_US_USMODE_RS485;
++ } else {
++ dev_dbg(port->dev, "Setting UART to RS232\n");
++ }
+ UART_PUT_MR(port, mode);
+ }
+
+@@ -268,12 +336,17 @@ static u_int atmel_get_mctrl(struct uart_port *port)
+ */
+ static void atmel_stop_tx(struct uart_port *port)
+ {
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
++
+ if (atmel_use_dma_tx(port)) {
+ /* disable PDC transmit */
+ UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
+- UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+- } else
+- UART_PUT_IDR(port, ATMEL_US_TXRDY);
++ }
++ /* Disable interrupts */
++ UART_PUT_IDR(port, atmel_port->tx_done_mask);
++
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED)
++ atmel_start_rx(port);
+ }
+
+ /*
+@@ -281,17 +354,41 @@ static void atmel_stop_tx(struct uart_port *port)
+ */
+ static void atmel_start_tx(struct uart_port *port)
+ {
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
++
+ if (atmel_use_dma_tx(port)) {
+ if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN)
+ /* The transmitter is already running. Yes, we
+ really need this.*/
+ return;
+
+- UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED)
++ atmel_stop_rx(port);
++
+ /* re-enable PDC transmit */
+ UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
+- } else
+- UART_PUT_IER(port, ATMEL_US_TXRDY);
++ }
++ /* Enable interrupts */
++ UART_PUT_IER(port, atmel_port->tx_done_mask);
++ atmel_txe(port, 1);
++}
++
++
++/*
++ * start receiving - port is in process of being opened.
++ */
++static void atmel_start_rx(struct uart_port *port)
++{
++ UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */
++
++ if (atmel_use_dma_rx(port)) {
++ /* enable PDC controller */
++ UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
++ port->read_status_mask);
++ UART_PUT_PTCR(port, ATMEL_PDC_RXTEN);
++ } else {
++ UART_PUT_IER(port, ATMEL_US_RXRDY);
++ }
+ }
+
+ /*
+@@ -302,9 +399,12 @@ static void atmel_stop_rx(struct uart_port *port)
+ if (atmel_use_dma_rx(port)) {
+ /* disable PDC receive */
+ UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);
+- UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
+- } else
++ UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
++ port->read_status_mask);
++ } else {
+ UART_PUT_IDR(port, ATMEL_US_RXRDY);
++ }
++ atmel_txe(port, 1);
+ }
+
+ /*
+@@ -428,8 +528,9 @@ static void atmel_rx_chars(struct uart_port *port)
+ static void atmel_tx_chars(struct uart_port *port)
+ {
+ struct circ_buf *xmit = &port->state->xmit;
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+- if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {
++ if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) {
+ UART_PUT_CHAR(port, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+@@ -437,7 +538,7 @@ static void atmel_tx_chars(struct uart_port *port)
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+ return;
+
+- while (UART_GET_CSR(port) & ATMEL_US_TXRDY) {
++ while (UART_GET_CSR(port) & atmel_port->tx_done_mask) {
+ UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+@@ -449,7 +550,8 @@ static void atmel_tx_chars(struct uart_port *port)
+ uart_write_wakeup(port);
+
+ if (!uart_circ_empty(xmit))
+- UART_PUT_IER(port, ATMEL_US_TXRDY);
++ /* Enable interrupts */
++ UART_PUT_IER(port, atmel_port->tx_done_mask);
+ }
+
+ /*
+@@ -501,18 +603,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
+ {
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+- if (atmel_use_dma_tx(port)) {
+- /* PDC transmit */
+- if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) {
+- UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+- tasklet_schedule(&atmel_port->tasklet);
+- }
+- } else {
+- /* Interrupt transmit */
+- if (pending & ATMEL_US_TXRDY) {
+- UART_PUT_IDR(port, ATMEL_US_TXRDY);
+- tasklet_schedule(&atmel_port->tasklet);
+- }
++ if (pending & atmel_port->tx_done_mask) {
++ /* Either PDC or interrupt transmission */
++ UART_PUT_IDR(port, atmel_port->tx_done_mask);
++ tasklet_schedule(&atmel_port->tasklet);
+ }
+ }
+
+@@ -590,9 +684,15 @@ static void atmel_tx_dma(struct uart_port *port)
+
+ UART_PUT_TPR(port, pdc->dma_addr + xmit->tail);
+ UART_PUT_TCR(port, count);
+- /* re-enable PDC transmit and interrupts */
++ /* re-enable PDC transmit */
+ UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
+- UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
++ /* Enable interrupts */
++ UART_PUT_IER(port, atmel_port->tx_done_mask);
++ } else {
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
++ /* DMA done, stop TX, start RX for RS485 */
++ atmel_start_rx(port);
++ }
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+@@ -1017,6 +1117,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
+ {
+ unsigned long flags;
+ unsigned int mode, imr, quot, baud;
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+ /* Get current mode register */
+ mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
+@@ -1115,6 +1216,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
+ /* disable receiver and transmitter */
+ UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
+
++ /* Resetting serial mode to RS232 (0x0) */
++ mode &= ~ATMEL_US_USMODE;
++
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
++ dev_dbg(port->dev, "Setting UART to RS485\n");
++ UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
++ mode |= ATMEL_US_USMODE_RS485;
++ } else {
++ dev_dbg(port->dev, "Setting UART to RS232\n");
++ }
++
+ /* set the parity, stop bits and data size */
+ UART_PUT_MR(port, mode);
+
+@@ -1213,6 +1325,35 @@ static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser)
+ return ret;
+ }
+
++static int
++atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
++{
++ struct serial_rs485 rs485conf;
++
++ switch (cmd) {
++ case TIOCSRS485:
++ if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg,
++ sizeof(rs485conf)))
++ return -EFAULT;
++
++ atmel_config_rs485(port, &rs485conf);
++ break;
++
++ case TIOCGRS485:
++ if (copy_to_user((struct serial_rs485 *) arg,
++ &(to_atmel_uart_port(port)->rs485),
++ sizeof(rs485conf)))
++ return -EFAULT;
++ break;
++
++ default:
++ return -ENOIOCTLCMD;
++ }
++ return 0;
++}
++
++
++
+ static struct uart_ops atmel_pops = {
+ .tx_empty = atmel_tx_empty,
+ .set_mctrl = atmel_set_mctrl,
+@@ -1232,6 +1373,7 @@ static struct uart_ops atmel_pops = {
+ .config_port = atmel_config_port,
+ .verify_port = atmel_verify_port,
+ .pm = atmel_serial_pm,
++ .ioctl = atmel_ioctl,
+ };
+
+ /*
+@@ -1243,13 +1385,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
+ struct uart_port *port = &atmel_port->uart;
+ struct atmel_uart_data *data = pdev->dev.platform_data;
+
+- port->iotype = UPIO_MEM;
+- port->flags = UPF_BOOT_AUTOCONF;
+- port->ops = &atmel_pops;
+- port->fifosize = 1;
+- port->line = pdev->id;
+- port->dev = &pdev->dev;
+-
++ port->iotype = UPIO_MEM;
++ port->flags = UPF_BOOT_AUTOCONF;
++ port->ops = &atmel_pops;
++ port->fifosize = 1;
++ port->line = pdev->id;
++ port->dev = &pdev->dev;
+ port->mapbase = pdev->resource[0].start;
+ port->irq = pdev->resource[1].start;
+
+@@ -1277,8 +1418,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
+
+ atmel_port->use_dma_rx = data->use_dma_rx;
+ atmel_port->use_dma_tx = data->use_dma_tx;
+- if (atmel_use_dma_tx(port))
++ atmel_port->rs485 = data->rs485;
++ /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
++ if (atmel_port->rs485.flags & SER_RS485_ENABLED)
++ atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
++ else if (atmel_use_dma_tx(port)) {
+ port->fifosize = PDC_BUFFER_SIZE;
++ atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;
++ } else {
++ atmel_port->tx_done_mask = ATMEL_US_TXRDY;
++ }
+ }
+
+ /*
+@@ -1312,6 +1461,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch)
+ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ {
+ struct uart_port *port = &atmel_ports[co->index].uart;
++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ unsigned int status, imr;
+ unsigned int pdc_tx;
+
+@@ -1319,7 +1469,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ * First, save IMR and then disable interrupts
+ */
+ imr = UART_GET_IMR(port);
+- UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY);
++ UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask);
+
+ /* Store PDC transmit status and disable it */
+ pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN;
+@@ -1333,7 +1483,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ */
+ do {
+ status = UART_GET_CSR(port);
+- } while (!(status & ATMEL_US_TXRDY));
++ } while (!(status & atmel_port->tx_done_mask));
+
+ /* Restore PDC transmit status */
+ if (pdc_tx)
+@@ -1530,6 +1680,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
+ struct atmel_uart_port *port;
+ void *data;
+ int ret;
++ struct atmel_serial_data *pdata;
+
+ BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
+
+@@ -1561,12 +1712,27 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
+ clk_disable(port->clk);
+ }
+ #endif
++ pdata = NULL;
++ //pdata = pdev->private_data;
++ if(pdata) {
++ port->txe_gpio = pdata->txe_gpio;
++ port->active_low = pdata->active_low;
++ if(gpio_is_valid(port->txe_gpio)) {
++ gpio_request(port->txe_gpio, "TXE");
++ gpio_direction_output(port->txe_gpio, port->active_low);
++ }
++ } else {
++ port->txe_gpio = -ENODEV;
++ }
+
+ device_init_wakeup(&pdev->dev, 1);
+ platform_set_drvdata(pdev, port);
+
++
+ return 0;
+
++ if(gpio_is_valid(port->txe_gpio))
++ gpio_free(port->txe_gpio);
+ err_add_port:
+ kfree(port->rx_ring.buf);
+ port->rx_ring.buf = NULL;
+@@ -1585,6 +1751,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ int ret = 0;
+
++ if(gpio_is_valid(atmel_port->txe_gpio))
++ gpio_free(atmel_port->txe_gpio);
+ device_init_wakeup(&pdev->dev, 0);
+ platform_set_drvdata(pdev, NULL);
+
+diff --git a/include/linux/atmel_serial.h b/include/linux/atmel_serial.h
+index fd68337..ac15147 100644
+--- a/include/linux/atmel_serial.h
++++ b/include/linux/atmel_serial.h
+@@ -124,4 +124,9 @@
+ #define ATMEL_US_NER 0x44 /* Number of Errors Register */
+ #define ATMEL_US_IF 0x4c /* IrDA Filter Register */
+
++struct atmel_serial_data {
++ int txe_gpio;
++ int active_low;
++};
++
+ #endif
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0009-ICnova-add-support-for-ADB3000-revB.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0009-ICnova-add-support-for-ADB3000-revB.patch
new file mode 100644
index 0000000000..622cf2a05d
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0009-ICnova-add-support-for-ADB3000-revB.patch
@@ -0,0 +1,117 @@
+From 44a7e4c328dc2d1d40525fead5d80d28c3e8758c Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 14:00:48 +0100
+Subject: [PATCH 09/18] [ICnova] add support for ADB3000 revB
+
+This changed the numbering of UARTs and the atmel-tsadcc was
+replaced by a ads7846.
+---
+ arch/arm/mach-at91/board-icnova_adb3000.c | 42 +++++++++++++++++++++++++---
+ 1 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-icnova_adb3000.c b/arch/arm/mach-at91/board-icnova_adb3000.c
+index 6006faa..7bbe786 100644
+--- a/arch/arm/mach-at91/board-icnova_adb3000.c
++++ b/arch/arm/mach-at91/board-icnova_adb3000.c
+@@ -89,14 +89,14 @@ static void __init ek_map_io(void)
+ at91sam9g45_initialize(12000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+- at91_register_uart(0, 0, 0);
++ at91_register_uart(0, 4, 0);
+
+ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
+ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
+ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
+- at91_register_uart(AT91SAM9G45_ID_US3, 4, 0);
++ at91_register_uart(AT91SAM9G45_ID_US3, 0, 0);
+
+- /* set serial console to ttyS0 (ie, DBGU) */
++ /* set serial console to ttyS0 */
+ at91_set_serial_console(0);
+ }
+
+@@ -124,7 +124,32 @@ static struct i2c_board_info icnova_i2c[] = {
+ * SPI devices.
+ */
+
++#ifndef CONFIG_BOARD_ICNOVA_TOUCH_INT
++#define CONFIG_BOARD_ICNOVA_ADS7846_IRQ AT91_PIN_PD18
++#define CONFIG_BOARD_ICNOVA_ADS7846_CS 2
++static struct ads7846_platform_data ads_info = {
++ .model = 7846,
++ .vref_delay_usecs = 100,
++ .gpio_pendown = CONFIG_BOARD_ICNOVA_ADS7846_IRQ,
++ .x_min = 330,
++ .y_min = 3700,
++ .x_max = 3700,
++ .y_max = 330,
++ .settle_delay_usecs = 50,
++};
++#endif
++
+ static struct spi_board_info ek_spi_devices[] = {
++#ifndef CONFIG_BOARD_ICNOVA_TOUCH_INT
++ {
++ .modalias = "ads7846",
++ .max_speed_hz = 125000 * 26,
++ .chip_select = CONFIG_BOARD_ICNOVA_ADS7846_CS,
++ .platform_data = &ads_info,
++ .bus_num = 0,
++ .controller_data = (void *)AT91_PIN_PD25,
++ },
++#endif
+ };
+
+
+@@ -221,8 +246,8 @@ static struct fb_videomode at91_tft_vga_modes[] = {
+ .xres = 800, .yres = 480,
+ .pixclock = KHZ2PICOS(33260),
+
+- .left_margin = 128, .right_margin = 88,
+- .upper_margin = 27, .lower_margin = 16,
++ .left_margin = 178, .right_margin = 38,
++ .upper_margin = 35, .lower_margin = 8,
+ .hsync_len = 40, .vsync_len = 2,
+
+ .vmode = FB_VMODE_NONINTERLACED,
+@@ -263,6 +288,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+ #endif
+
+
++#ifdef CONFIG_BOARD_ICNOVA_TOUCH_INT
+ /*
+ * Touchscreen
+ */
+@@ -271,6 +297,7 @@ static struct at91_tsadcc_data ek_tsadcc_data = {
+ .pendet_debounce = 0x0d,
+ .ts_sample_hold_time = 0x0a,
+ };
++#endif
+
+ /*
+ * LEDs
+@@ -336,6 +363,9 @@ static void __init ek_board_init(void)
+ /* USB HS Device */
+ at91_add_device_usba(NULL);
+ /* SPI */
++#ifndef CONFIG_BOARD_ICNOVA_TOUCH_INT
++ ek_spi_devices[0].irq = gpio_to_irq(CONFIG_BOARD_ICNOVA_ADS7846_IRQ),
++#endif
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* MMC */
+ at91_add_device_mci(0, &ek_mmc_data);
+@@ -354,8 +384,10 @@ static void __init ek_board_init(void)
+ gpio_direction_output(AT91_PIN_PE6, 1);
+
+ at91_add_device_lcdc(&ek_lcdc_data);
++#ifdef CONFIG_BOARD_ICNOVA_TOUCH_INT
+ /* Touch Screen */
+ at91_add_device_tsadcc(&ek_tsadcc_data);
++#endif
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* FPGA-Interface */
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0010-atmel-pwm-Making-driver-selectable-for-SAM9G45.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0010-atmel-pwm-Making-driver-selectable-for-SAM9G45.patch
new file mode 100644
index 0000000000..998459facd
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0010-atmel-pwm-Making-driver-selectable-for-SAM9G45.patch
@@ -0,0 +1,26 @@
+From 636100a205fc74fe9a580792e0c81753faa827cf Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 14:03:02 +0100
+Subject: [PATCH 10/18] [atmel-pwm] Making driver selectable for SAM9G45
+
+The Core of the AT91SAM9G45 is compatible with this PWMdriver.
+---
+ drivers/misc/Kconfig | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 072c8a4..8d0a517 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -29,7 +29,7 @@ config AD525X_DPOT
+
+ config ATMEL_PWM
+ tristate "Atmel AT32/AT91 PWM support"
+- depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
++ depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_AT91SAM9G45
+ help
+ This option enables device driver support for the PWM channels
+ on certain Atmel processors. Pulse Width Modulation is used for
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0011-hwmon-atm_pwm-adding-new-Userspace-atmel-pwm-interfa.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0011-hwmon-atm_pwm-adding-new-Userspace-atmel-pwm-interfa.patch
new file mode 100644
index 0000000000..cde5a814a4
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0011-hwmon-atm_pwm-adding-new-Userspace-atmel-pwm-interfa.patch
@@ -0,0 +1,300 @@
+From c1196b5a31f90c0af0efbf8b2e9263b7cafab767 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 14:16:18 +0100
+Subject: [PATCH 11/18] [hwmon/atm_pwm] adding new Userspace<->atmel-pwm interface
+
+Now the PWM-Outputs can be configured from userspace, if the
+board-file does set up these pins.
+---
+ drivers/hwmon/Kconfig | 8 ++
+ drivers/hwmon/Makefile | 1 +
+ drivers/hwmon/atm_pwm.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 255 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/hwmon/atm_pwm.c
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 68cf877..6cdc1af 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -216,6 +216,14 @@ config SENSORS_ADT7475
+ This driver can also be build as a module. If so, the module
+ will be called adt7475.
+
++config SENSORS_ATM_PWM
++ tristate "Atmel PWM"
++ depends on ATMEL_PWM
++ help
++ This is some kind of userspace-interface for the PWMs found in some
++ Atmel Processors (like AP7000)
++ Your Board-Code must set the needed Pins to be PWM!
++
+ config SENSORS_K8TEMP
+ tristate "AMD Athlon64/FX or Opteron temperature sensor"
+ depends on X86 && PCI && EXPERIMENTAL
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 4bc215c..33ee45f 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
+ obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
+ obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
+ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
++obj-$(CONFIG_SENSORS_ATM_PWM) += atm_pwm.o
+ obj-$(CONFIG_SENSORS_AMS) += ams/
+ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
+ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
+diff --git a/drivers/hwmon/atm_pwm.c b/drivers/hwmon/atm_pwm.c
+new file mode 100644
+index 0000000..1f5bc8f
+--- /dev/null
++++ b/drivers/hwmon/atm_pwm.c
+@@ -0,0 +1,246 @@
++/*
++ * Copyright (C) 2009 by Benjamin Tietz <benjamin.tietz@in-circuit.de>
++ * based on the atmel-pwm-bl.c
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ */
++#define DEBUG
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/clk.h>
++#include <linux/gpio.h>
++#include <linux/atmel_pwm.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/sysfs.h>
++
++#define ATMEL_PWM_NCHN 4
++#define ATMEL_PWM_MAX 1000
++
++struct atmel_pwm_hwmon {
++ unsigned int pwm_channel;
++ struct hwmon_device *hwdev;
++ struct platform_device *pdev;
++ struct pwm_channel pwmc[ATMEL_PWM_NCHN];
++ struct device dev;
++};
++
++static ssize_t atmel_pwm_hwmon_set_duty(struct device *dev,
++ struct device_attribute *devattr, const char *buf, size_t count)
++{
++ struct platform_device *pdev =
++ container_of(dev, struct platform_device, dev);
++ struct atmel_pwm_hwmon *pwmhw = platform_get_drvdata(pdev);
++ unsigned int pwm_duty = simple_strtoul(buf, NULL, 10);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
++ struct pwm_channel *pwmc = &(pwmhw->pwmc[attr->index]);
++
++ if(pwm_duty > ATMEL_PWM_MAX)
++ pwm_duty = ATMEL_PWM_MAX;
++ pwm_channel_writel(pwmc, PWM_CUPD, pwm_duty);
++
++ return count;
++}
++
++static ssize_t atmel_pwm_hwmon_get_duty(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ struct platform_device *pdev =
++ container_of(dev, struct platform_device, dev);
++ struct atmel_pwm_hwmon *pwmhw = platform_get_drvdata(pdev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
++ struct pwm_channel *pwmc = &(pwmhw->pwmc[attr->index]);
++
++ return sprintf(buf, "%d\n", pwm_channel_readl(pwmc, PWM_CDTY));
++}
++
++static ssize_t atmel_pwm_hwmon_set_freq(struct device *dev,
++ struct device_attribute *devattr, const char *buf, size_t count)
++{
++ struct platform_device *pdev =
++ container_of(dev, struct platform_device, dev);
++ struct atmel_pwm_hwmon *pwmhw = platform_get_drvdata(pdev);
++ int pwm_freq = simple_strtoul(buf, NULL, 10);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
++ struct pwm_channel *pwmc = &(pwmhw->pwmc[attr->index]);
++ unsigned long pwm_rate = pwmc->mck;
++ unsigned long prescale;
++
++
++ pwm_channel_disable(pwmc);
++ if(!pwm_freq)
++ return count;
++
++ prescale = DIV_ROUND_UP(pwm_rate, (pwm_freq * ATMEL_PWM_MAX)) -1;
++ /*
++ * Prescale must be power of two and maximum 0xf in size because of
++ * hardware limit. PWM speed will be:
++ * PWM module clock speed / (2 ^ prescale).
++ */
++ prescale = fls(prescale);
++ if (prescale > 0xa)
++ prescale = 0xa;
++
++ pwm_channel_writel(pwmc, PWM_CPRD, ATMEL_PWM_MAX);
++ pwm_channel_writel(pwmc, PWM_CMR, prescale);
++ pwm_channel_enable(pwmc);
++
++ return count;
++}
++
++static ssize_t atmel_pwm_hwmon_get_freq(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ struct platform_device *pdev =
++ container_of(dev, struct platform_device, dev);
++ struct atmel_pwm_hwmon *pwmhw = platform_get_drvdata(pdev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
++ struct pwm_channel *pwmc = &(pwmhw->pwmc[attr->index]);
++ unsigned long pwm_freq = pwm_channel_readl(pwmc, PWM_CMR);
++ pwm_freq = 1<<pwm_freq;
++ pwm_freq = pwmc->mck / pwm_freq / ATMEL_PWM_MAX;
++
++ return sprintf(buf, "%lu\n", pwm_freq);
++}
++
++static SENSOR_DEVICE_ATTR(pwm0_freq, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_freq, atmel_pwm_hwmon_set_freq, 0);
++static SENSOR_DEVICE_ATTR(pwm0, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_duty, atmel_pwm_hwmon_set_duty, 0);
++static SENSOR_DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_freq, atmel_pwm_hwmon_set_freq, 1);
++static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_duty, atmel_pwm_hwmon_set_duty, 1);
++static SENSOR_DEVICE_ATTR(pwm2_freq, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_freq, atmel_pwm_hwmon_set_freq, 2);
++static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_duty, atmel_pwm_hwmon_set_duty, 2);
++static SENSOR_DEVICE_ATTR(pwm3_freq, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_freq, atmel_pwm_hwmon_set_freq, 3);
++static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO,
++ atmel_pwm_hwmon_get_duty, atmel_pwm_hwmon_set_duty, 3);
++
++static struct attribute *atmel_pwm_hwmon_attributes[] = {
++ &sensor_dev_attr_pwm0_freq.dev_attr.attr,
++ &sensor_dev_attr_pwm0.dev_attr.attr,
++ NULL,
++ &sensor_dev_attr_pwm1_freq.dev_attr.attr,
++ &sensor_dev_attr_pwm1.dev_attr.attr,
++ NULL,
++ &sensor_dev_attr_pwm2_freq.dev_attr.attr,
++ &sensor_dev_attr_pwm2.dev_attr.attr,
++ NULL,
++ &sensor_dev_attr_pwm3_freq.dev_attr.attr,
++ &sensor_dev_attr_pwm3.dev_attr.attr,
++ NULL,
++};
++
++static const struct attribute_group atmel_pwm_hwmon_group[] = {
++ {
++ .attrs = &(atmel_pwm_hwmon_attributes[0]),
++ },
++ {
++ .attrs = &(atmel_pwm_hwmon_attributes[3]),
++ },
++ {
++ .attrs = &(atmel_pwm_hwmon_attributes[6]),
++ },
++ {
++ .attrs = &(atmel_pwm_hwmon_attributes[9]),
++ },
++};
++
++static int atmel_pwm_hwmon_probe(struct platform_device *pdev)
++{
++ struct atmel_pwm_hwmon *pwmhw;
++ int retval;
++ int i;
++
++ pwmhw = kzalloc(sizeof(struct atmel_pwm_hwmon), GFP_KERNEL);
++ if (!pwmhw)
++ return -ENOMEM;
++
++ pwmhw->pdev = pdev;
++
++ for(i=0; i< ATMEL_PWM_NCHN; i++) {
++ retval = pwm_channel_alloc(i, &pwmhw->pwmc[i]);
++ if(retval) continue;
++
++ retval = sysfs_create_group(&pdev->dev.kobj,
++ &(atmel_pwm_hwmon_group[i]));
++ if(retval)
++ goto err_free_pwm;
++ }
++
++ pwmhw->hwdev = hwmon_device_register(&pdev->dev);
++ if(IS_ERR(pwmhw->hwdev)) {
++ dev_dbg(&pdev->dev, "Can't register hwmon-device\n");
++ retval = PTR_ERR(pwmhw->hwdev);
++ goto err_hwmon;
++ }
++
++ platform_set_drvdata(pdev, pwmhw);
++
++ return 0;
++
++//err_free_hwmon_dev:
++ platform_set_drvdata(pdev, NULL);
++ hwmon_device_unregister(pwmhw->hwdev);
++err_hwmon:
++ i = ATMEL_PWM_NCHN;
++err_free_pwm:
++ for(i--;i>=0;i--) {
++ sysfs_remove_group(&pdev->dev.kobj,
++ &(atmel_pwm_hwmon_group[i]));
++ pwm_channel_free(&pwmhw->pwmc[i]);
++ }
++//err_free_mem:
++ kfree(pwmhw);
++ return retval;
++}
++
++static int __exit atmel_pwm_hwmon_remove(struct platform_device *pdev)
++{
++ struct atmel_pwm_hwmon *pwmhw = platform_get_drvdata(pdev);
++ int i;
++
++ platform_set_drvdata(pdev, NULL);
++ hwmon_device_unregister(pwmhw->hwdev);
++ for(i=0;i<ATMEL_PWM_NCHN;i++) {
++ sysfs_remove_group(&pdev->dev.kobj,
++ &(atmel_pwm_hwmon_group[i]));
++ pwm_channel_disable(&pwmhw->pwmc[i]);
++ pwm_channel_free(&pwmhw->pwmc[i]);
++ }
++ kfree(pwmhw);
++ return 0;
++}
++
++static struct platform_driver atmel_pwm_hwmon_driver = {
++ .driver = {
++ .name = "atmel-pwm-hwmon",
++ },
++ /* REVISIT add suspend() and resume() */
++ .remove = __exit_p(atmel_pwm_hwmon_remove),
++};
++
++static int __init atmel_pwm_hwmon_init(void)
++{
++ return platform_driver_probe(&atmel_pwm_hwmon_driver, atmel_pwm_hwmon_probe);
++}
++module_init(atmel_pwm_hwmon_init);
++
++static void __exit atmel_pwm_hwmon_exit(void)
++{
++ platform_driver_unregister(&atmel_pwm_hwmon_driver);
++}
++module_exit(atmel_pwm_hwmon_exit);
++
++MODULE_AUTHOR("Benjamin Tietz <benjamin.tietz@in-circuit.de>");
++MODULE_DESCRIPTION("Atmel PWM hwmon driver");
++MODULE_LICENSE("GPL");
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0012-ICnova-configuring-the-buzzer.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0012-ICnova-configuring-the-buzzer.patch
new file mode 100644
index 0000000000..20c7c7a315
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0012-ICnova-configuring-the-buzzer.patch
@@ -0,0 +1,38 @@
+From d88aa9d978fd2eca603204e33e452437dad8ce70 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin@marvin.local.in-circuit.de>
+Date: Wed, 15 Dec 2010 14:16:58 +0100
+Subject: [PATCH 12/18] [ICnova] configuring the buzzer
+
+The buzzer is now accessible via the hwmon interface
+---
+ arch/arm/mach-at91/board-icnova_adb1000.c | 7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-icnova_adb1000.c b/arch/arm/mach-at91/board-icnova_adb1000.c
+index b292acf..dec1597 100644
+--- a/arch/arm/mach-at91/board-icnova_adb1000.c
++++ b/arch/arm/mach-at91/board-icnova_adb1000.c
+@@ -303,6 +303,10 @@ static struct gpio_led ek_leds[] = {
+ },
+ };
+
++static struct platform_device icnova_pwmdev = {
++ .name = "atmel-pwm-hwmon",
++ .id = 0,
++};
+
+ static void __init ek_board_init(void)
+ {
+@@ -339,6 +343,9 @@ static void __init ek_board_init(void)
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
++ /* Buzzer */
++ at91_add_device_pwm(1<<AT91_PWM1);
++ platform_device_register(&icnova_pwmdev);
+ }
+
+ MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova G45")
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0013-sound-soc-adding-ssm2603-attached-to-atmel-ssc.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0013-sound-soc-adding-ssm2603-attached-to-atmel-ssc.patch
new file mode 100644
index 0000000000..f7a8a01dd8
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0013-sound-soc-adding-ssm2603-attached-to-atmel-ssc.patch
@@ -0,0 +1,337 @@
+From 8e5d4b938e4aeb0e091eaccfdfa4824a23a007aa Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:42:52 +0100
+Subject: [PATCH 13/18] [sound/soc] adding ssm2603 attached to atmel-ssc
+
+This will add support for an SSM2603 I2S-Codec connected to
+an Atmel SSC-Interface.
+---
+ sound/soc/atmel/Kconfig | 9 ++
+ sound/soc/atmel/Makefile | 1 +
+ sound/soc/atmel/atmel_ssc_dai.c | 9 +-
+ sound/soc/atmel/snd-soc-ssm2603.c | 254 +++++++++++++++++++++++++++++++++++++
+ 4 files changed, 270 insertions(+), 3 deletions(-)
+ create mode 100644 sound/soc/atmel/snd-soc-ssm2603.c
+
+diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
+index e720d5e..ad2b560 100644
+--- a/sound/soc/atmel/Kconfig
++++ b/sound/soc/atmel/Kconfig
+@@ -14,6 +14,15 @@ config SND_ATMEL_SOC_SSC
+ ATMEL SSC interface. You will also needs to select the individual
+ machine drivers to support below.
+
++config SND_AT91_SOC_ICNOVA_SSM2603
++ tristate "SoC Audio support for SSM2603-based ICnova board"
++ depends on ATMEL_SSC && ( MACH_ICNOVA_ADB1000 || MACH_ICNOVA_ADB4000) && SND_ATMEL_SOC
++ select SND_ATMEL_SOC_SSC
++ select SND_SOC_SSM2602
++ help
++ Say Y or M if you want to add support for SoC audio on SSM2603
++ based board.
++
+ config SND_AT91_SOC_SAM9G20_WM8731
+ tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
+ depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
+diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
+index e7ea56b..85f553e 100644
+--- a/sound/soc/atmel/Makefile
++++ b/sound/soc/atmel/Makefile
+@@ -14,3 +14,4 @@ snd-soc-playpaq-objs := playpaq_wm8510.o
+ obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
+ obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
+ obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
++obj-$(CONFIG_SND_AT91_SOC_ICNOVA_SSM2603) += snd-soc-ssm2603.o
+diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
+index e588e63..fc2da03 100644
+--- a/sound/soc/atmel/atmel_ssc_dai.c
++++ b/sound/soc/atmel/atmel_ssc_dai.c
+@@ -48,7 +48,7 @@
+ #include "atmel_ssc_dai.h"
+
+
+-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
++#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91SAM9G45)
+ #define NUM_SSC_DEVICES 1
+ #else
+ #define NUM_SSC_DEVICES 3
+@@ -165,11 +165,14 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
+ struct atmel_ssc_info *ssc_p = dev_id;
+ struct atmel_pcm_dma_params *dma_params;
+ u32 ssc_sr;
++ u32 ssc_imr;
+ u32 ssc_substream_mask;
+ int i;
+
+- ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
+- & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
++ ssc_imr = (unsigned long) ssc_readl(ssc_p->ssc->regs, IMR);
++ ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR);
++ pr_debug("SSC_DAI got IRQ: %08lx & %08lx\n", ssc_sr, ssc_imr);
++ ssc_sr &= ssc_imr;
+
+ /*
+ * Loop through the substreams attached to this SSC. If
+diff --git a/sound/soc/atmel/snd-soc-ssm2603.c b/sound/soc/atmel/snd-soc-ssm2603.c
+new file mode 100644
+index 0000000..c471102
+--- /dev/null
++++ b/sound/soc/atmel/snd-soc-ssm2603.c
+@@ -0,0 +1,254 @@
++/*
++ * File: sound/soc/atmel/snd-soc-ssm2602.c
++ * Author: Benjamin Tietz <benjamin.tietz@in-circuit.de>
++ *
++ * Created: Thu Octobre 21 2010
++ * Description: board driver for SSM2603 sound chip
++ *
++ * 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, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#define DEBUG
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/device.h>
++
++#include <linux/atmel-ssc.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/pcm_params.h>
++
++#include <asm/dma.h>
++#include <linux/gpio.h>
++#include "../codecs/ssm2602.h"
++#include "atmel-pcm.h"
++#include "atmel_ssc_dai.h"
++
++static struct snd_soc_card atmel_ssm2603;
++
++static int atmel_ssm2603_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
++ unsigned int clk = 0;
++ int ret = 0;
++
++ pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
++ params_format(params));
++ /*
++ * If you are using a crystal source which frequency is not 12MHz
++ * then modify the below case statement with frequency of the crystal.
++ *
++ * If you are using the SPORT to generate clocking then this is
++ * where to do it.
++ */
++
++ switch (params_rate(params)) {
++ case 8000:
++ case 16000:
++ case 48000:
++ case 96000:
++ case 11025:
++ case 22050:
++ case 44100:
++ clk = 12000000;
++ break;
++ }
++
++ /*
++ * CODEC is master for BCLK and LRC in this configuration.
++ */
++
++ /* set codec DAI configuration */
++ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0)
++ return ret;
++ /* set cpu DAI configuration */
++ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0)
++ return ret;
++
++ ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
++ SND_SOC_CLOCK_IN);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++#if 0
++static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
++ SND_SOC_DAPM_MIC("Int Mic", NULL),
++ SND_SOC_DAPM_SPK("Ext Spk", NULL),
++};
++
++static const struct snd_soc_dapm_route intercon[] = {
++
++ /* speaker connected to LHPOUT */
++ {"Ext Spk", NULL, "LHPOUT"},
++
++ /* mic is connected to Mic Jack, with WM8731 Mic Bias */
++ {"MICIN", NULL, "Mic Bias"},
++ {"Mic Bias", NULL, "Int Mic"},
++};
++
++/*
++ * Logic for a wm8731 as connected on a at91sam9g20ek board.
++ */
++static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
++{
++ struct snd_soc_dai *codec_dai = &codec->dai[0];
++ int ret;
++
++ printk(KERN_DEBUG
++ "at91sam9g20ek_wm8731 "
++ ": at91sam9g20ek_wm8731_init() called\n");
++
++ ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, 12000000,
++ SND_SOC_CLOCK_IN);
++ if (ret < 0) {
++ printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
++ return ret;
++ }
++
++ /* Add specific widgets */
++ snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
++ ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
++ /* Set up specific audio path interconnects */
++ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
++
++ /* not connected */
++ snd_soc_dapm_nc_pin(codec, "RLINEIN");
++ snd_soc_dapm_nc_pin(codec, "LLINEIN");
++
++ snd_soc_dapm_enable_pin(codec, "Int Mic");
++
++ /* always connected */
++ snd_soc_dapm_enable_pin(codec, "Ext Spk");
++
++ snd_soc_dapm_sync(codec);
++
++ return 0;
++}
++#endif
++
++static struct snd_soc_ops atmel_ssm2603_ops = {
++ .hw_params = atmel_ssm2603_hw_params,
++};
++
++static struct snd_soc_dai_link atmel_ssm2603_dai = {
++ .name = "ssm2603",
++ .stream_name = "SSM2603",
++ .cpu_dai = &atmel_ssc_dai[0],
++ .codec_dai = &ssm2602_dai,
++#if 0
++ .init = at91sam9g20ek_wm8731_init,
++#endif
++ .ops = &atmel_ssm2603_ops,
++};
++
++/*
++ * SSM2603 2 wire address is determined by CSB
++ * state during powerup.
++ * low = 0x1a
++ * high = 0x1b
++ */
++
++static struct ssm2602_setup_data atmel_ssm2603_setup = {
++ .i2c_bus = 1,
++ .i2c_address = 0x1b,
++};
++
++static struct snd_soc_card atmel_ssm2603 = {
++ .name = "atmel_ssm2603",
++ .platform = &atmel_soc_platform,
++ .dai_link = &atmel_ssm2603_dai,
++ .num_links = 1,
++};
++
++static struct snd_soc_device atmel_ssm2603_snd_devdata = {
++ .card = &atmel_ssm2603,
++ .codec_dev = &soc_codec_dev_ssm2602,
++ .codec_data = &atmel_ssm2603_setup,
++};
++
++static struct platform_device *atmel_ssm2603_snd_device;
++
++static int __init atmel_ssm2603_init(void)
++{
++ struct atmel_ssc_info *ssc_p = atmel_ssm2603_dai.cpu_dai->private_data;
++ struct ssc_device *ssc = NULL;
++ int ret;
++
++ pr_debug("%s enter\n", __func__);
++ /*
++ * Request SSC device
++ */
++ ssc = ssc_request(0);
++ if (IS_ERR(ssc)) {
++ printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
++ ret = PTR_ERR(ssc);
++ ssc = NULL;
++ goto err_ssc;
++ }
++ ssc_p->ssc = ssc;
++
++ atmel_ssm2603_snd_device = platform_device_alloc("soc-audio", -1);
++ if (!atmel_ssm2603_snd_device) {
++ pr_debug("Can't allocate device\n");
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(atmel_ssm2603_snd_device,
++ &atmel_ssm2603_snd_devdata);
++ atmel_ssm2603_snd_devdata.dev = &atmel_ssm2603_snd_device->dev;
++ ret = platform_device_add(atmel_ssm2603_snd_device);
++
++ if (ret) {
++ pr_debug("Can't add device\n");
++ platform_device_put(atmel_ssm2603_snd_device);
++ }
++
++ return ret;
++
++ ssc_free(ssc);
++ ssc_p->ssc = NULL;
++err_ssc:
++ return ret;
++}
++
++static void __exit atmel_ssm2603_exit(void)
++{
++ pr_debug("%s enter\n", __func__);
++ platform_device_unregister(atmel_ssm2603_snd_device);
++}
++
++module_init(atmel_ssm2603_init);
++module_exit(atmel_ssm2603_exit);
++
++/* Module information */
++MODULE_AUTHOR("Benjamin Tietz");
++MODULE_DESCRIPTION("ALSA SoC SSM2603 ADB4000");
++MODULE_LICENSE("GPL");
++
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0014-ICnova-ADB1000-Adding-BPP-to-16.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0014-ICnova-ADB1000-Adding-BPP-to-16.patch
new file mode 100644
index 0000000000..c6e9e5244c
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0014-ICnova-ADB1000-Adding-BPP-to-16.patch
@@ -0,0 +1,27 @@
+From c500d362b621070c95ed85a5bf9b2ed4e8797d14 Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:44:47 +0100
+Subject: [PATCH 14/18] [ICnova ADB1000] Adding BPP to 16
+
+As this increases the overall system-performance massivly, the
+BitsPerPixel where reduced to 16.
+---
+ arch/arm/mach-at91/board-icnova_adb1000.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/board-icnova_adb1000.c b/arch/arm/mach-at91/board-icnova_adb1000.c
+index dec1597..c6c0d50 100644
+--- a/arch/arm/mach-at91/board-icnova_adb1000.c
++++ b/arch/arm/mach-at91/board-icnova_adb1000.c
+@@ -261,7 +261,7 @@ static struct fb_monspecs at91fb_default_monspecs = {
+ /* Driver datas */
+ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .lcdcon_is_backlight = true,
+- .default_bpp = 24,
++ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0015-ADS7846-Adding-option-to-support-fuzz-on-input.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0015-ADS7846-Adding-option-to-support-fuzz-on-input.patch
new file mode 100644
index 0000000000..69a7024726
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0015-ADS7846-Adding-option-to-support-fuzz-on-input.patch
@@ -0,0 +1,47 @@
+From 5a9ad893301d24de3b9c3c43ddd8948dc426817b Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:46:55 +0100
+Subject: [PATCH 15/18] [ADS7846] Adding option to support fuzz on input.
+
+To calm down the reactness of the touch input, the fuzzing can be
+set. Now the board-driver is able to set this value for a specific
+board, too.
+---
+ drivers/input/touchscreen/ads7846.c | 4 ++--
+ include/linux/spi/ads7846.h | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index 52d2ca1..64d6f04 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -968,11 +968,11 @@ static int __devinit ads7846_probe(struct spi_device *spi)
+ input_set_abs_params(input_dev, ABS_X,
+ pdata->x_min ? : 0,
+ pdata->x_max ? : MAX_12BIT,
+- 0, 0);
++ pdata->xy_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_Y,
+ pdata->y_min ? : 0,
+ pdata->y_max ? : MAX_12BIT,
+- 0, 0);
++ pdata->xy_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE,
+ pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
+index 51948eb..c52a1e6 100644
+--- a/include/linux/spi/ads7846.h
++++ b/include/linux/spi/ads7846.h
+@@ -39,6 +39,8 @@ struct ads7846_platform_data {
+ u16 y_min, y_max;
+ u16 pressure_min, pressure_max;
+
++ u16 xy_fuzz;
++
+ u16 debounce_max; /* max number of additional readings
+ * per sample */
+ u16 debounce_tol; /* tolerance used for filtering */
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0016-ADB4000-Adding-support-for-the-IO-Processor.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0016-ADB4000-Adding-support-for-the-IO-Processor.patch
new file mode 100644
index 0000000000..cd63f9eb99
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0016-ADB4000-Adding-support-for-the-IO-Processor.patch
@@ -0,0 +1,1785 @@
+From babb2d6e7ec94f3ff102298a34862baf47eb466f Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:53:13 +0100
+Subject: [PATCH 16/18] [ADB4000] Adding support for the IO-Processor
+
+The ICnova ADB4000 is equipped with an IO-Processor, adding more IOs,
+analog inputs and a buzzer.
+---
+ drivers/misc/Kconfig | 1 +
+ drivers/misc/Makefile | 1 +
+ drivers/misc/adb4000/Kconfig | 86 +++
+ drivers/misc/adb4000/Makefile | 2 +
+ drivers/misc/adb4000/spi_comm.c | 107 +++
+ drivers/misc/adb4000/spi_comm.h | 49 ++
+ drivers/misc/adb4000/supervisor.c | 1411 +++++++++++++++++++++++++++++++++++++
+ drivers/misc/adb4000/supervisor.h | 46 ++
+ 8 files changed, 1703 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/misc/adb4000/Kconfig
+ create mode 100644 drivers/misc/adb4000/Makefile
+ create mode 100644 drivers/misc/adb4000/spi_comm.c
+ create mode 100644 drivers/misc/adb4000/spi_comm.h
+ create mode 100644 drivers/misc/adb4000/supervisor.c
+ create mode 100644 drivers/misc/adb4000/supervisor.h
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 8d0a517..c8aa1e2 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -296,6 +296,7 @@ source "drivers/misc/c2port/Kconfig"
+ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+ source "drivers/misc/iwmc3200top/Kconfig"
++source "drivers/misc/adb4000/Kconfig"
+
+ config FPGA_SRAM
+ tristate "FPGA-SRAM Interface"
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 61fe337..1b1e4f4 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -29,3 +29,4 @@ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
+ obj-$(CONFIG_FPGA_SRAM) += fpga_sram.o
+ obj-y += eeprom/
+ obj-y += cb710/
++obj-y += adb4000/
+diff --git a/drivers/misc/adb4000/Kconfig b/drivers/misc/adb4000/Kconfig
+new file mode 100644
+index 0000000..945b643
+--- /dev/null
++++ b/drivers/misc/adb4000/Kconfig
+@@ -0,0 +1,86 @@
++config SPI_COMM
++ tristate
++ default n
++ help
++ Communication-layer for supervisor
++
++config SUPERVISOR
++ depends on SPI
++ select SPI_COMM
++ tristate "ADB4000 Supervisor"
++ default y
++ help
++ The supervisor expands the board by a couple of UART-lines as
++ well as some buttons and GPIOs.
++
++config SUPERVISOR_ATOI
++ bool
++ default n
++ help
++ Provide a simple str2int function
++
++config SUPERVISOR_LED
++ depends on SUPERVISOR
++ bool "Support LEDs on Supervisor"
++ default y
++ help
++ This will utilize the Supervisors LEDs as those and not as GPIO.
++
++config SUPERVISOR_IRQ
++ depends on SUPERVISOR
++ bool "Support for Interrupt driven GPIOs on Supervisor"
++ default y
++ help
++ This will make the GPIOs on the Supervisor be able to trigger
++ interrupts on the system.
++
++config SUPERVISOR_UART
++ depends on SUPERVISOR
++ bool "Make UARTs available"
++ default y
++ help
++ The Supervisor can provide a set of UART, connected to some
++ Radios or utilized for RS232/RS422/RS485
++
++config SUPERVISOR_SYSFS
++ depends on SUPERVISOR
++ bool
++ default n
++
++config SUPERVISOR_BUZZER
++ depends on SUPERVISOR
++ select SUPERVISOR_SYSFS
++ select SUPERVISOR_ATOI
++ bool "Give access to the buzzer"
++ default y
++ help
++ This will give access to the supervisor's buzzer via a sysfs-file
++
++config SUPERVISOR_ADC
++ depends on SUPERVISOR
++ select SUPERVISOR_SYSFS
++ select SUPERVISOR_ATOI
++ bool "Utilize the Analog input Streams"
++ default y
++ help
++ To use the analog inputs and switch them from 0-10V to 4-20mA and
++ vice versa, this will be needed.
++
++config SUPERVISOR_CNTIN
++ depends on SUPERVISOR
++ select SUPERVISOR_SYSFS
++ select SUPERVISOR_ATOI
++ bool "Use digital inputs as counter"
++ default y
++
++config SUPERVISOR_NOCHECK
++ depends on SUPERVISOR
++ bool "Do not test for the presence of the Supervisor"
++ default n
++
++config SUPERVISOR_BOOTLOADER
++ depends on SUPERVISOR
++ select SUPERVISOR_SYSFS
++ bool "Allow Firmwareupgrades to the Supervisor"
++ default y
++
+diff --git a/drivers/misc/adb4000/Makefile b/drivers/misc/adb4000/Makefile
+new file mode 100644
+index 0000000..7857f0a
+--- /dev/null
++++ b/drivers/misc/adb4000/Makefile
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_SPI_COMM) += spi_comm.o
++obj-$(CONFIG_SUPERVISOR)+= supervisor.o
+diff --git a/drivers/misc/adb4000/spi_comm.c b/drivers/misc/adb4000/spi_comm.c
+new file mode 100644
+index 0000000..daed9c9
+--- /dev/null
++++ b/drivers/misc/adb4000/spi_comm.c
+@@ -0,0 +1,107 @@
++#define DEBUG
++#include "spi_comm.h"
++#include <linux/crc32.h>
++
++#define CRC32_SEED 0x04C11DB7UL
++
++static int spi_comm_resend(struct spi_comm *spi) {
++ return spi_async(spi->spi, &spi->msg);
++}
++
++static int spi_comm_recv(struct spi_comm *spi, char buf[XM_SPI_BUF_SIZE]) {
++ u32 crc, crcr;
++ crc = crc32(CRC32_SEED, spi->rx+1, XM_SPI_BUF_SIZE);
++ pr_debug("Got %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
++ spi->rx[1], spi->rx[2], spi->rx[3], spi->rx[4],
++ spi->rx[5], spi->rx[6], spi->rx[7], spi->rx[8],
++ spi->rx[9], spi->rx[10], spi->rx[11], spi->rx[12]);
++ memcpy(&crcr, spi->rx + XM_SPI_BUF_SIZE+1, sizeof(crc));
++ pr_debug("CRC %08X vs %08X\n", crc, crcr);
++ if(crc == crcr) {
++ memcpy(buf, spi->rx, XM_SPI_BUF_SIZE);
++ return 1;
++ }
++ return 0;
++}
++
++static inline void spi_comm_cb(struct spi_comm *spi, char buf[XM_SPI_BUF_SIZE]) {
++ if(spi->cb == NULL) return;
++ if(spi->cb(buf, spi) >= 0) return;
++ if(spi->pckretry == 0) {
++ dev_warn(&spi->spi->dev, "Msg timed out\n");
++ return;
++ }
++ spi->pckretry--;
++ spi_comm_resend(spi);
++}
++
++static void spi_comm_complete(void *ctx) {
++ struct spi_comm *spi = ctx;
++ char buf[XM_SPI_BUF_SIZE];
++
++ if(spi->msg.status) {
++ spi->state = SPIC_ERR;
++ spi_comm_cb(spi, NULL);
++ return;
++ }
++ if(!spi_comm_recv(spi, buf)) {
++ if(spi->pckretry) {
++ spi->pckretry--;
++ spi_comm_resend(spi);
++ return;
++ }
++ spi->state = SPIC_CRCERR;
++ spi_comm_cb(spi, NULL);
++ return;
++ }
++ spi_comm_cb(spi, spi->rx + 1);
++ return;
++}
++
++int spi_comm_msg(struct spi_comm *spi, char buf[XM_SPI_BUF_SIZE]) {
++ u32 crc;
++
++ pr_debug("Msg %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
++ buf[0], buf[1], buf[2], buf[3],
++ buf[4], buf[5], buf[6], buf[7],
++ buf[8], buf[9], buf[10], buf[11]);
++ memcpy(spi->tx, buf, XM_SPI_BUF_SIZE);
++ crc = crc32(CRC32_SEED, buf, XM_SPI_BUF_SIZE);
++ pr_debug("CRC 0x%08x size %i+%i\n", crc, XM_SPI_BUF_SIZE, sizeof(crc));
++ memcpy(spi->tx + XM_SPI_BUF_SIZE, &crc, sizeof(crc));
++ spi->trans.tx_buf = spi->tx;
++ spi->trans.rx_buf = spi->rx;
++ spi->trans.len = sizeof(spi->tx);
++ spi_message_init(&spi->msg);
++ spi->msg.spi = spi->spi;
++ spi->msg.complete = spi_comm_complete;
++ spi->msg.context = spi;
++ spi->pckretry = spi->retries;
++ spi_message_add_tail(&spi->trans, &spi->msg);
++ return spi_comm_resend(spi);
++}
++
++int spi_comm_init(struct spi_comm *spic, struct spi_device *spi, int retries,
++ int busypin) {
++ spic->spi = spi;
++ spic->retries = retries;
++ spic->pckretry = retries;
++ return 0;
++}
++
++void spi_comm_destroy(struct spi_comm *spic) {
++ return;
++}
++
++int spi_comm_busy(struct spi_comm *spic) {
++ return 0;
++}
++
++EXPORT_SYMBOL(spi_comm_msg);
++EXPORT_SYMBOL(spi_comm_destroy);
++EXPORT_SYMBOL(spi_comm_init);
++EXPORT_SYMBOL(spi_comm_busy);
++
++MODULE_AUTHOR("Benjamin Tietz <benjamin.tietz@in-circuit.de>");
++MODULE_DESCRIPTION("XMEGA-SPI Communication Protocol");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/misc/adb4000/spi_comm.h b/drivers/misc/adb4000/spi_comm.h
+new file mode 100644
+index 0000000..a9e3619
+--- /dev/null
++++ b/drivers/misc/adb4000/spi_comm.h
+@@ -0,0 +1,49 @@
++#ifndef __SPI_COMM_H
++#define __SPI_COMM_H
++
++#include <linux/spi/spi.h>
++#include <linux/wait.h>
++
++#define XM_SPI_BUF_SIZE 12
++//#define XM_SPI_BUF_SIZE 28
++#define CRC32_SEED 0x04C11DB7UL
++
++struct spi_comm;
++struct spi_comm {
++ /* These fields must be initialized by the driver */
++ struct spi_device *spi;
++ int (*cb)(char buf[XM_SPI_BUF_SIZE], struct spi_comm *);
++ int retries;
++ /* This imposes the actual state of the received msg */
++ enum {
++ SPIC_OK,
++ SPIC_CRCERR,
++ SPIC_ERR,
++ } state;
++ int msg_state;
++ /* These should be ignored and handled internally */
++#ifdef CONFIG_SPI_COMM_V2
++ int busypin, busyirq, sending;
++ wait_queue_head_t busywaiter;
++#else
++ int pckretry;
++ struct spi_message msg;
++ struct spi_transfer trans;
++ char rx[XM_SPI_BUF_SIZE + 5], tx[XM_SPI_BUF_SIZE + 5];
++#endif
++};
++
++/*
++ * This intializes and set up a spi_comm struct.
++ */
++int spi_comm_init(struct spi_comm *spic, struct spi_device *spi, int retries,
++ int busypin);
++void spi_comm_destroy(struct spi_comm *spic);
++
++int spi_comm_busy(struct spi_comm *spic);
++/*
++ * This set up a new message and queues it to be send
++ */
++int spi_comm_msg(struct spi_comm *spi, char buf[XM_SPI_BUF_SIZE]);
++
++#endif
+diff --git a/drivers/misc/adb4000/supervisor.c b/drivers/misc/adb4000/supervisor.c
+new file mode 100644
+index 0000000..f5c3b2a
+--- /dev/null
++++ b/drivers/misc/adb4000/supervisor.c
+@@ -0,0 +1,1411 @@
++/*
++ * This is the kernel-driver for the ADB4000 Supervisor
++ *
++ * (C) 2010 by Benjamin Tietz <benjamin.tietz@in-circuit.de>
++ */
++
++//#define DEBUG
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/timer.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/leds.h>
++#include <linux/platform_device.h>
++#ifdef CONFIG_SUPERVISOR_IRQ
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#endif
++#ifdef CONFIG_SUPERVISOR_UART
++#include <linux/serial_core.h>
++#endif
++#ifdef CONFIG_SUPERVISOR_SYSFS
++#include <linux/hwmon-sysfs.h>
++#endif
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++#include <linux/firmware.h>
++#include <linux/crc32.h>
++#endif
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include "spi_comm.h"
++#include "supervisor.h"
++
++#define UART_NAME "ttyU"
++#define UART_MAJOR 204
++#define UART_MINOR 160
++#define UART_NR 4
++#define PORT_UARTEXTENDER 0xCBC
++#define UART_BUFSIZE 1024
++
++#define SUPERVISOR_SENDTO 20
++
++#define SUP_ADC_NUM 2
++#define SPI_VERSION_STRING "ICURTGP1.1"
++#define SPI_BL_VERSION_STRING "ICBOOTL0.1"
++
++typedef uint32_t counter_t;
++
++struct supervisor_data;
++#ifdef CONFIG_SUPERVISOR_UART
++struct uartextender_port {
++ struct uart_port uart;
++ struct supervisor_data *data;
++ int enabled:1, rx:1, tx:1;
++};
++#endif
++
++#ifdef CONFIG_SUPERVISOR_ADC
++enum supervisor_adc_type {
++ SUP_ADC_0_10_V,
++ SUP_ADC_4_20_mA,
++};
++#endif
++
++struct supervisor_data {
++ struct spi_comm spic;
++ struct gpio_chip gpioc;
++ spinlock_t lock;
++
++ /* transmission control */
++ char rx[XM_SPI_BUF_SIZE/3][3], tx[XM_SPI_BUF_SIZE/3][3];
++ wait_queue_head_t recvq;
++ int rx_valid:1, last_valid:1;
++ struct timer_list recvtimer, sendtimer;
++
++#ifdef CONFIG_SUPERVISOR_LED
++ /* LEDs */
++ struct gpio_led leds[4];
++ struct gpio_led_platform_data leds_plat;
++ struct platform_device leds_dev;
++#endif
++
++#ifdef CONFIG_SUPERVISOR_IRQ
++ /* Interrupt support */
++ int firq;
++#endif
++#if defined(CONFIG_SUPERVISOR_UART) || defined(CONFIG_SUPERVISOR_IRQ)
++ int hirq;
++#endif
++
++#ifdef CONFIG_SUPERVISOR_UART
++ struct timer_list ussendtimer;
++ struct timer_list testtimer;
++ struct uartextender_port port[UART_NR];
++ int ports_enabled;
++#endif
++#ifdef CONFIG_SUPERVISOR_BUZZER
++#endif
++#ifdef CONFIG_SUPERVISOR_ADC
++ enum supervisor_adc_type sensortype[SUP_ADC_NUM];
++#endif
++#ifndef CONFIG_SUPERVISOR_NOCHECK
++ int found:1;
++#endif
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ int bootloader:1;
++ enum {
++ BL_INIT = 0,
++ BL_WAIT_FW,
++ BL_CONTACTING,
++ BL_LOADING,
++ BL_VERIFYING,
++ BL_DONE,
++ BL_ERR,
++ } blstate;
++ wait_queue_head_t blw;
++ struct workqueue_struct *blwq;
++ struct work_struct blwork;
++ char blbuf[XM_SPI_BUF_SIZE];
++#endif
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ int cnt_valid:1, cnt_tx_sent:1;
++ char cnt_buf[sizeof(counter_t)];
++ char cnt_tx_buf[XM_SPI_BUF_SIZE];
++#endif
++};
++
++#ifdef CONFIG_SUPERVISOR_BUZZER
++static ssize_t sp_buzzer(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len);
++#endif
++#ifdef CONFIG_SUPERVISOR_ADC
++static ssize_t sen_val(struct device *dev,
++ struct device_attribute *dattr, char *buf);
++static ssize_t sen_get_type(struct device *dev,
++ struct device_attribute *dattr, char *buf);
++static ssize_t sen_set_type(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len);
++static ssize_t sen_get_cal(struct device *dev,
++ struct device_attribute *dattr, char *buf);
++static ssize_t sen_set_cal(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len);
++
++#define ADCCALVMIN (0<<8)
++#define ADCCALVMAX (1<<8)
++#define ADCCALCMIN (2<<8)
++#define ADCCALCMAX (3<<8)
++#endif
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++static ssize_t bl_start_load(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len);
++static ssize_t bl_get_state(struct device *dev,
++ struct device_attribute *dattr, char *buf);
++#endif
++#ifdef CONFIG_SUPERVISOR_CNTIN
++static ssize_t cnt_set(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len);
++static ssize_t cnt_get(struct device *dev,
++ struct device_attribute *dattr, char *buf);
++#endif
++
++
++#ifdef CONFIG_SUPERVISOR_SYSFS
++static struct sensor_device_attribute sp_sensors[] = {
++#ifdef CONFIG_SUPERVISOR_BUZZER
++ SENSOR_ATTR(buzzer, 0222, NULL, sp_buzzer, GE_BUZZER),
++#endif
++#ifdef CONFIG_SUPERVISOR_ADC
++ SENSOR_ATTR(adc0raw, 0444, sen_val, NULL, GE_ADC(0)),
++ SENSOR_ATTR(adc1raw, 0444, sen_val, NULL, GE_ADC(1)),
++ SENSOR_ATTR(adc0type, 0666, sen_get_type, sen_set_type, 0),
++ SENSOR_ATTR(adc1type, 0666, sen_get_type, sen_set_type, 1),
++ SENSOR_ATTR(adc0value, 0444, sen_val, NULL, GE_ADCCALIB(0)),
++ SENSOR_ATTR(adc1value, 0444, sen_val, NULL, GE_ADCCALIB(1)),
++ SENSOR_ATTR(adc0calibVmax, 0644,
++ sen_get_cal, sen_set_cal, ADCCALVMAX | 0),
++ SENSOR_ATTR(adc1calibVmax, 0644,
++ sen_get_cal, sen_set_cal, ADCCALVMAX | 1),
++ SENSOR_ATTR(adc0calibVmin, 0644,
++ sen_get_cal, sen_set_cal, ADCCALVMIN | 0),
++ SENSOR_ATTR(adc1calibVmin, 0644,
++ sen_get_cal, sen_set_cal, ADCCALVMIN | 1),
++ SENSOR_ATTR(adc0calibCmax, 0644,
++ sen_get_cal, sen_set_cal, ADCCALCMAX | 0),
++ SENSOR_ATTR(adc1calibCmax, 0644,
++ sen_get_cal, sen_set_cal, ADCCALCMAX | 1),
++ SENSOR_ATTR(adc0calibCmin, 0644,
++ sen_get_cal, sen_set_cal, ADCCALCMIN | 0),
++ SENSOR_ATTR(adc1calibCmin, 0644,
++ sen_get_cal, sen_set_cal, ADCCALCMIN | 1),
++#endif
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ SENSOR_ATTR(firmware, 0640, bl_get_state, bl_start_load, 0),
++#endif
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ SENSOR_ATTR(counter0, 0666, cnt_get, cnt_set, 0),
++ SENSOR_ATTR(counter1, 0666, cnt_get, cnt_set, 1),
++ SENSOR_ATTR(counter2, 0666, cnt_get, cnt_set, 2),
++ SENSOR_ATTR(counter3, 0666, cnt_get, cnt_set, 3),
++ SENSOR_ATTR(counter4, 0666, cnt_get, cnt_set, 4),
++#endif
++};
++#endif
++
++#ifdef CONFIG_SUPERVISOR_ATOI
++static int sp_atoi(const uint8_t *buf, size_t len) {
++ int value = 0;
++ int i;
++ for(i=0; i<len; i++) {
++ if(buf[i] < '0') break;
++ if(buf[i] > '9') break;
++ value = value * 10 + buf[i] - '0';
++ }
++ return value;
++}
++#endif
++
++#ifdef CONFIG_SUPERVISOR_UART
++static struct uart_driver uartextender_uart = {
++ .owner = THIS_MODULE,
++ .driver_name = "spi_uartextender",
++ .dev_name = UART_NAME,
++ .major = UART_MAJOR,
++ .minor = UART_MINOR,
++ .nr = UART_NR,
++ .cons = NULL,
++};
++
++static void uartextender_send_pck(struct supervisor_data *data,
++ uint8_t buf[XM_SPI_BUF_SIZE]) {
++ unsigned long flags;
++ spin_lock_irqsave(&data->lock, flags);
++ if(timer_pending(&data->ussendtimer)) del_timer(&data->ussendtimer);
++ if(data->ports_enabled)
++ mod_timer(&data->testtimer, jiffies + msecs_to_jiffies(100));
++ spi_comm_msg(&data->spic, buf);
++ spin_unlock_irqrestore(&data->lock, flags);
++
++}
++
++static unsigned int uartextender_tx_empty(struct uart_port *port) {
++ return TIOCSER_TEMT;
++}
++
++static void uartextender_set_mctrl(struct uart_port *port, unsigned int mctrl) {
++ return;
++}
++
++static unsigned int uartextender_get_mctrl(struct uart_port *port) {
++ return (TIOCM_CTS|TIOCM_DSR);
++}
++
++static void uartextender_start_tx(struct uart_port *uport) {
++ struct uartextender_port *port = (struct uartextender_port *) uport;
++ if(port->enabled == 0)
++ return;
++ port->tx = 1;
++}
++
++static void uartextender_stop_tx(struct uart_port *uport) {
++ struct uartextender_port *port = (struct uartextender_port *) uport;
++ if(port->enabled == 0)
++ return;
++ port->tx = 0;
++}
++
++static void uartextender_stop_rx(struct uart_port *uport) {
++ struct uartextender_port *port = (struct uartextender_port *) uport;
++ if(port->enabled == 0)
++ return;
++ port->rx = 1;
++}
++
++static int uartextender_startup(struct uart_port *uport) {
++ struct uartextender_port *port = (struct uartextender_port *) uport;
++ pr_debug("startup port %i\n", uport->line);
++ if(port->enabled) return 0;
++ port->enabled = 1;
++ port->data->ports_enabled++;
++ return 0;
++}
++
++static void uartextender_shutdown(struct uart_port *uport) {
++ struct uartextender_port *port = (struct uartextender_port *) uport;
++ pr_debug("shutdown port %i\n", uport->line);
++ if(!port->enabled) return;
++ port->enabled = 0;
++ port->data->ports_enabled--;
++}
++
++static void uartextender_flush_buffer(struct uart_port *port) {
++ return;
++}
++
++static void uartextender_set_termios(struct uart_port *port,
++ struct ktermios *termios, struct ktermios *old) {
++ struct uartextender_port *uport = (struct uartextender_port *) port;
++ uint8_t buf[XM_SPI_BUF_SIZE] = {0x80, port->line, 1, };
++ unsigned int baud;
++ baud = uart_get_baud_rate(port, termios, old, 0, 32000000UL);
++ buf[3] = baud >> 16;
++ buf[4] = baud >> 8;
++ buf[5] = baud & 0xFF;
++ switch(termios->c_cflag & CSIZE) {
++ case CS5: buf[10] = 5; break;
++ case CS6: buf[10] = 6; break;
++ case CS7: buf[10] = 7; break;
++ default: buf[10] = 8; break;
++ }
++ if(termios->c_cflag & PARENB) {
++ if(termios->c_cflag & PARODD)
++ buf[11] = 2;
++ else
++ buf[11] = 1;
++ }
++ if(termios->c_cflag & CSTOPB)
++ buf[11] |= (1<<7);
++ uartextender_send_pck(uport->data, buf);
++};
++
++static const char *uartextender_type(struct uart_port *port) {
++ if(port->type == PORT_UARTEXTENDER) return "UARTEXTENDER";
++ return NULL;
++}
++
++static void uartextender_config_port(struct uart_port *port, int flags) {
++ if(flags & UART_CONFIG_TYPE) {
++ port->type = PORT_UARTEXTENDER;
++ }
++}
++
++static int uartextender_verify_port(struct uart_port *port,
++ struct serial_struct *ser) {
++ if(port->type == PORT_UARTEXTENDER) return 0;
++ if(port->type == PORT_UNKNOWN) return 0;
++ return -EINVAL;
++}
++
++static struct uart_ops uartextender_uops = {
++ .tx_empty = uartextender_tx_empty,
++ .set_mctrl = uartextender_set_mctrl,
++ .get_mctrl = uartextender_get_mctrl,
++ .stop_tx = uartextender_stop_tx,
++ .start_tx = uartextender_start_tx,
++ .stop_rx = uartextender_stop_rx,
++ .startup = uartextender_startup,
++ .shutdown = uartextender_shutdown,
++ .flush_buffer = uartextender_flush_buffer,
++ .set_termios = uartextender_set_termios,
++ .type = uartextender_type,
++ .config_port = uartextender_config_port,
++ .verify_port = uartextender_verify_port,
++};
++
++/*********************************************************
++ * UART Stuff
++ *********************************************************/
++static int uartextender_send(struct uartextender_port *port) {
++ uint8_t buf[XM_SPI_BUF_SIZE] = {GE_USART(port->uart.line),};
++ struct circ_buf *xmit = &port->uart.state->xmit;
++ int ret = 0;
++ if(!port->enabled) return 0;
++ if(port->uart.x_char) {
++ buf[1]++;
++ buf[buf[1]+1] = port->uart.x_char;
++ port->uart.x_char = 0;
++ }
++ if(uart_tx_stopped(&port->uart)) {
++ if(buf[1])
++ uartextender_send_pck(port->data, buf);
++ return buf[1];
++ }
++ while(!uart_circ_empty(xmit) && (buf[1] < (XM_SPI_BUF_SIZE-2))) {
++ buf[1]++;
++ buf[buf[1]+1] = xmit->buf[xmit->tail];
++ xmit->tail = (xmit->tail+1)&(UART_XMIT_SIZE-1);
++ ret++;
++ }
++ if(buf[1])
++ uartextender_send_pck(port->data, buf);
++
++ if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&port->uart);
++
++ return buf[1];
++}
++
++static void ue_noptrans(unsigned long _data) {
++ struct supervisor_data *data = (void *) _data;
++ char rbuf[XM_SPI_BUF_SIZE] = {};
++ int i;
++ unsigned long flags;
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return;
++#endif
++ spin_lock_irqsave(&data->lock, flags);
++ for(i=0;i<UART_NR;i++) {
++ if(uartextender_send(&data->port[i]) != 0) break;
++ }
++ if(i==UART_NR)
++ spi_comm_msg(&data->spic, rbuf);
++ spin_unlock_irqrestore(&data->lock, flags);
++}
++
++static void ue_starttrans(unsigned long _data) {
++ struct supervisor_data *data = (void *) _data;
++ int i;
++ unsigned long flags;
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return;
++#endif
++ spin_lock_irqsave(&data->lock, flags);
++ for(i=0;i<UART_NR;i++) {
++ if(uartextender_send(&data->port[i]) != 0) break;
++ }
++ if(i==UART_NR && data->ports_enabled)
++ mod_timer(&data->testtimer, jiffies + msecs_to_jiffies(100));
++ spin_unlock_irqrestore(&data->lock, flags);
++}
++
++static struct uart_port uartextender_porttemplate = {
++ .iotype = UPIO_MEM,
++ .ops = &uartextender_uops,
++ .type = PORT_UARTEXTENDER,
++ .fifosize = 10,
++};
++
++#endif // CONFIG_SUPERVISOR_UART
++
++static void supervisor_rxinval(unsigned long _data) {
++ struct supervisor_data *data = (struct supervisor_data *) _data;
++ unsigned long flags;
++ spin_lock_irqsave(&data->lock, flags);
++ data->rx_valid = 0;
++ spin_unlock_irqrestore(&data->lock, flags);
++}
++
++static void supervisor_send(unsigned long _data) {
++ struct supervisor_data *data = (struct supervisor_data *) _data;
++ unsigned long flags;
++ pr_debug("Send Msg\n");
++ spin_lock_irqsave(&data->lock, flags);
++ if(data->tx[0][0]) {
++ data->last_valid = 1;
++ spi_comm_msg(&data->spic, (char *) data->tx);
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ } else if(data->cnt_tx_buf[0] && !data->cnt_tx_sent) {
++ data->last_valid = 1;
++ data->cnt_tx_sent = 1;
++ spi_comm_msg(&data->spic, data->cnt_tx_buf);
++#endif
++ } else {
++ data->last_valid = 0;
++ spi_comm_msg(&data->spic, (char *) data->tx);
++ }
++ memset(data->tx, 0, sizeof(data->tx));
++ spin_unlock_irqrestore(&data->lock, flags);
++}
++
++#ifdef CONFIG_SUPERVISOR_CNTIN
++
++static void supervisor_reset_send(struct supervisor_data *data,
++ char buf[XM_SPI_BUF_SIZE]) {
++ unsigned long flags;
++ spin_lock_irqsave(&data->lock, flags);
++ memcpy(data->cnt_tx_buf, buf, XM_SPI_BUF_SIZE);
++ data->cnt_tx_sent = 0;
++ if(!timer_pending(&data->sendtimer)) {
++ data->sendtimer.expires =
++ jiffies + msecs_to_jiffies(SUPERVISOR_SENDTO);
++ add_timer(&data->sendtimer);
++ }
++ spin_unlock_irqrestore(&data->lock, flags);
++}
++static void supervisor_cntreg_set(struct supervisor_data *data, int counter,
++ uint32_t value) {
++ char buf[XM_SPI_BUF_SIZE] = { GE_CNTER_SET, counter,
++ //value >> 24, value >> 16, value >> 8, value >> 0,
++ value >> 0, value >> 8, value >> 16, value >> 24,
++ };
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return;
++#endif
++ supervisor_reset_send(data, buf);
++}
++
++static counter_t supervisor_cntreg_get(struct supervisor_data *data, int num) {
++ unsigned long flags;
++ char buf[XM_SPI_BUF_SIZE] = { GE_CNTER_GET, num, };
++ counter_t ret;
++ int i;
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return 0;
++#endif
++ pr_debug("Recv Counter\n");
++ data->cnt_valid = 0;
++ do {
++ supervisor_reset_send(data, buf);
++ wait_event_interruptible_timeout(data->recvq, data->cnt_valid,
++ msecs_to_jiffies(10));
++ if(data->cnt_valid) {
++ spin_lock_irqsave(&data->lock, flags);
++ ret = 0;
++ for(i=sizeof(ret);i>0;i--) {
++ ret = ret<<8;
++ ret += data->cnt_buf[i-1];
++ }
++ spin_unlock_irqrestore(&data->lock, flags);
++ return ret;
++ }
++ } while(1);
++}
++
++static ssize_t cnt_set(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ int value = sp_atoi(buf, len);
++ if((buf[0] == 'r') || (buf[0] == 'R'))
++ value = 0xFFFFFFFFUL;
++ supervisor_cntreg_set(data, attr->index, value);
++ return len;
++}
++
++static ssize_t cnt_get(struct device *dev,
++ struct device_attribute *dattr, char *buf) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ return sprintf(buf, "%li\n",
++ (long) supervisor_cntreg_get(data, attr->index));
++}
++#endif
++/*********************************************************
++ * Register handling
++ *********************************************************/
++static void supervisor_setreg_mask(struct supervisor_data *data, int reg,
++ int port, int mask) {
++ int i;
++ unsigned long flags;
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return;
++#endif
++ spin_lock_irqsave(&data->lock, flags);
++ for(i=0; i<ARRAY_SIZE(data->tx); i++) {
++ if((data->tx[i][0] == reg) && (data->tx[i][1] == port)) {
++ data->tx[i][2] |= mask;
++ spin_unlock_irqrestore(&data->lock, flags);
++ return;
++ }
++ if(data->tx[i][0] != 0) continue;
++ data->tx[i][0] = reg;
++ data->tx[i][1] = port;
++ data->tx[i][2] = mask;
++ if(!timer_pending(&data->sendtimer)) {
++ data->sendtimer.expires =
++ jiffies + msecs_to_jiffies(SUPERVISOR_SENDTO);
++ add_timer(&data->sendtimer);
++ }
++ spin_unlock_irqrestore(&data->lock, flags);
++ return;
++ }
++ // Queue is full, schedule transfer and open next.
++ del_timer(&data->sendtimer);
++ spin_unlock_irqrestore(&data->lock, flags);
++ supervisor_send((unsigned long) data);
++ data->tx[0][0] = reg;
++ data->tx[0][1] = port;
++ data->tx[0][2] = mask;
++ for(i=1;i<ARRAY_SIZE(data->tx); i++) {
++ data->tx[i][0] = 0;
++ data->tx[i][1] = 0;
++ data->tx[i][2] = 0;
++ }
++ data->sendtimer.expires = jiffies + msecs_to_jiffies(SUPERVISOR_SENDTO);
++ add_timer(&data->sendtimer);
++}
++
++static void supervisor_setreg(struct supervisor_data *data, int reg, int pin) {
++ supervisor_setreg_mask(data, reg, pin>>3, 1<<(pin &0x07));
++}
++
++static int supervisor_getreg_raw(struct supervisor_data *data, int reg,
++ int port, int testport) {
++ int i, ignore = 0;
++ unsigned long flags;
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) return 0;
++#endif
++ do {
++ spin_lock_irqsave(&data->lock, flags);
++ for(i=0;i<ARRAY_SIZE(data->rx);i++) {
++ if(!data->rx_valid) break;
++ if(data->rx[i][0] == 0) break;
++ if(data->rx[i][0] != reg) continue;
++ if(testport && (data->rx[i][1] != port)) continue;
++ spin_unlock_irqrestore(&data->lock, flags);
++ return (data->rx[i][1]<<8)|data->rx[i][2];
++ }
++ // No actual data got
++ if(!ignore) {
++ supervisor_setreg_mask(data, reg, port, 0);
++ del_timer(&data->recvtimer);
++ }
++ ignore = !ignore;
++ data->rx_valid = 0;
++ spin_unlock_irqrestore(&data->lock, flags);
++ wait_event_interruptible(data->recvq, data->rx_valid);
++ } while(1);
++}
++
++static int supervisor_getreg_mask(struct supervisor_data *data, int reg,
++ int port, int mask) {
++ return supervisor_getreg_raw(data, reg, port, 1) & mask;
++}
++
++static int supervisor_getreg(struct supervisor_data *data, int reg, int pin) {
++ return supervisor_getreg_mask(data, reg, pin>>3, 1<<(pin&0x07))?1:0;
++}
++
++/*********************************************************
++ * GPIO handling
++ *********************************************************/
++
++static int supervisor_dirin(struct gpio_chip *gpio, unsigned int offset) {
++ struct supervisor_data *data =
++ container_of(gpio, struct supervisor_data, gpioc);
++ int ret = 0;
++ if(offset < 8) {
++ supervisor_setreg(data, GE_IER, offset);
++ } else if(offset < 24) {
++ ret = -EACCES;
++ }
++ return ret;
++}
++
++static int supervisor_dirout(struct gpio_chip *gpio, unsigned int offset,
++ int value) {
++ struct supervisor_data *data =
++ container_of(gpio, struct supervisor_data, gpioc);
++ int ret = 0;
++ int reg = value?GE_OER:GE_ODR;
++ if(offset < 8) {
++ supervisor_setreg(data, GE_IDR, offset);
++ }
++ if(offset >= 24) {
++ ret = -EACCES;
++ } else if (ret == 0) {
++ supervisor_setreg(data, reg, offset);
++ }
++ return ret;
++}
++
++static int supervisor_get(struct gpio_chip *gpio, unsigned int offset) {
++ struct supervisor_data *data =
++ container_of(gpio, struct supervisor_data, gpioc);
++ int ret = 0;
++ ret = supervisor_getreg(data, GE_PPR, offset)?1:0;
++ return ret;
++}
++
++static void supervisor_set(struct gpio_chip *gpio, unsigned int offset, int value) {
++ struct supervisor_data *data =
++ container_of(gpio, struct supervisor_data, gpioc);
++ int reg = value?GE_OER:GE_ODR;
++
++ supervisor_setreg(data, reg, offset);
++}
++
++#ifdef CONFIG_SUPERVISOR_IRQ
++static int supervisor_to_irq(struct gpio_chip *gpio, unsigned offset) {
++ struct supervisor_data *data =
++ container_of(gpio, struct supervisor_data, gpioc);
++ pr_debug("gpio %i to irq %i\n", offset, data->firq+offset);
++ if(offset < 16) {
++ return data->firq + offset;
++ }
++ return -1;
++}
++#else
++#define supervisor_to_irq NULL
++#endif
++
++static struct gpio_chip supervisor_gpio = {
++ .owner = THIS_MODULE,
++ .direction_input = supervisor_dirin,
++ .direction_output = supervisor_dirout,
++ .get = supervisor_get,
++ .set = supervisor_set,
++ .to_irq = supervisor_to_irq,
++ .base = -1,
++ .ngpio = 16,
++ .can_sleep = 1,
++ .label = "supervisor0",
++};
++
++#ifdef CONFIG_SUPERVISOR_IRQ
++/*********************************************************
++ * IRQ Stuff
++ *********************************************************/
++
++static void supervisor_irq_mask(unsigned irq) {
++ struct supervisor_data *data = get_irq_chip_data(irq);
++
++ supervisor_setreg(data, GE_IDR, irq - data->firq);
++}
++
++static void supervisor_irq_unmask(unsigned irq) {
++ struct supervisor_data *data = get_irq_chip_data(irq);
++
++ supervisor_setreg(data, GE_IER, irq - data->firq);
++}
++
++static int supervisor_irq_type(unsigned irq, unsigned type) {
++ if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE)
++ return -EINVAL;
++ return 0;
++}
++
++static struct irq_chip supervisor_irq = {
++ .name = "supervisor",
++ .mask = supervisor_irq_mask,
++ .unmask = supervisor_irq_unmask,
++ .set_type = supervisor_irq_type,
++};
++
++#endif
++
++#if defined(CONFIG_SUPERVISOR_UART) || defined(CONFIG_SUPERVISOR_IRQ)
++
++static irqreturn_t supervisor_irqh(int irq, void *_data) {
++ struct supervisor_data *data = _data;
++#ifdef CONFIG_SUPERVISOR_UART
++ unsigned long flags;
++#endif
++
++#ifdef CONFIG_SUPERVISOR_IRQ
++ supervisor_setreg(data, GE_ISR, 0);
++ supervisor_setreg(data, GE_ISR, 8);
++#endif
++#ifdef CONFIG_SUPERVISOR_UART
++ spin_lock_irqsave(&data->lock, flags);
++ if(timer_pending(&data->ussendtimer))
++ mod_timer(&data->ussendtimer, jiffies + msecs_to_jiffies(1));
++ spin_unlock_irqrestore(&data->lock, flags);
++#endif
++
++ return IRQ_HANDLED;
++}
++
++#endif
++
++/*********************************************************
++ * Buzzer
++ *********************************************************/
++#ifdef CONFIG_SUPERVISOR_BUZZER
++static ssize_t sp_buzzer(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ int value = sp_atoi(buf, len);
++ supervisor_setreg_mask(data, attr->index, value >> 8, value & 0xFFU);
++ return len;
++}
++#endif
++
++/*********************************************************
++ * A/D Converter
++ *********************************************************/
++#ifdef CONFIG_SUPERVISOR_ADC
++static ssize_t sen_val(struct device *dev,
++ struct device_attribute *dattr, char *buf) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ return sprintf(buf, "%i\n",
++ supervisor_getreg_raw(data, attr->index, 0, 0));
++}
++
++static ssize_t sen_get_type(struct device *dev,
++ struct device_attribute *dattr, char *buf) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ return sprintf(buf, "%s\n",
++ (data->sensortype[attr->index] == SUP_ADC_0_10_V)?
++ "[voltage] current":"voltage [current]");
++}
++
++#define _cal2num(attr) ((attr) & 0xFFU)
++static uint8_t _get_cal_byte(int attr) {
++ switch(attr & 0xFF00U) {
++ case ADCCALVMIN: return GE_ADCSET_V|GE_ADCSET_CALMIN;
++ case ADCCALVMAX: return GE_ADCSET_V|GE_ADCSET_CALMAX;
++ case ADCCALCMIN: return GE_ADCSET_I|GE_ADCSET_CALMIN;
++ case ADCCALCMAX: return GE_ADCSET_I|GE_ADCSET_CALMAX;
++ }
++ return 0;
++}
++
++static ssize_t sen_set_type(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ int value = ((buf[0]|(1<<5)) == 'v')?GE_ADCSET_V:GE_ADCSET_I;
++
++ data->sensortype[attr->index] = value?SUP_ADC_4_20_mA:SUP_ADC_0_10_V;
++ supervisor_setreg_mask(data, GE_ADCSET, _cal2num(attr->index), value);
++ return len;
++}
++
++static ssize_t sen_get_cal(struct device *dev,
++ struct device_attribute *dattr, char *buf) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++
++ // invalidate cache, as the result may come from another sensor
++ data->rx_valid=0;
++
++ supervisor_setreg_mask(data, GE_ADCSET, _cal2num(attr->index),
++ _get_cal_byte(attr->index));
++ return sprintf(buf, "%i\n", supervisor_getreg_raw(data,
++ GE_ADCGCAL(_cal2num(attr->index)), 0, 0));
++}
++
++static ssize_t sen_set_cal(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(dattr);
++ int value = sp_atoi(buf, len);
++
++ supervisor_setreg_mask(data, GE_ADCSET, _cal2num(attr->index),
++ _get_cal_byte(attr->index));
++ supervisor_setreg_mask(data, GE_ADCSCAL(_cal2num(attr->index)),
++ value >> 8, value & 0xFFU);
++ return len;
++}
++
++#endif
++
++/*********************************************************
++ * Protocol Stuff
++ *********************************************************/
++#ifndef CONFIG_SUPERVISOR_NOCHECK
++static int supervisor_init_cb(char buf[XM_SPI_BUF_SIZE], struct spi_comm *spi) {
++ struct supervisor_data *data =
++ container_of(spi, struct supervisor_data, spic);
++ if(buf == NULL) {
++ dev_info(&spi->spi->dev, "got init-pck NULL spic:%i, spi:%i\n",
++ spi->state, spi->msg_state);
++ if(spi->state == SPIC_CRCERR) return -1;
++ return 0;
++ }
++ dev_info(&spi->spi->dev, "got init-pck '%x%s'\n", buf[0], buf +1);
++ data->found = (strncmp(buf+1, SPI_VERSION_STRING,
++ strlen(SPI_VERSION_STRING)) == 0);
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if((!data->found) && strncmp(buf + 1, SPI_BL_VERSION_STRING,
++ strlen(SPI_BL_VERSION_STRING)) == 0) {
++ dev_warn(&spi->spi->dev,
++ "Supervisor is in Bootloadermode during init!\n"
++ "Supply a new firmware first!");
++ data->found = 1;
++ data->bootloader = 1;
++ }
++#endif
++ wake_up(&data->recvq);
++ return 0;
++}
++#endif
++
++static int supervisor_cb(char buf[XM_SPI_BUF_SIZE], struct spi_comm *spi) {
++ struct supervisor_data *data =
++ container_of(spi, struct supervisor_data, spic);
++ int i, valid;
++ unsigned long flags, expires;
++#ifdef CONFIG_SUPERVISOR_IRQ
++ int pin, offset;
++#endif
++#ifdef CONFIG_SUPERVISOR_UART
++ struct uart_port *port;
++#endif
++
++ if(buf == NULL) {
++ if(spi->state == SPIC_CRCERR) return -1; // resend last pck
++ return 0;
++ }
++ pr_debug("valid data received\n");
++ spin_lock_irqsave(&data->lock, flags);
++#ifdef CONFIG_SUPERVISOR_UART
++ if((GE_BUSART(buf[0]) >= 0) && (GE_BUSART(buf[0]) < UART_NR) &&
++ (data->port[GE_BUSART(buf[0])].enabled)) {
++ port = &data->port[GE_BUSART(buf[0])].uart;
++ pr_debug("p%02x %p (%ib): ", buf[0], port, buf[1]);
++ for(i=0; i<buf[1]; i++) {
++#ifdef DEBUG
++ printk("%02x ", buf[i+2]);
++#endif
++ if(uart_handle_sysrq_char(port, buf[i+2])) continue;
++ uart_insert_char(port, 0, 0, buf[i+2], 0);
++ }
++#ifdef DEBUG
++ printk("\n");
++#endif
++ tty_flip_buffer_push(port->state->port.tty);
++ }
++#endif
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ if(buf[0] == GE_CNTER_GET) {
++ memcpy(data->cnt_buf, buf + 2, sizeof(counter_t));
++ data->cnt_valid = 1;
++ } else if(buf[0] != GE_CNTER_SET) {
++#endif
++ expires = jiffies + msecs_to_jiffies(100);
++ mod_timer(&data->recvtimer, expires);
++ memcpy(data->rx, buf, XM_SPI_BUF_SIZE);
++ data->rx_valid = 1;
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ }
++#endif
++ wake_up(&data->recvq);
++ /* If the device send valid data, it is possible, that it has more
++ * data left. So schedule a new transmission then */
++ valid = 0;
++ for(i=0; i<ARRAY_SIZE(data->rx); i++) {
++ if(data->rx[i][0] == 0x00) continue; // No data
++ valid = 1;
++#ifdef CONFIG_SUPERVISOR_IRQ
++ if(data->rx[i][0] != GE_ISR) continue;
++ offset = 8 * data->rx[i][1] + data->firq;
++ for(pin=0;pin<8;pin++) {
++ if(!(data->rx[i][2] & (1<<pin)))
++ continue;
++ pr_debug("handle IRQ %i\n", offset + pin);
++ generic_handle_irq(offset + pin);
++ }
++#else
++ break;
++#endif
++ }
++#ifdef CONFIG_SUPERVISOR_UART
++ for(i=0; i<UART_NR; i++) {
++ if(uartextender_send(&data->port[i]) != 0) break;
++ }
++ if(i==UART_NR && ((buf[0] & 0x90) == 0x90)) // There might be more data
++ mod_timer(&data->ussendtimer, jiffies + msecs_to_jiffies(10));
++ if(data->ports_enabled)
++ mod_timer(&data->testtimer, jiffies + msecs_to_jiffies(100));
++#endif
++ if(valid || data->last_valid) {
++ mod_timer(&data->sendtimer,
++ jiffies + msecs_to_jiffies(SUPERVISOR_SENDTO));
++ }
++ spin_unlock_irqrestore(&data->lock, flags);
++ return 0;
++}
++
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++/*********************************************************
++ * Bootloader logic
++ *********************************************************/
++static int supervisor_bootloader_cb(char buf[XM_SPI_BUF_SIZE],
++ struct spi_comm *spi) {
++ unsigned long flags;
++ struct supervisor_data *data =
++ container_of(spi, struct supervisor_data, spic);
++
++ if(buf == NULL) {
++ if(spi->state == SPIC_CRCERR) return -1; // resend last pck
++ return 0;
++ }
++ pr_debug("valid data received\n");
++ spin_lock_irqsave(&data->lock, flags);
++ memcpy(data->blbuf, buf, XM_SPI_BUF_SIZE);
++ wake_up(&data->blw);
++ spin_unlock_irqrestore(&data->lock, flags);
++ return 0;
++}
++
++#define bl_mk_cmd(buf, cmd, size) _bl_mk_cmd(buf, GE_BL_CMD_ ## cmd, size)
++static void _bl_mk_cmd(char buf[XM_SPI_BUF_SIZE], char cmd, int size) {
++ buf[0] = GE_BL_CMD;
++ buf[1] = cmd;
++ buf[2] = size >> 8;
++ buf[3] = size & 0xFFU;
++}
++
++static void bl_mk_data(char buf[XM_SPI_BUF_SIZE], int addr, const char *data,
++ int size) {
++ int i;
++ buf[0] = GE_BL_DATA;
++ buf[1] = addr >> 8;
++ buf[2] = addr & 0xFFU;
++ //buf[3] = (1<<size)-1;
++ for(i=0; i<size; i++) buf[i+4] = data[i];
++}
++
++static void bl_mk_chk(char buf[XM_SPI_BUF_SIZE], int start, int end, long seed)
++{
++ buf[0] = GE_BL_CHKSUM;
++ buf[1] = start >> 16;
++ buf[2] = start >> 8;
++ buf[3] = start;
++ buf[4] = 0;
++ buf[5] = end >> 16;
++ buf[6] = end >> 8;
++ buf[7] = end;
++ buf[8] = seed >> 24;
++ buf[9] = seed >> 16;
++ buf[10] = seed >> 8;
++ buf[11] = seed;
++}
++
++static void update_thread(struct work_struct *work) {
++ struct supervisor_data *data =
++ container_of(work, struct supervisor_data, blwork);
++ const struct firmware *fw;
++ int addr, i, counter;
++ int blpagecount, blpagesize;
++ int status, size, chsize;
++ unsigned long flags;
++ char buf[XM_SPI_BUF_SIZE] = {};
++ char *_dbuf;
++#define dbuf(i) (&_dbuf[(i) * XM_SPI_BUF_SIZE])
++
++ init_waitqueue_head(&data->blw);
++ data->blstate = BL_WAIT_FW;
++ status = request_firmware(&fw, "adb4000.bin", &data->spic.spi->dev);
++ if(status != 0) {
++ dev_warn(&data->spic.spi->dev, "Firmware not found");
++ data->blstate = BL_ERR;
++ goto bl_up_fwnotfound;
++ }
++
++ dev_info(&data->spic.spi->dev, "Contacting Bootloader...");
++ data->blstate = BL_CONTACTING;
++ data->bootloader = 1;
++ data->spic.cb = supervisor_bootloader_cb;
++ do {
++ spin_lock_irqsave(&data->lock, flags);
++ buf[0] = GE_BL_INFO;
++ msleep(40);
++ spi_comm_msg(&data->spic, buf);
++ wait_event_interruptible(data->blw, 1);
++ spin_unlock_irqrestore(&data->lock, flags);
++ blpagesize = data->blbuf[2]<<8|data->blbuf[3];
++ blpagecount = data->blbuf[4]<<8|data->blbuf[5];
++ } while((data->blbuf[0] != GE_BL_INFO) || (blpagesize == 0) || (blpagecount == 0) );
++ dev_info(&data->spic.spi->dev,
++ "Bootloader has %iB per %i pages. Size is %iB",
++ blpagesize, blpagecount, blpagesize * blpagecount);
++ if(fw->size > (blpagesize * blpagecount)) {
++ dev_warn(&data->spic.spi->dev, "Firmware too large");
++ data->blstate = BL_ERR;
++ goto bl_up_tolarge;
++ }
++
++ dev_info(&data->spic.spi->dev, "Loading Firmware...");
++ data->blstate = BL_LOADING;
++ _dbuf = kzalloc(((blpagesize / 8) + 4) * XM_SPI_BUF_SIZE, GFP_KERNEL);
++ for(addr = 0; addr < fw->size; addr += blpagesize) {
++ //spin_lock_irqsave(&data->lock, flags);
++ bl_mk_cmd(dbuf(0), LOAD, addr / blpagesize);
++ spi_comm_msg(&data->spic, dbuf(0));
++ size = blpagesize;
++ if((fw->size - addr) < size) size = fw->size - addr;
++ for(i = addr % blpagesize; i < size; i+=chsize) {
++ chsize = fw->size - addr -i;
++ if(chsize > size - i) chsize = size - i;
++ if(chsize > 8) chsize = 8;
++ //if(i%0x80 == 0) msleep(100);
++ bl_mk_data(dbuf(i/8+3), i, fw->data + addr + i, chsize);
++ spi_comm_msg(&data->spic, dbuf(i/8+1));
++ }
++ //spi_comm_msg(&data->spic, dbuf(1));
++ bl_mk_cmd(dbuf(2), WRITE, addr/blpagesize);
++ //spi_comm_msg(&data->spic, dbuf(2));
++ //spin_unlock_irqrestore(&data->lock, flags);
++ // Wait for write done
++ counter = 0;
++ while((data->blbuf[0] != GE_BL_CMD) ||
++ (data->blbuf[1] != GE_BL_CMD_WRITE)) {
++ wait_event_interruptible_timeout(data->blw, 1,
++ msecs_to_jiffies(100));
++ if(counter == 0) {
++ spi_comm_msg(&data->spic, dbuf(2));
++ counter = 10;
++ } else {
++ spi_comm_msg(&data->spic, dbuf(1));
++ counter --;
++ }
++ msleep(40);
++ }
++ }
++
++ dev_info(&data->spic.spi->dev, "Verifying Firmware...");
++ data->blstate = BL_VERIFYING;
++ spi_comm_msg(&data->spic, dbuf(1));
++ bl_mk_chk(buf, 0, fw->size, CRC32_SEED);
++ counter = 0;
++ do {
++ wait_event_interruptible_timeout(data->blw, 1,
++ msecs_to_jiffies(100));
++ if(counter == 0) {
++ spi_comm_msg(&data->spic, buf);
++ counter = 10;
++ } else {
++ spi_comm_msg(&data->spic, dbuf(1));
++ counter --;
++ }
++ msleep(40);
++ } while(data->blbuf[0] != GE_BL_CHKSUM);
++
++ i = data->blbuf[8]<<24;
++ i |= data->blbuf[9]<<16;
++ i |= data->blbuf[10]<<8;
++ i |= data->blbuf[11];
++ if(i != crc32(CRC32_SEED, fw->data, fw->size)) {
++ data->blstate = BL_ERR;
++ dev_warn(&data->spic.spi->dev, "Checksum doesn't match");
++ goto bl_up_chkerr;
++ }
++
++ dev_info(&data->spic.spi->dev, "Uploading Firmware done");
++ data->blstate = BL_DONE;
++ bl_mk_cmd(buf, RESET, 0);
++ spi_comm_msg(&data->spic, buf);
++
++bl_up_chkerr:
++ kfree(_dbuf);
++bl_up_tolarge:
++ data->spic.cb = supervisor_cb;
++ data->bootloader = 0;
++ release_firmware(fw);
++bl_up_fwnotfound:
++// destroy_workqueue(data->blwq);
++ return;
++}
++
++
++static void bl_init(struct supervisor_data *data) {
++ data->blwq = create_singlethread_workqueue("Supervisor_update");
++ INIT_WORK(&data->blwork, update_thread);
++ queue_work(data->blwq, &data->blwork);
++}
++
++static ssize_t bl_start_load(struct device *dev,
++ struct device_attribute *dattr, const char *buf, size_t len) {
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ bl_init(data);
++ return len;
++}
++
++static ssize_t bl_get_state(struct device *dev,
++ struct device_attribute *dattr, char *buf) {
++ const char *msg = NULL;
++ struct supervisor_data *data = dev_get_drvdata(dev);
++ switch(data->blstate) {
++ case BL_INIT: msg = "not used"; break;
++ case BL_WAIT_FW: msg = "waiting for firmware"; break;
++ case BL_CONTACTING: msg = "contacting"; break;
++ case BL_LOADING: msg = "uploading"; break;
++ case BL_VERIFYING: msg = "verifying"; break;
++ case BL_DONE: msg = "OK"; break;
++ case BL_ERR: msg = "Error"; break;
++ }
++ return sprintf(buf, "%s\n", msg);
++}
++#endif
++
++
++static int __devinit supervisor_probe(struct spi_device *spi) {
++ struct supervisor_data *data;
++ int status = 0;
++ int i;
++
++ i = 0;
++
++ data = kzalloc(sizeof(*data), GFP_KERNEL);
++ if(!data)
++ return -ENOMEM;
++ status = spi_comm_init(&data->spic, spi, 10, (3*32+9));
++ if(status < 0) goto spi_comm_err;
++
++ data->rx_valid = 0;
++ init_waitqueue_head(&data->recvq);
++ spin_lock_init(&data->lock);
++
++ // Timer
++ setup_timer(&data->recvtimer, supervisor_rxinval, (unsigned long) data);
++ setup_timer(&data->sendtimer, supervisor_send, (unsigned long) data);
++
++ // SPI
++ spi_set_drvdata(spi, data);
++#ifndef CONFIG_SUPERVISOR_NOCHECK
++ data->spic.cb = supervisor_init_cb;
++ for(i=3;i>0;i--) {
++ unsigned long flags;
++ char buf[XM_SPI_BUF_SIZE] = { GE_VERSION, };
++ spin_lock_irqsave(&data->lock, flags);
++ if(spi_comm_busy(&data->spic)) {
++ msleep(100);
++ continue;
++ }
++ spi_comm_msg(&data->spic, buf);
++ spin_unlock_irqrestore(&data->lock, flags);
++ wait_event_interruptible_timeout(data->recvq, data->found,
++ msecs_to_jiffies(20));
++ if(data->found) break;
++ }
++ if(!data->found) {
++ dev_warn(&spi->dev, "No Supervisor-Chip found!\n");
++ status = -ENODEV;
++ goto notfound;
++ }
++#endif
++ data->spic.cb = supervisor_cb;
++#ifdef CONFIG_SUPERVISOR_BOOTLOADER
++ if(data->bootloader) bl_init(data);
++#endif
++
++ // GPIO
++ memcpy(&data->gpioc, &supervisor_gpio, sizeof(supervisor_gpio));
++ data->gpioc.dev = &spi->dev;
++ status = gpiochip_add(&data->gpioc);
++ if(status < 0)
++ goto gpioerr;
++
++#ifdef CONFIG_SUPERVISOR_LED
++ // LEDs
++ for(i=0;i<ARRAY_SIZE(data->leds);i++) {
++ data->leds[i].name = kasprintf(GFP_KERNEL, "%s:led%i",
++ dev_name(&spi->dev), i);
++ if(data->leds[i].name == NULL) {
++ status = -ENOMEM;
++ goto ledmemerr;
++ }
++ data->leds[i].gpio = data->gpioc.base + i + 3;
++ data->leds[i].active_low = 1;
++ }
++ data->leds[0].default_trigger = "heartbeat";
++ data->leds[1].default_trigger = "nand-disk";
++ data->leds[2].default_trigger = "mmc0";
++ data->leds[3].default_trigger = "mmc1";
++ data->leds_plat.num_leds = i;
++ data->leds_plat.leds = data->leds;
++ data->leds_dev.name = "leds-gpio";
++ data->leds_dev.dev.platform_data = &data->leds_plat;
++ status = platform_device_register(&data->leds_dev);
++ if(status < 0)
++ goto lederr;
++#endif
++
++#ifdef CONFIG_SUPERVISOR_IRQ
++ data->firq = data->gpioc.base;
++ for(i=data->firq;i<(data->firq + 16);i++) {
++ set_irq_chip(i, &supervisor_irq);
++ set_irq_handler(i, handle_simple_irq);
++ set_irq_flags(i, IRQF_VALID);
++ set_irq_chip_data(i, data);
++ }
++#endif
++
++#ifdef CONFIG_SUPERVISOR_UART
++ setup_timer(&data->ussendtimer, ue_noptrans, (unsigned long) data);
++ setup_timer(&data->testtimer, ue_starttrans, (unsigned long) data);
++
++ for(i=0; i < UART_NR; i++) {
++ memcpy(&data->port[i].uart, &uartextender_porttemplate,
++ sizeof(uartextender_porttemplate));
++ pr_debug("set up uart %i (%p)\n", i, &data->port[i].uart);
++ data->port[i].uart.line = i;
++ data->port[i].uart.dev = &spi->dev;
++ data->port[i].data = data;
++ status = uart_add_one_port(&uartextender_uart,
++ &data->port[i].uart);
++ if(status)
++ pr_warning("Can't add port%i (%i)\n", i, status);
++ }
++#endif
++
++#if defined(CONFIG_SUPERVISOR_IRQ) || defined(CONFIG_SUPERVISOR_UART)
++// data->hirq = (int) spi_get_drvdata(spi);
++ data->hirq = gpio_to_irq(4*32+18);
++ if(data->hirq <= 0) {
++ dev_warn(&spi->dev, "No interrupt!\n");
++ goto irqerr;
++ }
++ status = request_irq(data->hirq, supervisor_irqh, IRQ_TYPE_EDGE_BOTH,
++ "supervisor", data);
++ if(status < 0)
++ goto irqerr;
++#endif
++#ifdef CONFIG_SUPERVISOR_SYSFS
++ for(i=0; i< ARRAY_SIZE(sp_sensors); i++) {
++ if((status = device_create_file(&spi->dev,
++ &sp_sensors[i].dev_attr))<0)
++ goto sysfserr;
++ }
++#endif
++#ifdef CONFIG_SUPERVISOR_CNTIN
++ data->cnt_valid = 0;
++#endif
++
++ return 0;
++
++#ifdef CONFIG_SUPERVISOR_SYSFS
++ i = ARRAY_SIZE(sp_sensors);
++sysfserr:
++ for(;i>0;i--)
++ device_remove_file(&spi->dev, &sp_sensors[i-1].dev_attr);
++#endif
++#if defined(CONFIG_SUPERVISOR_IRQ) || defined(CONFIG_SUPERVISOR_UART)
++ free_irq(data->hirq, data);
++irqerr:
++#endif
++#ifdef CONFIG_SUPERVISOR_LED
++ platform_device_unregister(&data->leds_dev);
++ i = ARRAY_SIZE(data->leds);
++ledmemerr:
++ for(;i>0;i--)
++ kfree(data->leds[i].name);
++lederr:
++#endif
++ if(gpiochip_remove(&data->gpioc) < 0)
++ dev_warn(&spi->dev, "Can't remove GPIO-CHIP!");
++gpioerr:
++notfound:
++ spi_comm_destroy(&data->spic);
++spi_comm_err:
++ kfree(data);
++ return status;
++}
++
++static int __devexit supervisor_remove(struct spi_device *spi) {
++ struct supervisor_data *data = spi_get_drvdata(spi);
++ int i;
++
++#ifdef CONFIG_SUPERVISOR_SYSFS
++ for(i=0; i<ARRAY_SIZE(sp_sensors); i++)
++ device_remove_file(&spi->dev, &sp_sensors[i].dev_attr);
++#endif
++#if defined(CONFIG_SUPERVISOR_IRQ) || defined(CONFIG_SUPERVISOR_UART)
++ free_irq(data->hirq, data);
++#endif
++#ifdef CONFIG_SUPERVISOR_LED
++ platform_device_unregister(&data->leds_dev);
++ for(i=0;i<ARRAY_SIZE(data->leds);i++)
++ kfree(data->leds[i].name);
++#else
++ i = 0;
++#endif
++ if(gpiochip_remove(&data->gpioc) < 0)
++ dev_warn(&spi->dev, "Can't remove GPIO-CHIP!");
++ spi_comm_destroy(&data->spic);
++ kfree(data);
++ return 0;
++}
++
++static struct spi_driver supervisor_driver = {
++ .driver = {
++ .name = "supervisor",
++ .owner = THIS_MODULE,
++ },
++ .probe = supervisor_probe,
++ .remove = __devexit_p(supervisor_remove),
++};
++
++/*********************************************************
++ * Module Stuff
++ *********************************************************/
++static int __init supervisor_init(void) {
++ int status;
++#ifdef CONFIG_SUPERVISOR_UART
++ status = uart_register_driver(&uartextender_uart);
++ if(status < 0)
++ goto uart_err;
++#endif
++ status = spi_register_driver(&supervisor_driver);
++ if(status < 0)
++ goto spi_err;
++
++ return 0;
++
++ spi_unregister_driver(&supervisor_driver);
++spi_err:
++#ifdef CONFIG_SUPERVISOR_UART
++ uart_unregister_driver(&uartextender_uart);
++uart_err:
++#endif
++ return status;
++}
++module_init(supervisor_init);
++
++static void __exit supervisor_exit(void) {
++ spi_unregister_driver(&supervisor_driver);
++#ifdef CONFIG_SUPERVISOR_UART
++ uart_unregister_driver(&uartextender_uart);
++#endif
++}
++module_exit(supervisor_exit);
++
++MODULE_AUTHOR("Benjamin Tietz <benjamin.tietz@in-circuit.de>");
++MODULE_DESCRIPTION("ADB4000 Supervisor");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/misc/adb4000/supervisor.h b/drivers/misc/adb4000/supervisor.h
+new file mode 100644
+index 0000000..6fdff83
+--- /dev/null
++++ b/drivers/misc/adb4000/supervisor.h
+@@ -0,0 +1,46 @@
++#ifndef __GPIOEXT_H
++#define __GPIOEXT_H
++
++#define GE_SOR 0x12
++#define GE_SIR 0x11
++#define GE_IOSR 0x10
++#define GE_PPR 0x20
++#define GE_ISR 0x33
++#define GE_IER 0x32
++#define GE_IDR 0x31
++#define GE_IMR 0x30
++#define GE_PER 0x42
++#define GE_PDR 0x41
++#define GE_PSR 0x40
++#define GE_OER 0x52
++#define GE_ODR 0x51
++#define GE_OSR 0x50
++#define GE_BUZZER 0x60
++#define GE_ADCSET 0x6F
++#define GE_ADCSET_V (0<<0)
++#define GE_ADCSET_I (1<<0)
++#define GE_ADCSET_NOCAL (0<<1)
++#define GE_ADCSET_CALMIN (1<<1)
++#define GE_ADCSET_CALMAX (2<<1)
++#define GE_ADCSET_CALMASK (3<<1)
++#define GE_ADC(x) (0x70 + (x))
++#define GE_ADCCALIB(x) (0x74 + (x))
++#define GE_ADCGCAL(x) (0x78 + (x))
++#define GE_ADCSCAL(x) (0x7C + (x))
++#define GE_SETUP_USART 0x80
++#define GE_VERSION 0x81
++#define GE_USART(x) (0x90 + (x))
++#define GE_BUSART(x) ((int) (x) - 0x90)
++#define GE_CNTER_GET 0xA0
++#define GE_CNTER_SET 0xA1
++#define GE_BL_INFO 0xF0
++#define GE_BL_CMD 0xF1
++#define GE_BL_CMD_ERASEALL 0x10
++#define GE_BL_CMD_ERASE 0x11
++#define GE_BL_CMD_WRITE 0x12
++#define GE_BL_CMD_LOAD 0x13
++#define GE_BL_CMD_RESET 0xFF
++#define GE_BL_DATA 0xF2
++#define GE_BL_CHKSUM 0xF3
++
++#endif
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0017-AT91-raising-the-number-of-GPIOs-to-support-addition.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0017-AT91-raising-the-number-of-GPIOs-to-support-addition.patch
new file mode 100644
index 0000000000..da13b9df72
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0017-AT91-raising-the-number-of-GPIOs-to-support-addition.patch
@@ -0,0 +1,25 @@
+From 7a34372ce1f84edc36fde3ab3bdf3943c21d2e6a Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:53:49 +0100
+Subject: [PATCH 17/18] [AT91] raising the number of GPIOs to support additional GPIO-Chips
+
+---
+ arch/arm/mach-at91/include/mach/irqs.h | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h
+index 36bd55f..97cd0fe 100644
+--- a/arch/arm/mach-at91/include/mach/irqs.h
++++ b/arch/arm/mach-at91/include/mach/irqs.h
+@@ -40,7 +40,7 @@
+ * symbols in gpio.h for ones handled indirectly as GPIOs.
+ * We make provision for 5 banks of GPIO.
+ */
+-#define NR_IRQS (NR_AIC_IRQS + (5 * 32))
++#define NR_IRQS 256 /*(NR_AIC_IRQS + (5 * 32))*/
+
+ /* FIQ is AIC source 0. */
+ #define FIQ_START AT91_ID_FIQ
+--
+1.7.3.3
+
diff --git a/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0018-ICnova-Adding-ADB4000.patch b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0018-ICnova-Adding-ADB4000.patch
new file mode 100644
index 0000000000..5973307e7d
--- /dev/null
+++ b/recipes/linux/linux-2.6.33/adb4000/linux-2.6.33.2-0018-ICnova-Adding-ADB4000.patch
@@ -0,0 +1,448 @@
+From f5432c38d18ae2b36483ab485ea4d2a3363302de Mon Sep 17 00:00:00 2001
+From: Benjamin Tietz <benjamin.tietz@in-circuit.de>
+Date: Thu, 16 Dec 2010 13:55:21 +0100
+Subject: [PATCH 18/18] [ICnova] Adding ADB4000
+
+This will add support for the ICnova ADB4000 equipped with an
+ICnova SAM9G45 SO-Dimm.
+---
+ arch/arm/mach-at91/Kconfig | 9 +-
+ arch/arm/mach-at91/Makefile | 1 +
+ arch/arm/mach-at91/at91sam9g45_devices.c | 2 +
+ arch/arm/mach-at91/board-icnova_adb4000.c | 371 +++++++++++++++++++++++++++++
+ 4 files changed, 381 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/mach-at91/board-icnova_adb4000.c
+
+diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
+index 3c984e1..82fb410 100644
+--- a/arch/arm/mach-at91/Kconfig
++++ b/arch/arm/mach-at91/Kconfig
+@@ -386,8 +386,7 @@ config MACH_ICNOVA_ADB1004
+ bool "In-Circuit ADB1004 G45 Evaluation Kit"
+ help
+ Select this if you are using In-Circuit's ICnova G45 on an ADB1004
+- Development Board. The Configration currently supports the version
+- using the 4.3inch Display
++ Development Board.
+
+ config MACH_ICNOVA_ADB3000
+ bool "In-Circuit ADB3000 G45/FPGA Evaluation Kit"
+@@ -395,6 +394,12 @@ config MACH_ICNOVA_ADB3000
+ Select this if you are using In-Circuit's ICnova G45 on an ADB3000
+ Development Board.
+
++config MACH_ICNOVA_ADB4000
++ bool "In-Circuit ADB4000 G45-SODIMM Evaluation Kit"
++ help
++ Select this if you are using In-Circuit's ICnova G45 SO-Dimm on an
++ ADB4000 Development Board.
++
+ endif
+
+ config ICNOVA_ET050000
+diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
+index be44d7f..c982c06 100644
+--- a/arch/arm/mach-at91/Makefile
++++ b/arch/arm/mach-at91/Makefile
+@@ -69,6 +69,7 @@ obj-$(CONFIG_MACH_ICNOVA_ADB1000) += board-icnova_adb1000.o
+ obj-$(CONFIG_MACH_ICNOVA_ADB1002) += board-icnova_adb1002.o
+ obj-$(CONFIG_MACH_ICNOVA_ADB1004) += board-icnova_adb1004.o
+ obj-$(CONFIG_MACH_ICNOVA_ADB3000) += board-icnova_adb3000.o
++obj-$(CONFIG_MACH_ICNOVA_ADB4000) += board-icnova_adb4000.o
+
+ # AT91CAP9 board-specific support
+ obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 0f9955f..f0126de 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -502,7 +502,9 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
+ at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */
++#ifndef CONFIG_MACH_ICNOVA_ADB4000
+ at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */
++#endif
+ }
+
+ eth_data = *data;
+diff --git a/arch/arm/mach-at91/board-icnova_adb4000.c b/arch/arm/mach-at91/board-icnova_adb4000.c
+new file mode 100644
+index 0000000..f079b4c
+--- /dev/null
++++ b/arch/arm/mach-at91/board-icnova_adb4000.c
+@@ -0,0 +1,371 @@
++/*
++ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
++ *
++ * Covers: * AT91SAM9G45-EKES board
++ * * AT91SAM9M10G45-EK board
++ *
++ * Copyright (C) 2009 Atmel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/ads7846.h>
++#include <linux/fb.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
++#include <linux/leds.h>
++#include <linux/clk.h>
++
++#include <mach/hardware.h>
++#include <video/atmel_lcdc.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/gpio.h>
++#include <mach/at91sam9_smc.h>
++#include <mach/at91_shdwc.h>
++
++#include "sam9_smc.h"
++#include "generic.h"
++
++
++static void __init ek_map_io(void)
++{
++ /* Initialize processor: 12.000 MHz crystal */
++ at91sam9g45_initialize(12000000);
++
++ /* DGBU on ttyS0. (Rx & Tx only) */
++ at91_register_uart(0, 0, 0);
++
++ // For RS485 you might enable ATMEL_UART_RTS instead of 0
++ at91_register_uart(AT91SAM9G45_ID_US0, 1, 0);
++ at91_register_uart(AT91SAM9G45_ID_US1, 2, 0);
++ at91_register_uart(AT91SAM9G45_ID_US2, 3, 0);
++ //at91_register_uart(AT91SAM9G45_ID_US3, 4, 0);
++
++ /* set serial console to ttyS0 (ie, DBGU) */
++ at91_set_serial_console(0);
++}
++
++static void __init ek_init_irq(void)
++{
++ at91sam9g45_init_interrupts(NULL);
++}
++
++
++/*
++ * USB HS Host port (common to OHCI & EHCI)
++ */
++static struct at91_usbh_data __initdata ek_usbh_hs_data = {
++ .ports = 2,
++// .vbus_pin = {AT91_PIN_PB12, AT91_PIN_PB13, },
++};
++
++/*
++ * I2C devices
++ */
++static struct i2c_board_info icnova_i2c[] = {
++ { I2C_BOARD_INFO("m41t82", 0x68) },
++};
++
++static struct i2c_board_info icnova_i2c2[] = {
++};
++
++/*
++ * SPI devices.
++ */
++
++#define CONFIG_BOARD_ICNOVA_ADS7846_IRQ AT91_PIN_PC30
++#define CONFIG_BOARD_ICNOVA_ADS7846_CS 1
++static struct ads7846_platform_data ads_info = {
++ .model = 7846,
++ .vref_delay_usecs = 100,
++ .gpio_pendown = CONFIG_BOARD_ICNOVA_ADS7846_IRQ,
++ .x_min = 180,//330,
++ .y_min = 3827,//3700,
++ .x_max = 3900,//3700,
++ .y_max = 150,//330,
++ .xy_fuzz = 40,
++ .pressure_max = 0xFFF0,
++ .pressure_min = 0xF100,
++ .settle_delay_usecs = 200,
++ .debounce_rep = 4,
++ .debounce_tol = 40,
++ .debounce_max = 10,
++};
++
++static struct spi_board_info ek_spi_devices[] = {
++ {
++ .modalias = "ads7846",
++ .max_speed_hz = 125000 * 26,
++ .chip_select = CONFIG_BOARD_ICNOVA_ADS7846_CS,
++ .platform_data = &ads_info,
++ .bus_num = 0,
++ .controller_data = (void *) AT91_PIN_PD24,
++ },
++ {
++ .modalias = "supervisor",
++ .max_speed_hz = 550000,
++ .chip_select = 0,
++ .platform_data = NULL,
++ .bus_num = 0,
++ },
++
++};
++
++
++/*
++ * MACB Ethernet device
++ */
++static struct at91_eth_data __initdata ek_macb_data = {
++ .phy_irq_pin = AT91_PIN_PA27,
++};
++
++
++/*
++ * NAND flash
++ */
++static struct mtd_partition __initdata ek_nand_partition[] = {
++ {
++ .name = "Kernel",
++ .offset = 0,
++ .size = SZ_4M,
++ },
++ {
++ .name = "Data",
++ .offset = MTDPART_OFS_NXTBLK,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(ek_nand_partition);
++ return ek_nand_partition;
++}
++
++/* det_pin is not connected */
++static struct atmel_nand_data __initdata ek_nand_data = {
++ .ale = 21,
++ .cle = 22,
++ .rdy_pin = AT91_PIN_PC8,
++ .enable_pin = AT91_PIN_PC14,
++ .partition_info = nand_partitions,
++ .bus_width_16 = 0,
++};
++
++static struct sam9_smc_config __initdata ek_nand_smc_config = {
++ .ncs_read_setup = 0,
++ .nrd_setup = 10,
++ .ncs_write_setup = 0,
++ .nwe_setup = 10,
++
++ .ncs_read_pulse = 50,
++ .nrd_pulse = 30,
++ .ncs_write_pulse = 50,
++ .nwe_pulse = 30,
++
++ .read_cycle = 60,
++ .write_cycle = 60,
++
++ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
++ .tdf_cycles = 4,
++};
++
++static void __init ek_add_device_nand(void)
++{
++ /* configure chip-select 3 (NAND) */
++ sam9_smc_configure(3, &ek_nand_smc_config);
++
++ at91_add_device_nand(&ek_nand_data);
++}
++
++/*
++ * MCI (SD/MMC)
++ */
++static struct mci_platform_data __initdata ek_mmc_data = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PC6,
++ .wp_pin = -1,
++ },
++};
++
++static struct mci_platform_data __initdata ek_mmc_data1 = {
++ .slot[0] = {
++ .bus_width = 4,
++ .detect_pin = AT91_PIN_PC7,
++ .wp_pin = -1,
++ },
++};
++
++
++/*
++ * LCD Controller
++ */
++#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
++static struct fb_videomode at91_tft_vga_modes[] = {
++ {
++ .name = "VGA",
++ .refresh = 50,
++ .xres = 800, .yres = 480,
++ .pixclock = 25000,
++
++ .left_margin = 178, .right_margin = 38,
++ .upper_margin = 35, .lower_margin = 8,
++ .hsync_len = 40, .vsync_len = 2,
++
++ .vmode = FB_VMODE_NONINTERLACED,
++ }
++};
++
++static struct fb_monspecs at91fb_default_monspecs = {
++ .manufacturer = "Hita",
++ .monitor = "TX20D26VM0APA",
++
++ .modedb = at91_tft_vga_modes,
++ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
++ .hfmin = 16700,
++ .hfmax = 41700,
++ .vfmin = 47,
++ .vfmax = 75,
++};
++
++#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
++ | ATMEL_LCDC_DISTYPE_TFT \
++ | ATMEL_LCDC_INVCLK \
++ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
++ //| ATMEL_LCDC_INVDVAL
++
++/* Driver datas */
++static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
++ .lcdcon_is_backlight = true,
++ .default_bpp = /*24*/16,
++ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
++ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
++ .default_monspecs = &at91fb_default_monspecs,
++ .guard_time = 9,
++ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
++};
++
++#else
++static struct atmel_lcdfb_info __initdata ek_lcdc_data;
++#endif
++
++#if 0
++static struct platform_device icnova_pwmdev = {
++ .name = "atmel-pwm-hwmon",
++ .id = 0,
++};
++#endif
++
++/*
++ * Btns
++ */
++static struct gpio_keys_button buttons[] = {
++#ifdef CONFIG_SUPERVISOR_IRQ
++ {
++ .code = KEY_BACK,
++ .gpio = 240,
++ .active_low = 1,
++ .desc = "back",
++ .wakeup = 1,
++ },
++ {
++ .code = KEY_HOME,
++ .gpio = 241,
++ .active_low = 1,
++ .desc = "home",
++ .wakeup = 1,
++ },
++ {
++ .code = KEY_MENU,
++ .gpio = 242,
++ .active_low = 1,
++ .desc = "menu",
++ .wakeup = 1,
++ },
++#endif
++};
++
++static struct gpio_keys_platform_data button_data = {
++ .buttons = buttons,
++ .nbuttons = ARRAY_SIZE(buttons),
++};
++
++static struct platform_device button_device = {
++ .name = "gpio-keys",
++ .id = -1,
++ .num_resources = 0,
++ .dev = {
++ .platform_data = &button_data,
++ },
++};
++
++
++static void __init ek_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* USB HS Host */
++ gpio_request(AT91_PIN_PB8, "usbhub.reset");
++ gpio_direction_output(AT91_PIN_PB8, 1);
++ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
++ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
++ /* USB HS Device */
++ at91_add_device_usba(NULL);
++ /* SPI */
++ ek_spi_devices[0].irq = gpio_to_irq(CONFIG_BOARD_ICNOVA_ADS7846_IRQ),
++ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
++ /* MMC */
++ at91_add_device_mci(0, &ek_mmc_data);
++ at91_add_device_mci(1, &ek_mmc_data1);
++ /* Ethernet */
++ at91_add_device_eth(&ek_macb_data);
++ /* NAND */
++ ek_add_device_nand();
++ /* I2C */
++ at91_add_device_i2c(0, icnova_i2c, ARRAY_SIZE(icnova_i2c));
++ at91_add_device_i2c(1, icnova_i2c2, ARRAY_SIZE(icnova_i2c2));
++ /* LCD Controller */
++ gpio_request(AT91_PIN_PE1, "lcdc.mode");
++ gpio_direction_output(AT91_PIN_PE1, 1);
++ gpio_request(AT91_PIN_PE0, "lcdc.pwr");
++ gpio_direction_output(AT91_PIN_PE0, 1);
++
++ at91_add_device_lcdc(&ek_lcdc_data);
++ /* SSC (for SSM2603) */
++ at91_add_device_ssc(AT91SAM9G45_ID_SSC0,
++ ATMEL_SSC_TX|ATMEL_SSC_RD|ATMEL_SSC_RF);
++ /* BTN */
++ platform_device_register(&button_device);
++}
++
++MACHINE_START(AT91SAM9G45EKES, "In-Circuit ICnova SAM9G45 SO-DIMM")
++ /* Maintainer: Atmel */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91sam926x_timer,
++ .map_io = ek_map_io,
++ .init_irq = ek_init_irq,
++ .init_machine = ek_board_init,
++MACHINE_END
+--
+1.7.3.3
+