diff options
Diffstat (limited to 'recipes/linux')
20 files changed, 8500 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 + diff --git a/recipes/linux/linux_2.6.33.bb b/recipes/linux/linux_2.6.33.bb index 3cff6c30e8..7f8b3a5ae6 100644 --- a/recipes/linux/linux_2.6.33.bb +++ b/recipes/linux/linux_2.6.33.bb @@ -12,6 +12,7 @@ DEFAULT_PREFERENCE_mpc8315e-rdb = "1" DEFAULT_PREFERENCE_mpc8544ds = "1" DEFAULT_PREFERENCE_imote2 = "1" DEFAULT_PREFERENCE_afeb9260 = "1" +DEFAULT_PREFERENCE_adb4000 = "1" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/${P}.tar.bz2;name=kernel \ file://defconfig" @@ -47,5 +48,26 @@ SRC_URI_append_afeb9260 = " \ file://0007-Adding-4th-serial-port.patch \ " +SRC_URI_append_adb4000 = " \ + http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.33.2.bz2 \ + file://linux-2.6.33.2-0001-misc-fpga_sram-added-driver-for-a-memory-connected-F.patch \ + file://linux-2.6.33.2-0002-tfp410-added-driver-for-tfp410-DVI-Controller.patch \ + file://linux-2.6.33.2-0003-drivers-at91_mci-modified-MMC-Host-to-work-on-G45.patch \ + file://linux-2.6.33.2-0004-.gitignore-ignore-arm-image-output.patch \ + file://linux-2.6.33.2-0005-arm-mach-at91-Add-support-for-icnova-boards.patch \ + file://linux-2.6.33.2-0006-ICnova-Add-support-for-ADB1004revB-and-5In-Displays.patch \ + file://linux-2.6.33.2-0007-atmel_tsadcc-adding-support-for-pressure-measurement.patch \ + file://linux-2.6.33.2-0008-atmel_serial-adding-support-for-RS485.patch \ + file://linux-2.6.33.2-0009-ICnova-add-support-for-ADB3000-revB.patch \ + file://linux-2.6.33.2-0010-atmel-pwm-Making-driver-selectable-for-SAM9G45.patch \ + file://linux-2.6.33.2-0011-hwmon-atm_pwm-adding-new-Userspace-atmel-pwm-interfa.patch \ + file://linux-2.6.33.2-0012-ICnova-configuring-the-buzzer.patch \ + file://linux-2.6.33.2-0013-sound-soc-adding-ssm2603-attached-to-atmel-ssc.patch \ + file://linux-2.6.33.2-0014-ICnova-ADB1000-Adding-BPP-to-16.patch \ + file://linux-2.6.33.2-0015-ADS7846-Adding-option-to-support-fuzz-on-input.patch \ + file://linux-2.6.33.2-0016-ADB4000-Adding-support-for-the-IO-Processor.patch \ + file://linux-2.6.33.2-0017-AT91-raising-the-number-of-GPIOs-to-support-addition.patch \ + file://linux-2.6.33.2-0018-ICnova-Adding-ADB4000.patch \ + " |