aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Sujak <sujak.marek@gmail.com>2011-01-28 14:54:50 +0100
committerEric Bénard <eric@eukrea.com>2011-01-31 22:01:03 +0100
commite03b29400325613a8f48a802839fdebe920bb23a (patch)
tree57e1b9aefd7ba37b20298005d6f43f526df91b0e
parentf1b35fed6340d04e14ae5bfd647a4fd92c75a570 (diff)
downloadopenembedded-e03b29400325613a8f48a802839fdebe920bb23a.tar.gz
openembedded-e03b29400325613a8f48a802839fdebe920bb23a.tar.bz2
openembedded-e03b29400325613a8f48a802839fdebe920bb23a.zip
kernel: added support for vmx25 into recipe 2.6.35 kernel
* modified recipe linux_2.6.35.bb * added kernel-2.6.35 defconfig for vmx25 * added kernel-2.6.35 patch for vmx25 ** Most of significant pheripherals was tested on (x11-image, qt4e image) ** ethernet -> ok ** video -> 640x480, 800x480, 800x600 ** sd -> ok ** audio -> ok Signed-off-by: Marek Sujak <sujak.marek@gmail.com> Signed-off-by: Eric Bénard <eric@eukrea.com>
-rw-r--r--recipes/linux/linux-2.6.35/vmx25/defconfig1771
-rw-r--r--recipes/linux/linux-2.6.35/vmx25/linux-2.6.35-vmx25-20110112.patch28459
-rw-r--r--recipes/linux/linux_2.6.35.bb3
3 files changed, 30233 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.35/vmx25/defconfig b/recipes/linux/linux-2.6.35/vmx25/defconfig
new file mode 100644
index 0000000000..cbd23c5c18
--- /dev/null
+++ b/recipes/linux/linux-2.6.35/vmx25/defconfig
@@ -0,0 +1,1771 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35
+# Thu Jan 27 12:12:40 2011
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=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_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=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=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_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 is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX 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=y
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_NAND=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+CONFIG_ARCH_MX25=y
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MXC91231 is not set
+# CONFIG_ARCH_MX5 is not set
+
+#
+# MX25 platforms:
+#
+# CONFIG_MACH_MX25_3DS is not set
+CONFIG_MACH_VMX25=y
+CONFIG_MACH_VMX_BASEBOARD=y
+# CONFIG_VMX_SD_ON_MODULE is not set
+CONFIG_VMX_SD_ON_BOARD=y
+CONFIG_MXC_SDMA_API=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_MXC_PWM=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_MXC_SSI_PORTS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_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 is not set
+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_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttymxc0,115200 mem=32M@0x80000000 mem=32M@0x90000000 ip=dhcp ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs otg_mode=host video=imxfb:VGA-16@60"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_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=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_NVS=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_MCP251X=y
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+CONFIG_CAN_DEBUG_DEVICES=y
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+# CONFIG_DEVTMPFS_MOUNT is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# MXC support drivers
+#
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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 is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# 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_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP 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_NAND_MXC=y
+# 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=y
+
+#
+# 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=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_AT25 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_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# 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
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO 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=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+CONFIG_W1=y
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=y
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+CONFIG_W1_SLAVE_SMEM=y
+# 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=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+CONFIG_HAVE_FB_IMX=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=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_IMX=y
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 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=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_SGTL5000=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+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_3M_PCT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EGALAX is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+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 is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MXC=y
+# 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_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=y
+# 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_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_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=300
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+CONFIG_USB_GADGET_FSL_USB2=y
+CONFIG_USB_FSL_USB2=y
+# 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 is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_WEBCAM is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_NOP_USB_XCEIV=y
+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=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MMC_MXC is not set
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_SDHCI_MXC=y
+# CONFIG_MMC_SDHCI_MXC_SELECT2 is not set
+# CONFIG_MMC_SDHCI_MXC_PIO_MODE is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+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=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_MXC is not set
+CONFIG_RTC_DRV_IMXDI=y
+# 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_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_XATTR is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+CONFIG_JBD2=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_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 is not set
+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
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+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 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_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+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=y
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_FRAME_POINTER=y
+# 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_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_USER=y
+# 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_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/recipes/linux/linux-2.6.35/vmx25/linux-2.6.35-vmx25-20110112.patch b/recipes/linux/linux-2.6.35/vmx25/linux-2.6.35-vmx25-20110112.patch
new file mode 100644
index 0000000000..edbde2da8b
--- /dev/null
+++ b/recipes/linux/linux-2.6.35/vmx25/linux-2.6.35-vmx25-20110112.patch
@@ -0,0 +1,28459 @@
+diff -urN linux.35.old/arch/arm/configs/vmx25_defconfig linux.35.new/arch/arm/configs/vmx25_defconfig
+--- linux.35.old/arch/arm/configs/vmx25_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/configs/vmx25_defconfig 2010-12-21 12:20:30.725765123 +0100
+@@ -0,0 +1,1866 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.35
++# Tue Dec 21 12:20:04 2010
++#
++CONFIG_ARM=y
++CONFIG_HAVE_PWM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_FIQ=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_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=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=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++# CONFIG_TREE_RCU is not set
++# CONFIG_TREE_PREEMPT_RCU is not set
++CONFIG_TINY_RCU=y
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_SYSFS_DEPRECATED_V2 is not set
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_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 is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++# CONFIG_PERF_COUNTERS is not set
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++# CONFIG_SLUB is not set
++CONFIG_SLOB=y
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_CLK=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_SLOW_WORK is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBDAF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++# 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_VEXPRESS is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_BCMRING is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CNS3XXX 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=y
++# CONFIG_ARCH_STMP3XXX is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_NUC93X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P6440 is not set
++# CONFIG_ARCH_S5P6442 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_U8500 is not set
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_PLAT_SPEAR is not set
++CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
++CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
++CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
++CONFIG_IMX_HAVE_PLATFORM_MXC_NAND=y
++CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
++
++#
++# Freescale MXC Implementations
++#
++# CONFIG_ARCH_MX1 is not set
++# CONFIG_ARCH_MX2 is not set
++CONFIG_ARCH_MX25=y
++# CONFIG_ARCH_MX3 is not set
++# CONFIG_ARCH_MXC91231 is not set
++# CONFIG_ARCH_MX5 is not set
++
++#
++# MX25 platforms:
++#
++# CONFIG_MACH_MX25_3DS is not set
++CONFIG_MACH_VMX25=y
++CONFIG_MACH_VMX_BASEBOARD=y
++# CONFIG_VMX_SD_ON_MODULE is not set
++CONFIG_VMX_SD_ON_BOARD=y
++CONFIG_MXC_SDMA_API=y
++CONFIG_MXC_IRQ_PRIOR=y
++CONFIG_MXC_PWM=y
++CONFIG_ARCH_MXC_IOMUX_V3=y
++CONFIG_ARCH_MXC_AUDMUX_V2=y
++CONFIG_MXC_SSI_PORTS=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_LEGACY=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++CONFIG_COMMON_CLKDEV=y
++
++#
++# Bus support
++#
++# CONFIG_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 is not set
++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_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttymxc0,115200 mem=32M@0x80000000 mem=32M@0x90000000 ip=dhcp ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs otg_mode=host video=imxfb:VGA-16@60"
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++CONFIG_CPU_IDLE=y
++CONFIG_CPU_IDLE_GOV_LADDER=y
++CONFIG_CPU_IDLE_GOV_MENU=y
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_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_UNIX=y
++# 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=y
++# CONFIG_IP_PNP_BOOTP is not set
++# 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 is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP 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=y
++CONFIG_CAN_RAW=y
++CONFIG_CAN_BCM=y
++
++#
++# CAN Device Drivers
++#
++# CONFIG_CAN_VCAN is not set
++CONFIG_CAN_DEV=y
++CONFIG_CAN_CALC_BITTIMING=y
++CONFIG_CAN_MCP251X=y
++CONFIG_HAVE_CAN_FLEXCAN=y
++CONFIG_CAN_FLEXCAN=y
++# CONFIG_CAN_SJA1000 is not set
++
++#
++# CAN USB interfaces
++#
++# CONFIG_CAN_EMS_USB is not set
++CONFIG_CAN_DEBUG_DEVICES=y
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++# CONFIG_DEVTMPFS_MOUNT is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++
++#
++# MXC support drivers
++#
++
++#
++# i.MX ADC support
++#
++# CONFIG_IMX_ADC is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG 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 is not set
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++# 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_SM_FTL is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++CONFIG_MTD_M25P80=y
++# CONFIG_M25PXX_USE_FAST_READ is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND_ECC=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_SM_COMMON is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP 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_NAND_MXC=y
++# 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=y
++
++#
++# 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=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++CONFIG_EEPROM_AT24=y
++# CONFIG_EEPROM_AT25 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_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=y
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# 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
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++CONFIG_SMSC_PHY=y
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++CONFIG_FEC=y
++# CONFIG_FEC2 is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_WLAN is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_IPHETH is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# 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_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8323 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++CONFIG_KEYBOARD_IMX=y
++# 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 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 is not set
++# 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_ADS7846=y
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_DYNAPRO is not set
++# CONFIG_TOUCHSCREEN_HAMPSHIRE 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_MXC_TSC=y
++# CONFIG_TOUCHSCREEN_WM97XX 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_TOUCHSCREEN_TPS6507X is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++# CONFIG_DEVKMEM is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_IMX=y
++CONFIG_SERIAL_IMX_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_RAMOOPS is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_COMPAT is not set
++CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C_HELPER_AUTO is not set
++# CONFIG_I2C_SMBUS is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_DESIGNWARE is not set
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_IMX=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_BITBANG=y
++# CONFIG_SPI_GPIO is not set
++CONFIG_SPI_IMX=y
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++# CONFIG_GPIO_IT8761E is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_ADP5588 is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++CONFIG_W1=y
++CONFIG_W1_CON=y
++
++#
++# 1-wire Bus Masters
++#
++# CONFIG_W1_MASTER_DS2490 is not set
++# CONFIG_W1_MASTER_DS2482 is not set
++CONFIG_W1_MASTER_MXC=y
++# CONFIG_W1_MASTER_DS1WM is not set
++# CONFIG_W1_MASTER_GPIO is not set
++
++#
++# 1-wire Slaves
++#
++# CONFIG_W1_SLAVE_THERM is not set
++CONFIG_W1_SLAVE_SMEM=y
++# 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=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Native drivers
++#
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7411 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7475 is not set
++# CONFIG_SENSORS_ASC7621 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_G760A is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM73 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_LTC4215 is not set
++# CONFIG_SENSORS_LTC4245 is not set
++# CONFIG_SENSORS_LM95241 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_SHT15 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_EMC1403 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_ADS7871 is not set
++# CONFIG_SENSORS_AMC6821 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_TMP102 is not set
++# CONFIG_SENSORS_TMP401 is not set
++# CONFIG_SENSORS_TMP421 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_NOWAYOUT=y
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++CONFIG_IMX2_WDT=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++# CONFIG_MFD_SUPPORT is not set
++# CONFIG_REGULATOR is not set
++CONFIG_MEDIA_SUPPORT=y
++
++#
++# Multimedia core support
++#
++CONFIG_VIDEO_DEV=y
++CONFIG_VIDEO_V4L2_COMMON=y
++# CONFIG_VIDEO_ALLOW_V4L1 is not set
++CONFIG_VIDEO_V4L1_COMPAT=y
++# CONFIG_DVB_CORE is not set
++CONFIG_VIDEO_MEDIA=y
++
++#
++# Multimedia drivers
++#
++CONFIG_IR_CORE=y
++CONFIG_VIDEO_IR=y
++# CONFIG_RC_MAP is not set
++# CONFIG_IR_NEC_DECODER is not set
++# CONFIG_IR_RC5_DECODER is not set
++# CONFIG_IR_RC6_DECODER is not set
++# CONFIG_IR_JVC_DECODER is not set
++# CONFIG_IR_SONY_DECODER is not set
++# CONFIG_IR_IMON is not set
++CONFIG_MEDIA_TUNER=y
++CONFIG_MEDIA_TUNER_CUSTOMISE=y
++# CONFIG_MEDIA_TUNER_SIMPLE is not set
++# CONFIG_MEDIA_TUNER_TDA8290 is not set
++# CONFIG_MEDIA_TUNER_TDA827X is not set
++# CONFIG_MEDIA_TUNER_TDA18271 is not set
++# CONFIG_MEDIA_TUNER_TDA9887 is not set
++# CONFIG_MEDIA_TUNER_TEA5761 is not set
++# CONFIG_MEDIA_TUNER_TEA5767 is not set
++# CONFIG_MEDIA_TUNER_MT20XX is not set
++# CONFIG_MEDIA_TUNER_MT2060 is not set
++# CONFIG_MEDIA_TUNER_MT2266 is not set
++# CONFIG_MEDIA_TUNER_MT2131 is not set
++# CONFIG_MEDIA_TUNER_QT1010 is not set
++# CONFIG_MEDIA_TUNER_XC2028 is not set
++# CONFIG_MEDIA_TUNER_XC5000 is not set
++# CONFIG_MEDIA_TUNER_MXL5005S is not set
++# CONFIG_MEDIA_TUNER_MXL5007T is not set
++# CONFIG_MEDIA_TUNER_MC44S803 is not set
++# CONFIG_MEDIA_TUNER_MAX2165 is not set
++CONFIG_VIDEO_V4L2=y
++# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
++# CONFIG_V4L_MEM2MEM_DRIVERS is not set
++CONFIG_RADIO_ADAPTERS=y
++# CONFIG_I2C_SI4713 is not set
++# CONFIG_RADIO_SI4713 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_RADIO_SI470X is not set
++# CONFIG_USB_MR800 is not set
++# CONFIG_RADIO_TEA5764 is not set
++# CONFIG_RADIO_SAA7706H is not set
++# CONFIG_RADIO_TEF6862 is not set
++CONFIG_RADIO_SI4705=y
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++CONFIG_HAVE_FB_IMX=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=y
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++CONFIG_FB_IMX=y
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_LCD_CLASS_DEVICE is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++# CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_PWM=y
++# CONFIG_BACKLIGHT_ADP8860 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=y
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_DYNAMIC_MINORS=y
++CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++# CONFIG_SND_USB is not set
++CONFIG_SND_SOC=y
++CONFIG_SND_SOC_AC97_BUS=y
++CONFIG_SND_IMX_SOC=y
++CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y
++CONFIG_SND_SOC_I2C_AND_SPI=y
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_SGTL5000=y
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++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_3M_PCT is not set
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CANDO is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_PRODIKEYS is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EGALAX is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MOSART is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_QUANTA is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_ROCCAT_KONE is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_STANTUM is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++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=y
++# CONFIG_USB_OTG_WHITELIST is not set
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_MXC=y
++# 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_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_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_GADGET=y
++CONFIG_USB_GADGET_DEBUG_FILES=y
++CONFIG_USB_GADGET_VBUS_DRAW=300
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++CONFIG_USB_GADGET_FSL_USB2=y
++CONFIG_USB_FSL_USB2=y
++# 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 is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=y
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++# CONFIG_USB_MASS_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_NOKIA is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_WEBCAM 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=y
++# CONFIG_MMC_SDHCI_PLTFM is not set
++# CONFIG_MMC_MXC is not set
++# CONFIG_MMC_SPI is not set
++CONFIG_MMC_SDHCI_MXC=y
++# CONFIG_MMC_SDHCI_MXC_SELECT2 is not set
++# CONFIG_MMC_SDHCI_MXC_PIO_MODE is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_LEDS_PCA9532 is not set
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO_PLATFORM=y
++# CONFIG_LEDS_LP3944 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_PWM is not set
++# CONFIG_LEDS_BD2802 is not set
++# CONFIG_LEDS_LT3593 is not set
++CONFIG_LEDS_TRIGGERS=y
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
++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=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_MXC is not set
++CONFIG_RTC_DRV_IMXDI=y
++# 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_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# 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=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++CONFIG_EXT4_FS=y
++# CONFIG_EXT4_FS_XATTR is not set
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD=y
++CONFIG_JBD2=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_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 is not set
++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
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++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 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_LOGFS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CEPH_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-15"
++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=y
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_NLS_ISO8859_2=y
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_MEMORY_INIT is not set
++CONFIG_FRAME_POINTER=y
++# 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_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_ARM_UNWIND is not set
++CONFIG_DEBUG_USER=y
++# 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_MANAGER is not set
++# CONFIG_CRYPTO_MANAGER2 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_RATIONAL=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
++CONFIG_GENERIC_ATOMIC64=y
+diff -urN linux.35.old/arch/arm/mach-mx25/clock.c linux.35.new/arch/arm/mach-mx25/clock.c
+--- linux.35.old/arch/arm/mach-mx25/clock.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/clock.c 2010-12-03 09:51:55.345346913 +0100
+@@ -51,6 +51,7 @@
+ #define CCM_LTR1 0x44
+ #define CCM_LTR2 0x48
+ #define CCM_LTR3 0x4c
++#define CCM_MCR 0x64
+
+ static unsigned long get_rate_mpll(void)
+ {
+@@ -72,7 +73,7 @@
+ unsigned long rate = get_rate_mpll();
+
+ if (cctl & (1 << 14))
+- rate = (rate * 3) >> 1;
++ rate = (rate * 3) >> 2;
+
+ return rate / ((cctl >> 30) + 1);
+ }
+@@ -96,10 +97,10 @@
+ unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
+ unsigned long fref;
+
+- if (readl(CRM_BASE + 0x64) & (1 << per))
++ if (readl(CRM_BASE + CCM_MCR) & (1 << per))
+ fref = get_rate_upll();
+ else
+- fref = get_rate_ipg(NULL);
++ fref = get_rate_ahb(NULL);
+
+ return fref / (val + 1);
+ }
+@@ -109,11 +110,26 @@
+ return get_rate_per(15);
+ }
+
++static unsigned long get_rate_ssi2(struct clk *clk)
++{
++ return get_rate_per(14);
++}
++
++static unsigned long get_rate_ssi1(struct clk *clk)
++{
++ return get_rate_per(13);
++}
++
+ static unsigned long get_rate_i2c(struct clk *clk)
+ {
+ return get_rate_per(6);
+ }
+
++static unsigned long get_rate_owire(struct clk *clk)
++{
++ return get_rate_per(9);
++}
++
+ static unsigned long get_rate_nfc(struct clk *clk)
+ {
+ return get_rate_per(8);
+@@ -129,9 +145,41 @@
+ return get_rate_per(7);
+ }
+
++static unsigned long get_rate_esdhc1(struct clk *clk)
++{
++ return get_rate_per(3);
++}
++
++static unsigned long get_rate_esdhc2(struct clk *clk)
++{
++ return get_rate_per(4);
++}
++
++static unsigned long get_rate_csi(struct clk *clk)
++{
++ return get_rate_per(0);
++}
++
+ static unsigned long get_rate_otg(struct clk *clk)
+ {
+- return 48000000; /* FIXME */
++ unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
++ unsigned long rate = get_rate_upll();
++
++ return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
++}
++
++static int set_rate_otg(struct clk *clk, unsigned long rate)
++{
++ u32 cctl = __raw_readl(CRM_BASE+CCM_CCTL) & ~(0x3f << 16);
++ unsigned long fref = get_rate_upll();
++ u32 usbdiv = (fref / rate) - 1;
++
++ if (usbdiv > 0x3f) {
++ return -1;
++ }
++ cctl |= usbdiv << 16;
++ __raw_writel(cctl, CRM_BASE+CCM_CCTL);
++ return 0;
+ }
+
+ static int clk_cgcr_enable(struct clk *clk)
+@@ -154,6 +202,10 @@
+ __raw_writel(reg, clk->enable_reg);
+ }
+
++static struct clk ahb_clk = {
++ .get_rate = get_rate_ahb,
++};
++
+ #define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
+ static struct clk name = { \
+ .id = i, \
+@@ -168,19 +220,23 @@
+
+ DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
+ DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
++DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
++DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
+ DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
+ DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
++DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
++DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
+ DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
+-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
++DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, set_rate_otg, NULL);
+ DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
+@@ -191,6 +247,23 @@
+ DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
+ DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
++DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
++DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, NULL, NULL, NULL);
++DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, NULL, NULL, &esdhc1_ahb_clk);
++DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL, &esdhc1_per_clk);
++DEFINE_CLOCK(esdhc2_ahb_clk, 1, CCM_CGCR0, 22, NULL, NULL, NULL);
++DEFINE_CLOCK(esdhc2_per_clk, 1, CCM_CGCR0, 4, NULL, NULL, &esdhc2_ahb_clk);
++DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL, &esdhc2_per_clk);
++DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
++DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
++DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
++DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
++DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
++DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
++DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
++DEFINE_CLOCK(can2_clk, 0, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
++DEFINE_CLOCK(owire_clk, 0, CCM_CGCR0, 9, get_rate_owire, NULL, NULL);
++
+
+ #define _REGISTER_CLOCK(d, n, c) \
+ { \
+@@ -200,6 +273,8 @@
+ },
+
+ static struct clk_lookup lookups[] = {
++ _REGISTER_CLOCK(NULL, "ahb", ahb_clk)
++ _REGISTER_CLOCK(NULL, "sdma", sdma_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+@@ -217,14 +292,25 @@
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
+ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
+ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
+- _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+- _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
++ _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
++ _REGISTER_CLOCK("imx_adc.0", "tsc_clk", tsc_clk)
++ _REGISTER_CLOCK("imx-tsc.0", NULL, tsc_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
++ _REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk)
++ _REGISTER_CLOCK("sdhci.0", NULL, esdhc1_clk)
++ _REGISTER_CLOCK("sdhci.1", NULL, esdhc2_clk)
++ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
++ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
++ _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
++ _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
++ _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
++ _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
++ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ };
+
+ int __init mx25_clocks_init(void)
+@@ -244,5 +330,25 @@
+
+ mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+
++ /* Debug info */
++ pr_info("Fin: %3lu.%03luMHz\n", \
++ (unsigned long) (24000000 / 1000000),
++ (unsigned long) (24000000 / 1000 % 1000));
++ pr_info("MPLL: %3lu.%03luMHz\n", \
++ get_rate_mpll() / 1000000,
++ get_rate_mpll() / 1000 % 1000);
++ pr_info("UPLL: %3lu.%03luMHz\n", \
++ get_rate_upll() / 1000000,
++ get_rate_upll() / 1000 % 1000);
++ pr_info("CPU: %3lu.%03luMHz\n", \
++ get_rate_arm(NULL) / 1000000,
++ get_rate_arm(NULL) / 1000 % 1000);
++ pr_info("AHB: %3lu.%03luMHz\n", \
++ get_rate_ahb(NULL) / 1000000,
++ get_rate_ahb(NULL) / 1000 % 1000);
++ pr_info("IPG: %3lu.%03luMHz\n", \
++ get_rate_ipg(NULL) / 1000000,
++ get_rate_ipg(NULL) / 1000 % 1000);
++
+ return 0;
+ }
+diff -urN linux.35.old/arch/arm/mach-mx25/devices.c linux.35.new/arch/arm/mach-mx25/devices.c
+--- linux.35.old/arch/arm/mach-mx25/devices.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/devices.c 2010-12-03 09:51:55.345346913 +0100
+@@ -21,103 +21,59 @@
+ #include <linux/gpio.h>
+ #include <mach/mx25.h>
+ #include <mach/irqs.h>
++#include <mach/sdma.h>
+
+-static struct resource uart0[] = {
+- {
+- .start = 0x43f90000,
+- .end = 0x43f93fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 45,
+- .end = 45,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_uart_device0 = {
+- .name = "imx-uart",
+- .id = 0,
+- .resource = uart0,
+- .num_resources = ARRAY_SIZE(uart0),
+-};
+-
+-static struct resource uart1[] = {
+- {
+- .start = 0x43f94000,
+- .end = 0x43f97fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 32,
+- .end = 32,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_uart_device1 = {
+- .name = "imx-uart",
+- .id = 1,
+- .resource = uart1,
+- .num_resources = ARRAY_SIZE(uart1),
+-};
+-
+-static struct resource uart2[] = {
+- {
+- .start = 0x5000c000,
+- .end = 0x5000ffff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 18,
+- .end = 18,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_uart_device2 = {
+- .name = "imx-uart",
+- .id = 2,
+- .resource = uart2,
+- .num_resources = ARRAY_SIZE(uart2),
+-};
+-
+-static struct resource uart3[] = {
+- {
+- .start = 0x50008000,
+- .end = 0x5000bfff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 5,
+- .end = 5,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_uart_device3 = {
+- .name = "imx-uart",
+- .id = 3,
+- .resource = uart3,
+- .num_resources = ARRAY_SIZE(uart3),
+-};
++#include "sdma_script_code.h"
+
+-static struct resource uart4[] = {
+- {
+- .start = 0x5002c000,
+- .end = 0x5002ffff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 40,
+- .end = 40,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_uart_device4 = {
+- .name = "imx-uart",
+- .id = 4,
+- .resource = uart4,
+- .num_resources = ARRAY_SIZE(uart4),
+-};
+-
+-#define MX25_OTG_BASE_ADDR 0x53FF4000
++void mxc_sdma_get_script_info(sdma_script_start_addrs *sdma_script_addr)
++{
++ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR;
++ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
++ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
++ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
++ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
++
++ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
++ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1;
++ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
++ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1;
++
++ sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR;
++ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR;
++ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR;
++ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR;
++
++ sdma_script_addr->mxc_sdma_per_2_per_addr = -1;
++
++ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_per_ADDR;
++ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR;
++ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR;
++ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR;
++
++ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR;
++ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR;
++
++ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR;
++ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR;
++ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR;
++ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR;
++
++ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1;
++ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1;
++
++ sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1;
++ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = -1;
++
++ sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = -1;
++
++ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1;
++ sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = ext_mem__ipu_ram_ADDR;
++ sdma_script_addr->mxc_sdma_descrambler_addr = -1;
++
++ sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code;
++ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
++ sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR;
++}
+
+ static u64 otg_dmamask = DMA_BIT_MASK(32);
+
+@@ -181,63 +137,6 @@
+ .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
+ };
+
+-static struct resource mxc_spi_resources0[] = {
+- {
+- .start = 0x43fa4000,
+- .end = 0x43fa7fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 14,
+- .end = 14,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_spi_device0 = {
+- .name = "spi_imx",
+- .id = 0,
+- .num_resources = ARRAY_SIZE(mxc_spi_resources0),
+- .resource = mxc_spi_resources0,
+-};
+-
+-static struct resource mxc_spi_resources1[] = {
+- {
+- .start = 0x50010000,
+- .end = 0x50013fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 13,
+- .end = 13,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_spi_device1 = {
+- .name = "spi_imx",
+- .id = 1,
+- .num_resources = ARRAY_SIZE(mxc_spi_resources1),
+- .resource = mxc_spi_resources1,
+-};
+-
+-static struct resource mxc_spi_resources2[] = {
+- {
+- .start = 0x50004000,
+- .end = 0x50007fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 0,
+- .end = 0,
+- .flags = IORESOURCE_IRQ,
+- },
+-};
+-
+-struct platform_device mxc_spi_device2 = {
+- .name = "spi_imx",
+- .id = 2,
+- .num_resources = ARRAY_SIZE(mxc_spi_resources2),
+- .resource = mxc_spi_resources2,
+-};
+-
+ static struct resource mxc_pwm_resources0[] = {
+ {
+ .start = 0x53fe0000,
+@@ -308,7 +207,7 @@
+ };
+
+ struct platform_device mxc_keypad_device = {
+- .name = "mxc-keypad",
++ .name = "imx-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mxc_keypad_resources),
+ .resource = mxc_keypad_resources,
+@@ -333,63 +232,6 @@
+ .resource = mxc_pwm_resources3,
+ };
+
+-static struct resource mxc_i2c_1_resources[] = {
+- {
+- .start = 0x43f80000,
+- .end = 0x43f83fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 3,
+- .end = 3,
+- .flags = IORESOURCE_IRQ,
+- }
+-};
+-
+-struct platform_device mxc_i2c_device0 = {
+- .name = "imx-i2c",
+- .id = 0,
+- .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+- .resource = mxc_i2c_1_resources,
+-};
+-
+-static struct resource mxc_i2c_2_resources[] = {
+- {
+- .start = 0x43f98000,
+- .end = 0x43f9bfff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 4,
+- .end = 4,
+- .flags = IORESOURCE_IRQ,
+- }
+-};
+-
+-struct platform_device mxc_i2c_device1 = {
+- .name = "imx-i2c",
+- .id = 1,
+- .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+- .resource = mxc_i2c_2_resources,
+-};
+-
+-static struct resource mxc_i2c_3_resources[] = {
+- {
+- .start = 0x43f84000,
+- .end = 0x43f87fff,
+- .flags = IORESOURCE_MEM,
+- }, {
+- .start = 10,
+- .end = 10,
+- .flags = IORESOURCE_IRQ,
+- }
+-};
+-
+-struct platform_device mxc_i2c_device2 = {
+- .name = "imx-i2c",
+- .id = 2,
+- .num_resources = ARRAY_SIZE(mxc_i2c_3_resources),
+- .resource = mxc_i2c_3_resources,
+-};
+-
+ static struct mxc_gpio_port imx_gpio_ports[] = {
+ {
+ .chip.label = "gpio-0",
+@@ -461,12 +303,12 @@
+
+ static struct resource mx25_rtc_resources[] = {
+ {
+- .start = MX25_DRYICE_BASE_ADDR,
+- .end = MX25_DRYICE_BASE_ADDR + 0x40,
++ .start = DRYICE_BASE_ADDR,
++ .end = DRYICE_BASE_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+- .start = MX25_INT_DRYICE,
++ .start = MXC_INT_DRYICE_NORM,
+ .flags = IORESOURCE_IRQ
+ },
+ };
+@@ -515,3 +357,100 @@
+ .num_resources = ARRAY_SIZE(mxc_wdt_resources),
+ .resource = mxc_wdt_resources,
+ };
++
++/* imx adc driver */
++static struct resource imx_adc_resources[] = {
++ {
++ .start = TSC_BASE_ADDR,
++ .end = TSC_BASE_ADDR + PAGE_SIZE,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = MXC_INT_TSC,
++ .end = MXC_INT_TSC,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++struct platform_device imx_adc_device = {
++ .name = "imx_adc",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(imx_adc_resources),
++ .resource = imx_adc_resources,
++ .dev = {
++ .release = NULL,
++ },
++};
++
++
++static struct resource mx25_tsc_resources[] = {
++ {
++ .start = TSC_BASE_ADDR,
++ .end = TSC_BASE_ADDR + PAGE_SIZE,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = MXC_INT_TSC,
++ .end = MXC_INT_TSC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device mx25_tsc_device = {
++ .name = "imx-tsc",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(mx25_tsc_resources),
++ .resource = mx25_tsc_resources,
++};
++
++static struct resource mxc_w1_master_resources[] = {
++ {
++ .start = MX25_OWIRE_BASE_ADDR,
++ .end = MX25_OWIRE_BASE_ADDR + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++struct platform_device mxc_w1_master_device = {
++ .name = "mxc_w1",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
++ .resource = mxc_w1_master_resources,
++};
++
++static struct resource imx_ssi_resources0[] = {
++ {
++ .start = MX25_SSI1_BASE_ADDR,
++ .end = MX25_SSI1_BASE_ADDR + 0x3fff,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = MX25_INT_SSI1,
++ .end = MX25_INT_SSI1,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct resource imx_ssi_resources1[] = {
++ {
++ .start = MX25_SSI2_BASE_ADDR,
++ .end = MX25_SSI2_BASE_ADDR + 0x3fff,
++ .flags = IORESOURCE_MEM
++ }, {
++ .start = MX25_INT_SSI2,
++ .end = MX25_INT_SSI2,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device imx_ssi_device0 = {
++ .name = "imx-ssi",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(imx_ssi_resources0),
++ .resource = imx_ssi_resources0,
++};
++
++struct platform_device imx_ssi_device1 = {
++ .name = "imx-ssi",
++ .id = 1,
++ .num_resources = ARRAY_SIZE(imx_ssi_resources1),
++ .resource = imx_ssi_resources1,
++};
+\ No newline at end of file
+diff -urN linux.35.old/arch/arm/mach-mx25/devices.h linux.35.new/arch/arm/mach-mx25/devices.h
+--- linux.35.old/arch/arm/mach-mx25/devices.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/devices.h 2010-12-03 09:51:55.349345851 +0100
+@@ -22,3 +22,8 @@
+ extern struct platform_device mx25_rtc_device;
+ extern struct platform_device mx25_fb_device;
+ extern struct platform_device mxc_wdt;
++extern struct platform_device imx_adc_device;
++extern struct platform_device mx25_tsc_device;
++extern struct platform_device mxc_w1_master_device;
++extern struct platform_device imx_ssi_device0;
++extern struct platform_device imx_ssi_device1;
+\ No newline at end of file
+diff -urN linux.35.old/arch/arm/mach-mx25/devices-imx25.h linux.35.new/arch/arm/mach-mx25/devices-imx25.h
+--- linux.35.old/arch/arm/mach-mx25/devices-imx25.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/mach-mx25/devices-imx25.h 2010-12-03 09:51:55.349345851 +0100
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2010 Pengutronix
++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <mach/mx25.h>
++#include <mach/devices-common.h>
++
++#define imx25_add_flexcan0(pdata) \
++ imx_add_flexcan(0, MX25_CAN1_BASE_ADDR, SZ_16K, MX25_INT_CAN1, pdata)
++#define imx25_add_flexcan1(pdata) \
++ imx_add_flexcan(1, MX25_CAN2_BASE_ADDR, SZ_16K, MX25_INT_CAN2, pdata)
++
++#define imx25_add_imx_i2c0(pdata) \
++ imx_add_imx_i2c(0, MX25_I2C1_BASE_ADDR, SZ_16K, MX25_INT_I2C1, pdata)
++#define imx25_add_imx_i2c1(pdata) \
++ imx_add_imx_i2c(1, MX25_I2C2_BASE_ADDR, SZ_16K, MX25_INT_I2C2, pdata)
++#define imx25_add_imx_i2c2(pdata) \
++ imx_add_imx_i2c(2, MX25_I2C3_BASE_ADDR, SZ_16K, MX25_INT_I2C3, pdata)
++
++#define imx25_add_imx_uart0(pdata) \
++ imx_add_imx_uart_1irq(0, MX25_UART1_BASE_ADDR, SZ_16K, MX25_INT_UART1, pdata)
++#define imx25_add_imx_uart1(pdata) \
++ imx_add_imx_uart_1irq(1, MX25_UART2_BASE_ADDR, SZ_16K, MX25_INT_UART2, pdata)
++#define imx25_add_imx_uart2(pdata) \
++ imx_add_imx_uart_1irq(2, MX25_UART3_BASE_ADDR, SZ_16K, MX25_INT_UART3, pdata)
++#define imx25_add_imx_uart3(pdata) \
++ imx_add_imx_uart_1irq(3, MX25_UART4_BASE_ADDR, SZ_16K, MX25_INT_UART4, pdata)
++#define imx25_add_imx_uart4(pdata) \
++ imx_add_imx_uart_1irq(4, MX25_UART5_BASE_ADDR, SZ_16K, MX25_INT_UART5, pdata)
++
++#define imx25_add_mxc_nand(pdata) \
++ imx_add_mxc_nand_v21(MX25_NFC_BASE_ADDR, MX25_INT_NANDFC, pdata)
++
++#define imx25_add_spi_imx0(pdata) \
++ imx_add_spi_imx(0, MX25_CSPI1_BASE_ADDR, SZ_16K, MX25_INT_CSPI1, pdata)
++#define imx25_add_spi_imx1(pdata) \
++ imx_add_spi_imx(1, MX25_CSPI2_BASE_ADDR, SZ_16K, MX25_INT_CSPI2, pdata)
++#define imx25_add_spi_imx2(pdata) \
++ imx_add_spi_imx(2, MX25_CSPI3_BASE_ADDR, SZ_16K, MX25_INT_CSPI3, pdata)
+diff -urN linux.35.old/arch/arm/mach-mx25/dma.c linux.35.new/arch/arm/mach-mx25/dma.c
+--- linux.35.old/arch/arm/mach-mx25/dma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/mach-mx25/dma.c 2010-12-03 09:51:55.351854203 +0100
+@@ -0,0 +1,666 @@
++/*
++ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/scatterlist.h>
++#include <mach/hardware.h>
++#include <mach/dma.h>
++
++//#include "serial.h"
++
++#ifdef CONFIG_SND_MXC_SOC_IRAM
++#define soc_trans_type int_2_per
++#else
++#define soc_trans_type emi_2_per
++#endif
++
++#define MXC_SSI_TX0_REG 0x0
++#define MXC_SSI_TX1_REG 0x4
++#define MXC_SSI_RX0_REG 0x8
++#define MXC_SSI_RX1_REG 0xC
++#define MXC_SSI_TXFIFO_WML 0x4
++#define MXC_SSI_RXFIFO_WML 0x6
++
++#define MXC_ESAI_TX_REG 0x00
++#define MXC_ESAI_RX_REG 0x04
++#define MXC_ESAI_FIFO_WML 0x40
++
++struct mxc_sdma_info_entry_s {
++ mxc_dma_device_t device;
++ mxc_sdma_channel_params_t *chnl_info;
++};
++
++#if 0
++static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = {
++ .chnl_params = {
++ .watermark_level = UART1_UFCR_RXTL,
++ .per_address = UART1_BASE_ADDR,
++ .peripheral_type = UART,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_UART1_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART1_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = {
++ .chnl_params = {
++ .watermark_level = UART1_UFCR_TXTL,
++ .per_address = UART1_BASE_ADDR + MXC_UARTUTXD,
++ .peripheral_type = UART,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_UART1_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART1_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = {
++ .chnl_params = {
++ .watermark_level = UART2_UFCR_RXTL,
++ .per_address = UART2_BASE_ADDR,
++ .peripheral_type = UART,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_UART2_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART2_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = {
++ .chnl_params = {
++ .watermark_level = UART2_UFCR_TXTL,
++ .per_address = UART2_BASE_ADDR + MXC_UARTUTXD,
++ .peripheral_type = UART,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_UART2_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART2_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = {
++ .chnl_params = {
++ .watermark_level = UART3_UFCR_RXTL,
++ .per_address = UART3_BASE_ADDR,
++ .peripheral_type = UART_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_UART3_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART3_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = {
++ .chnl_params = {
++ .watermark_level = UART3_UFCR_TXTL,
++ .per_address = UART3_BASE_ADDR + MXC_UARTUTXD,
++ .peripheral_type = UART_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_UART3_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART3_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart4_rx_params = {
++ .chnl_params = {
++ .watermark_level = UART4_UFCR_RXTL,
++ .per_address = UART4_BASE_ADDR,
++ .peripheral_type = UART_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_UART4_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART4_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart4_tx_params = {
++ .chnl_params = {
++ .watermark_level = UART4_UFCR_TXTL,
++ .per_address = UART4_BASE_ADDR + MXC_UARTUTXD,
++ .peripheral_type = UART_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_UART4_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART4_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart5_rx_params = {
++ .chnl_params = {
++ .watermark_level = UART5_UFCR_RXTL,
++ .per_address = UART5_BASE_ADDR,
++ .peripheral_type = UART_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_UART5_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART5_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_uart5_tx_params = {
++ .chnl_params = {
++ .watermark_level = UART5_UFCR_TXTL,
++ .per_address = UART5_BASE_ADDR + MXC_UARTUTXD,
++ .peripheral_type = UART_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_UART5_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_UART5_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++#endif
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI1_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_SSI1_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX0,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_8BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_RXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_SSI2_RX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = {
++ .chnl_params = {
++ .watermark_level = MXC_SSI_TXFIFO_WML,
++ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
++ .peripheral_type = SSI_SP,
++ .transfer_type = emi_2_per,
++ .event_id = DMA_REQ_SSI2_TX1,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
++ .chnl_priority = 2,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_memory_params = {
++ .chnl_params = {
++ .peripheral_type = MEMORY,
++ .transfer_type = emi_2_emi,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_MEMORY,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_esai_16bit_rx_params = {
++ .chnl_params = {
++ .watermark_level = MXC_ESAI_FIFO_WML,
++ .per_address = ESAI_BASE_ADDR + MXC_ESAI_RX_REG,
++ .peripheral_type = ESAI,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_ESAI_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_ESAI_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_esai_16bit_tx_params = {
++ .chnl_params = {
++ .watermark_level = MXC_ESAI_FIFO_WML,
++ .per_address = ESAI_BASE_ADDR + MXC_ESAI_TX_REG,
++ .peripheral_type = ESAI,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_ESAI_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_16BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_ESAI_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_esai_24bit_rx_params = {
++ .chnl_params = {
++ .watermark_level = MXC_ESAI_FIFO_WML,
++ .per_address = ESAI_BASE_ADDR + MXC_ESAI_RX_REG,
++ .peripheral_type = ESAI,
++ .transfer_type = per_2_emi,
++ .event_id = DMA_REQ_ESAI_RX,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_ESAI_RX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static mxc_sdma_channel_params_t mxc_sdma_esai_24bit_tx_params = {
++ .chnl_params = {
++ .watermark_level = MXC_ESAI_FIFO_WML,
++ .per_address = ESAI_BASE_ADDR + MXC_ESAI_TX_REG,
++ .peripheral_type = ESAI,
++ .transfer_type = soc_trans_type,
++ .event_id = DMA_REQ_ESAI_TX,
++ .bd_number = 32,
++ .word_size = TRANSFER_32BIT,
++ },
++ .channel_num = MXC_DMA_CHANNEL_ESAI_TX,
++ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
++};
++
++static struct mxc_sdma_info_entry_s mxc_sdma_active_dma_info[] = {
++#if 0
++ { MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params, },
++ { MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params, },
++ { MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params, },
++ { MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params, },
++ { MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params, },
++ { MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params, },
++ { MXC_DMA_UART4_RX, &mxc_sdma_uart4_rx_params, },
++ { MXC_DMA_UART4_TX, &mxc_sdma_uart4_tx_params, },
++ { MXC_DMA_UART5_RX, &mxc_sdma_uart5_rx_params, },
++ { MXC_DMA_UART5_TX, &mxc_sdma_uart5_tx_params, },
++#endif
++ { MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params, },
++ { MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params, },
++ { MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params, },
++ { MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params, },
++ { MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params, },
++ { MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params, },
++ { MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params, },
++ { MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params, },
++ { MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params, },
++ { MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params, },
++ { MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params, },
++ { MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params, },
++ { MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params, },
++ { MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params, },
++ { MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params, },
++ { MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params, },
++ { MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params, },
++ { MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params, },
++ { MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params, },
++ { MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params, },
++ { MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params, },
++ { MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params, },
++ { MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params, },
++ { MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params, },
++ { MXC_DMA_ESAI_16BIT_RX, &mxc_sdma_esai_16bit_rx_params, },
++ { MXC_DMA_ESAI_16BIT_TX, &mxc_sdma_esai_16bit_tx_params, },
++ { MXC_DMA_ESAI_24BIT_RX, &mxc_sdma_esai_24bit_rx_params, },
++ { MXC_DMA_ESAI_24BIT_TX, &mxc_sdma_esai_24bit_tx_params, },
++ { MXC_DMA_MEMORY, &mxc_sdma_memory_params, },
++};
++
++/*
++ * This functions Returns the SDMA paramaters associated for a module
++ *
++ * channel_id: the ID of the module requesting DMA
++ * returns the sdma parameters structure for the device
++ */
++mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
++ channel_id)
++{
++ struct mxc_sdma_info_entry_s *p = mxc_sdma_active_dma_info;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(mxc_sdma_active_dma_info); i++, p++) {
++ if (p->device == channel_id)
++ return p->chnl_info;
++ }
++ return NULL;
++}
++EXPORT_SYMBOL(mxc_sdma_get_channel_params);
++
++/*
++ * This functions marks the SDMA channels that are statically allocated
++ *
++ * chnl: the channel array used to store channel information
++ */
++void mxc_get_static_channels(mxc_dma_channel_t *chnl)
++{
++#ifdef CONFIG_SDMA_IRAM
++ int i;
++ for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++)
++ chnl[i].dynamic = 0;
++#endif
++}
++EXPORT_SYMBOL(mxc_get_static_channels);
+diff -urN linux.35.old/arch/arm/mach-mx25/Kconfig linux.35.new/arch/arm/mach-mx25/Kconfig
+--- linux.35.old/arch/arm/mach-mx25/Kconfig 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/Kconfig 2010-12-03 09:51:55.351854203 +0100
+@@ -4,5 +4,57 @@
+
+ config MACH_MX25_3DS
+ bool "Support MX25PDK (3DS) Platform"
++ select IMX_HAVE_PLATFORM_IMX_UART
++ select IMX_HAVE_PLATFORM_MXC_NAND
++
++config MACH_VMX25
++ bool "Support Voipac VMX25 module"
++ select IMX_HAVE_PLATFORM_IMX_I2C
++ select IMX_HAVE_PLATFORM_IMX_UART
++ select IMX_HAVE_PLATFORM_MXC_NAND
++ select IMX_HAVE_PLATFORM_SPI_IMX
++ select IMX_HAVE_PLATFORM_FLEXCAN
++ depends on ARCH_MX25
++ help
++ Include support for Voipac VMX25 processor module
++
++choice
++ prompt "Baseboard"
++ depends on MACH_VMX25
++ default MACH_VMX_BASEBOARD
++
++config MACH_VMX_BASEBOARD
++ bool "Voipac development baseboard"
++ help
++ This adds board specific devices that can be found on Voipac's
++ development baseboard.
++
++endchoice
++
++choice
++ prompt "SD slot selection"
++ depends on MACH_VMX25
++ default VMX_SD_ON_BOARD if MACH_VMX_BASEBOARD
++
++config VMX_SD_ON_MODULE
++ bool "Use integrated SD slot"
++ depends on MACH_VMX25
++ help
++ Provide SD CLK signal to vmx25 on module SD slot.
++
++config VMX_SD_ON_BOARD
++ bool "Use external SD slot"
++ depends on MACH_VMX25
++ help
++ Provide SD CLK signal to vmx25 baseboard SD slot.
++
++endchoice
++
++config MXC_SDMA_API
++ bool "Use SDMA API"
++ default y
++ help
++ This selects the Freescale MXC SDMA API.
++ If unsure, say N.
+
+ endif
+diff -urN linux.35.old/arch/arm/mach-mx25/mach-mx25pdk.c linux.35.new/arch/arm/mach-mx25/mach-mx25pdk.c
+--- linux.35.old/arch/arm/mach-mx25/mach-mx25pdk.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/mach-mx25pdk.c 2010-12-03 09:51:55.351854203 +0100
+@@ -36,10 +36,12 @@
+ #include <mach/mx25.h>
+ #include <mach/mxc_nand.h>
+ #include <mach/imxfb.h>
+-#include "devices.h"
+ #include <mach/iomux-mx25.h>
+
+-static struct imxuart_platform_data uart_pdata = {
++#include "devices-imx25.h"
++#include "devices.h"
++
++static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+ };
+
+@@ -142,7 +144,7 @@
+ mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
+ ARRAY_SIZE(mx25pdk_pads));
+
+- mxc_register_device(&mxc_uart_device0, &uart_pdata);
++ imx25_add_imx_uart0(&uart_pdata);
+ mxc_register_device(&mxc_usbh2, NULL);
+ mxc_register_device(&mxc_nand_device, &mx25pdk_nand_board_info);
+ mxc_register_device(&mx25_rtc_device, NULL);
+diff -urN linux.35.old/arch/arm/mach-mx25/mach-vmx25.c linux.35.new/arch/arm/mach-mx25/mach-vmx25.c
+--- linux.35.old/arch/arm/mach-mx25/mach-vmx25.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/mach-mx25/mach-vmx25.c 2011-01-12 14:54:30.832513858 +0100
+@@ -0,0 +1,467 @@
++/*
++ * arch/arm/mach-mx25/mach-vmx25.c
++ *
++ * Copyright (C) 2010 Voipac <support@voipac.com>
++ *
++ * Based on arch/arm/mach-mx25/karo-tx25.c
++ * Copyright (C) 2009 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the:
++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
++ *
++ * This file adds support for the Voipac VMX25 processor modules
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/input.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/serial_8250.h>
++#include <linux/fec.h>
++#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
++#include <mtd/mtd-abi.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <asm/mach/flash.h>
++#endif
++
++#include <linux/serial.h>
++#include <linux/fsl_devices.h>
++#include <linux/irq.h>
++#include <linux/mmc/host.h>
++#include <linux/leds.h>
++#include <linux/if_ether.h>
++
++#include <asm/setup.h>
++#include <asm/irq.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/time.h>
++#include <mach/common.h>
++#include <mach/hardware.h>
++#include <mach/gpio.h>
++#include <mach/iomux-v1.h>
++#include <mach/iomux-v3.h>
++#include <mach/iomux-mx25.h>
++#include <mach/irqs.h>
++#include <mach/clock.h>
++#include <mach/imxfb.h>
++#include <mach/mmc.h>
++#include <mach/mxc_nand.h>
++#if defined(CONFIG_TOUCHSCREEN_MXC_TSC) || defined(CONFIG_TOUCHSCREEN_MXC_TSC_MODULE)
++#include <mach/mxc_tsc.h>
++#endif
++
++#include "devices.h"
++
++int vmx_mod_type = -1;
++
++static void vmx25_gpio_config(struct pad_desc *pd, int num)
++{
++ int i;
++
++ for (i = 0; i < num; i++) {
++ if (mxc_iomux_v3_setup_pad(&pd[i]) == 0) {
++ mxc_iomux_v3_release_pad(&pd[i]);
++ }
++ }
++}
++
++/* MTD NAND flash */
++#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE)
++static struct pad_desc vmx25_nand_pads[] = {
++ MX25_PAD_NF_CE0__NF_CE0,
++ MX25_PAD_NFWE_B__NFWE_B,
++ MX25_PAD_NFRE_B__NFRE_B,
++ MX25_PAD_NFALE__NFALE,
++ MX25_PAD_NFCLE__NFCLE,
++ MX25_PAD_NFWP_B__NFWP_B,
++ MX25_PAD_NFRB__NFRB,
++ MX25_PAD_D7__D7,
++ MX25_PAD_D6__D6,
++ MX25_PAD_D5__D5,
++ MX25_PAD_D4__D4,
++ MX25_PAD_D3__D3,
++ MX25_PAD_D2__D2,
++ MX25_PAD_D1__D1,
++ MX25_PAD_D0__D0,
++};
++
++static struct mtd_partition mxc_nand_partitions[] = {
++ {
++ .name = "nand.barebox",
++ .offset = 0,
++ .size = 256 * 1024},
++ {
++ .name = "nand.bareboxenv",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 128 * 1024},
++ {
++ .name = "nand.kernel",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 2688 * 1024},
++ {
++ .name = "nand.rootfs",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL},
++};
++
++static struct mxc_nand_platform_data vmx25_nand_pdata = {
++ .parts = mxc_nand_partitions,
++ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
++ .hw_ecc = 1,
++ .width = 1,
++ .flash_bbt = 1,
++};
++
++static int vmx25_nand_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "%s: Configuring NAND pins\n", __FUNCTION__);
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx25_nand_pads,
++ ARRAY_SIZE(vmx25_nand_pads));
++
++ return ret;
++}
++arch_initcall(vmx25_nand_init);
++#endif // CONFIG_MTD_NAND_MXC CONFIG_MTD_NAND_MXC_MODULE
++
++#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
++
++static struct fec_platform_data vmx25_fec_pdata = {
++ .phy = PHY_INTERFACE_MODE_RMII,
++};
++
++/*
++ * Setup GPIO for FEC device
++ *
++ */
++
++static struct pad_desc vmx25_fec_pwr_gpios[] = {
++ MX25_PAD_D11__GPIO_4_9, /* FEC PHY power on pin */
++ MX25_PAD_D13__GPIO_4_7, /* FEC reset */
++};
++
++#define VMX25_FEC_PWR_GPIO (GPIO_PORTD | 9)
++#define VMX25_FEC_RST_GPIO (GPIO_PORTD | 7)
++
++static struct pad_desc vmx25_fec_gpios[] = {
++ MX25_PAD_FEC_MDC__FEC_MDC,
++ MX25_PAD_FEC_MDIO__FEC_MDIO,
++ MX25_PAD_FEC_TDATA0__FEC_TDATA0,
++ MX25_PAD_FEC_TDATA1__FEC_TDATA1,
++ MX25_PAD_FEC_TX_EN__FEC_TX_EN,
++ MX25_PAD_FEC_RDATA0__FEC_RDATA0,
++ MX25_PAD_FEC_RDATA1__FEC_RDATA1,
++ MX25_PAD_FEC_RX_DV__FEC_RX_DV,
++ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
++};
++
++static int vmx25_fec_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "%s: Configuring FEC pins\n", __FUNCTION__);
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx25_fec_pwr_gpios,
++ ARRAY_SIZE(vmx25_fec_pwr_gpios));
++ if (ret) {
++ return ret;
++ }
++
++ gpio_request(VMX25_FEC_PWR_GPIO, "FEC PHY enable");
++ gpio_request(VMX25_FEC_RST_GPIO, "FEC PHY reset");
++
++
++ /* turn off PHY power and lift reset */
++ gpio_direction_output(VMX25_FEC_PWR_GPIO, 0); /* drop PHY power */
++ gpio_direction_output(VMX25_FEC_RST_GPIO, 0); /* assert reset */
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx25_fec_gpios,
++ ARRAY_SIZE(vmx25_fec_gpios));
++
++ udelay(100);
++
++ /* turn on PHY power and lift reset */
++ gpio_set_value(VMX25_FEC_PWR_GPIO, 1);
++ gpio_set_value(VMX25_FEC_RST_GPIO, 1);
++
++ return ret;
++}
++arch_initcall(vmx25_fec_init);
++
++#endif // CONFIG_FEC CONFIG_FEC_MODULE
++
++#if defined(CONFIG_TOUCHSCREEN_MXC_TSC) || defined(CONFIG_TOUCHSCREEN_MXC_TSC_MODULE)
++static struct mxc_tsc_pdata vmx25_tsc_pdata = {
++ .pen_debounce_time = 32,
++ .intref = 1,
++ .adc_clk = 1666667,
++ .tsc_mode = MXC_TSC_4WIRE,
++ .r_xplate = 660,
++ .hsyncen = 1,
++ .hsyncpol = 0,
++};
++#endif
++
++static struct platform_dev_list {
++ struct platform_device *pdev;
++ void *pdata;
++} vmx25_devices[] __initdata = {
++#if defined(CONFIG_IMX2_WDT) || defined(CONFIG_IMX2_WDT_MODULE)
++ { .pdev = &mxc_wdt, },
++#endif
++#if defined(CONFIG_RTC_DRV_IMXDI) || defined(CONFIG_RTC_DRV_IMXDI_MODULE)
++ { .pdev = &mx25_rtc_device, },
++#endif
++#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE)
++ { .pdev = &mxc_nand_device, &vmx25_nand_pdata},
++#endif
++#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
++ { .pdev = &mx25_fec_device, &vmx25_fec_pdata},
++#endif
++#if defined(CONFIG_IMX_ADC) || defined(CONFIG_IMX_ADC_MODULE)
++ { .pdev = &imx_adc_device, },
++#endif
++#if defined(CONFIG_TOUCHSCREEN_MXC_TSC) || defined(CONFIG_TOUCHSCREEN_MXC_TSC_MODULE)
++ { .pdev = &mx25_tsc_device, &vmx25_tsc_pdata, },
++#endif
++#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
++ { .pdev = &mxc_w1_master_device, },
++#endif
++};
++#define VMX25_NUM_DEVICES ARRAY_SIZE(vmx25_devices)
++
++static __init void vmx25_board_init(void)
++{
++ int i;
++
++ printk(KERN_INFO "%s: \n", __FUNCTION__);
++
++ for (i = 0; i < VMX25_NUM_DEVICES; i++) {
++ int ret;
++
++ if (vmx25_devices[i].pdev == NULL) continue;
++
++ printk(KERN_INFO "%s: Registering platform device[%d] @ %p dev %p: %s\n",
++ __FUNCTION__, i, vmx25_devices[i].pdev, &vmx25_devices[i].pdev->dev,
++ vmx25_devices[i].pdev->name);
++ if (vmx25_devices[i].pdata) {
++ ret = mxc_register_device(vmx25_devices[i].pdev,
++ vmx25_devices[i].pdata);
++ } else {
++ ret = platform_device_register(vmx25_devices[i].pdev);
++ }
++ if (ret) {
++ printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n",
++ __FUNCTION__, i, vmx25_devices[i].pdev->name, ret);
++ }
++ }
++#if defined(CONFIG_RTC_DRV_IMXDI) || defined(CONFIG_RTC_DRV_IMXDI_MODULE)
++ device_init_wakeup(&mx25_rtc_device.dev, 1);
++#endif
++
++ printk(KERN_INFO "%s: Done\n", __FUNCTION__);
++}
++
++static struct pad_desc vmx25_gpios[] __refdata = {
++ MX25_PAD_GPIO_A__GPIO_A,
++ MX25_PAD_GPIO_B__GPIO_B,
++ MX25_PAD_GPIO_C__GPIO_C,
++ MX25_PAD_GPIO_D__GPIO_D,
++ MX25_PAD_GPIO_E__GPIO_E,
++ MX25_PAD_GPIO_F__GPIO_F,
++ MX25_PAD_CSI_D7__GPIO_1_6,
++ MX25_PAD_CSI_D8__GPIO_1_7,
++ MX25_PAD_CSI_MCLK__GPIO_1_8,
++ MX25_PAD_CSI_VSYNC__GPIO_1_9,
++ MX25_PAD_CSI_HSYNC__GPIO_1_10,
++ MX25_PAD_CSI_PIXCLK__GPIO_1_11,
++ MX25_PAD_I2C1_CLK__GPIO_1_12,
++ MX25_PAD_I2C1_DAT__GPIO_1_13,
++ MX25_PAD_CSPI1_MOSI__GPIO_1_14,
++ MX25_PAD_CSPI1_MISO__GPIO_1_15,
++ MX25_PAD_CSPI1_SS0__GPIO_1_16,
++ MX25_PAD_CSPI1_SS1__GPIO_1_17,
++ MX25_PAD_CSPI1_SCLK__GPIO_1_18,
++ MX25_PAD_LD5__GPIO_1_19,
++ MX25_PAD_LD6__GPIO_1_20,
++ MX25_PAD_LD7__GPIO_1_21,
++ MX25_PAD_HSYNC__GPIO_1_22,
++ MX25_PAD_VSYNC__GPIO_1_23,
++ MX25_PAD_LSCLK__GPIO_1_24,
++ MX25_PAD_OE_ACD__GPIO_1_25,
++ MX25_PAD_PWM__GPIO_1_26,
++ MX25_PAD_CSI_D2__GPIO_1_27,
++ MX25_PAD_CSI_D3__GPIO_1_28,
++ MX25_PAD_CSI_D4__GPIO_1_29,
++ MX25_PAD_CSI_D5__GPIO_1_30,
++ MX25_PAD_CSI_D6__GPIO_1_31,
++
++ MX25_PAD_A14__GPIO_2_0,
++ MX25_PAD_A15__GPIO_2_1,
++ MX25_PAD_A16__GPIO_2_2,
++ MX25_PAD_A17__GPIO_2_3,
++ MX25_PAD_A18__GPIO_2_4,
++ MX25_PAD_A19__GPIO_2_5,
++ MX25_PAD_A20__GPIO_2_6,
++ MX25_PAD_A21__GPIO_2_7,
++ MX25_PAD_A22__GPIO_2_8,
++ MX25_PAD_A23__GPIO_2_9,
++ MX25_PAD_A24__GPIO_2_10,
++ MX25_PAD_A25__GPIO_2_11,
++ MX25_PAD_EB0__GPIO_2_12,
++ MX25_PAD_EB1__GPIO_2_13,
++ MX25_PAD_OE__GPIO_2_14,
++ MX25_PAD_LD0__GPIO_2_15,
++ MX25_PAD_LD1__GPIO_2_16,
++ MX25_PAD_LD2__GPIO_2_17,
++ MX25_PAD_LD3__GPIO_2_18,
++ MX25_PAD_LD4__GPIO_2_19,
++ MX25_PAD_DE_B__GPIO_2_20,
++ MX25_PAD_CLKO__GPIO_2_21,
++ MX25_PAD_CSPI1_RDY__GPIO_2_22,
++ MX25_PAD_SD1_CMD__GPIO_2_23,
++ MX25_PAD_SD1_CLK__GPIO_2_24,
++ MX25_PAD_SD1_DATA0__GPIO_2_25,
++ MX25_PAD_SD1_DATA1__GPIO_2_26,
++ MX25_PAD_SD1_DATA2__GPIO_2_27,
++ MX25_PAD_SD1_DATA3__GPIO_2_28,
++// MX25_PAD_KPP_ROW0__GPIO_2_29,
++// MX25_PAD_KPP_ROW1__GPIO_2_30,
++// MX25_PAD_KPP_ROW2__GPIO_2_31,
++// MX25_PAD_KPP_ROW3__GPIO_3_0,
++// MX25_PAD_KPP_COL0__GPIO_3_1,
++// MX25_PAD_KPP_COL1__GPIO_3_2,
++// MX25_PAD_KPP_COL2__GPIO_3_3,
++// MX25_PAD_KPP_COL3__GPIO_3_4,
++ MX25_PAD_FEC_MDC__GPIO_3_5,
++ MX25_PAD_FEC_MDIO__GPIO_3_6,
++ MX25_PAD_FEC_TDATA0__GPIO_3_7,
++ MX25_PAD_FEC_TDATA1__GPIO_3_8,
++ MX25_PAD_FEC_TX_EN__GPIO_3_9,
++ MX25_PAD_FEC_RDATA0__GPIO_3_10,
++ MX25_PAD_FEC_RDATA1__GPIO_3_11,
++ MX25_PAD_FEC_RX_DV__GPIO_3_12,
++ MX25_PAD_FEC_TX_CLK__GPIO_3_13,
++#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
++ MX25_PAD_RTCK__OWIRE,
++#else
++ MX25_PAD_RTCK__GPIO_3_14,
++#endif
++ MX25_PAD_EXT_ARMCLK__GPIO_3_15,
++ MX25_PAD_UPLL_BYPCLK__GPIO_3_16,
++ MX25_PAD_VSTBY_REQ__GPIO_3_17,
++ MX25_PAD_VSTBY_ACK__GPIO_3_18,
++ MX25_PAD_POWER_FAIL__GPIO_3_19,
++ MX25_PAD_CS4__GPIO_3_20,
++ MX25_PAD_CS5__GPIO_3_21,
++#if 0 /* do not mess with these */
++ MX25_PAD_NF_CE0__GPIO_3_22,
++#endif
++ MX25_PAD_ECB__GPIO_3_23,
++ MX25_PAD_LBA__GPIO_3_24,
++ MX25_PAD_RW__GPIO_3_25,
++#if 0 /* do not mess with these */
++ MX25_PAD_NFWE_B__GPIO_3_26,
++ MX25_PAD_NFRE_B__GPIO_3_27,
++ MX25_PAD_NFALE__GPIO_3_28,
++ MX25_PAD_NFCLE__GPIO_3_29,
++ MX25_PAD_NFWP_B__GPIO_3_30,
++ MX25_PAD_NFRB__GPIO_3_31,
++#endif
++ MX25_PAD_A10__GPIO_4_0,
++ MX25_PAD_A13__GPIO_4_1,
++ MX25_PAD_CS0__GPIO_4_2,
++ MX25_PAD_CS1__GPIO_4_3,
++ MX25_PAD_BCLK__GPIO_4_4,
++ MX25_PAD_D15__GPIO_4_5,
++ MX25_PAD_D14__GPIO_4_6,
++ MX25_PAD_D13__GPIO_4_7,
++ MX25_PAD_D12__GPIO_4_8,
++ MX25_PAD_D11__GPIO_4_9,
++ MX25_PAD_D10__GPIO_4_10,
++ MX25_PAD_D9__GPIO_4_11,
++ MX25_PAD_D8__GPIO_4_12,
++#if 0 /* do not mess with these */
++ MX25_PAD_D7__GPIO_4_13,
++ MX25_PAD_D6__GPIO_4_14,
++ MX25_PAD_D5__GPIO_4_15,
++ MX25_PAD_D4__GPIO_4_16,
++ MX25_PAD_D3__GPIO_4_17,
++ MX25_PAD_D2__GPIO_4_18,
++ MX25_PAD_D1__GPIO_4_19,
++ MX25_PAD_D0__GPIO_4_20,
++#endif
++ MX25_PAD_CSI_D9__GPIO_4_21,
++ MX25_PAD_UART1_RXD__GPIO_4_22,
++ MX25_PAD_UART1_TXD__GPIO_4_23,
++ MX25_PAD_UART1_RTS__GPIO_4_24,
++ MX25_PAD_UART1_CTS__GPIO_4_25,
++ MX25_PAD_UART2_RXD__GPIO_4_26,
++ MX25_PAD_UART2_TXD__GPIO_4_27,
++ MX25_PAD_UART2_RTS__GPIO_4_28,
++ MX25_PAD_UART2_CTS__GPIO_4_29,
++ MX25_PAD_BOOT_MODE0__GPIO_4_30,
++ MX25_PAD_BOOT_MODE1__GPIO_4_31,
++};
++
++static int __init vmx25_setup_gpios(void)
++{
++ vmx25_gpio_config(vmx25_gpios, ARRAY_SIZE(vmx25_gpios));
++ return 0;
++}
++late_initcall(vmx25_setup_gpios);
++
++static void __init vmx25_fixup(struct machine_desc *desc, struct tag *tags,
++ char **cmdline, struct meminfo *mi)
++{
++}
++
++static void __init vmx25_timer_init(void)
++{
++ mx25_clocks_init();
++}
++
++static struct sys_timer vmx25_timer = {
++ .init = vmx25_timer_init,
++};
++
++static int __init vmx_mod_type_setup(char *line)
++{
++ get_option(&line, &vmx_mod_type);
++ printk(KERN_INFO "%s: Module type set to 0x%02x by kernel cmd line\n",
++ __FUNCTION__, vmx_mod_type);
++ return 1;
++}
++__setup("module_type=", vmx_mod_type_setup);
++
++MACHINE_START(VMX25, "Voipac VMX25 module (Freescale i.MX25)")
++ /* Maintainer: <support@voipac.com> */
++ .phys_io = MX25_AIPS1_BASE_ADDR,
++ .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
++ .fixup = vmx25_fixup,
++ .boot_params = MX25_PHYS_OFFSET + 0x100,
++ .map_io = mx25_map_io,
++ .init_irq = mx25_init_irq,
++ .init_machine = vmx25_board_init,
++ .timer = &vmx25_timer,
++MACHINE_END
++
+diff -urN linux.35.old/arch/arm/mach-mx25/Makefile linux.35.new/arch/arm/mach-mx25/Makefile
+--- linux.35.old/arch/arm/mach-mx25/Makefile 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/Makefile 2010-12-03 09:51:55.351854203 +0100
+@@ -1,3 +1,7 @@
+ obj-y := mm.o devices.o
+ obj-$(CONFIG_ARCH_MX25) += clock.o
+ obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25pdk.o
++obj-$(CONFIG_MACH_VMX25) += mach-vmx25.o
++obj-$(CONFIG_MACH_VMX_BASEBOARD) += vmx-baseboard.o
++
++obj-$(CONFIG_MXC_SDMA_API) += dma.o
+\ No newline at end of file
+diff -urN linux.35.old/arch/arm/mach-mx25/mm.c linux.35.new/arch/arm/mach-mx25/mm.c
+--- linux.35.old/arch/arm/mach-mx25/mm.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/mach-mx25/mm.c 2010-12-03 09:51:55.356349597 +0100
+@@ -14,10 +14,6 @@
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ #include <linux/mm.h>
+diff -urN linux.35.old/arch/arm/mach-mx25/sdma_script_code.h linux.35.new/arch/arm/mach-mx25/sdma_script_code.h
+--- linux.35.old/arch/arm/mach-mx25/sdma_script_code.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/mach-mx25/sdma_script_code.h 2010-12-03 09:51:55.356349597 +0100
+@@ -0,0 +1,159 @@
++
++/*
++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++/*!
++ * @file sdma_script_code.h
++ * @brief This file contains functions of SDMA scripts code initialization
++ *
++ * The file was generated automatically. Based on sdma scripts library.
++ *
++ * @ingroup SDMA
++ */
++/************************************************************************
++
++ SDMA RELEASE LABEL: "SS15_SENNA"
++
++************************************************************************/
++
++#ifndef SDMA_SCRIPT_CODE_H
++#define SDMA_SCRIPT_CODE_H
++
++/*!
++ * SDMA ROM scripts start addresses and sizes
++ */
++#define start_ADDR 0
++#define start_SIZE 22
++
++#define core_ADDR 80
++#define core_SIZE 233
++
++#define common_ADDR 313
++#define common_SIZE 416
++
++#define ap_2_ap_ADDR 729
++#define ap_2_ap_SIZE 41
++
++#define app_2_mcu_ADDR 770
++#define app_2_mcu_SIZE 64
++
++#define mcu_2_app_ADDR 834
++#define mcu_2_app_SIZE 70
++
++#define uart_2_mcu_ADDR 904
++#define uart_2_mcu_SIZE 75
++
++#define shp_2_mcu_ADDR 979
++#define shp_2_mcu_SIZE 69
++
++#define mcu_2_shp_ADDR 1048
++#define mcu_2_shp_SIZE 72
++
++#define uartsh_2_mcu_ADDR 1120
++#define uartsh_2_mcu_SIZE 69
++
++#define app_2_per_ADDR 1189
++#define app_2_per_SIZE 66
++
++#define per_2_app_ADDR 1255
++#define per_2_app_SIZE 74
++
++#define per_2_shp_ADDR 1329
++#define per_2_shp_SIZE 78
++
++#define shp_2_per_ADDR 1407
++#define shp_2_per_SIZE 72
++
++#define mcu_2_ata_ADDR 1479
++#define mcu_2_ata_SIZE 81
++
++#define ata_2_mcu_ADDR 1560
++#define ata_2_mcu_SIZE 96
++
++#define loop_DMAs_routines_ADDR 1656
++#define loop_DMAs_routines_SIZE 227
++
++#define test_ADDR 1883
++#define test_SIZE 63
++
++#define signature_ADDR 1022
++#define signature_SIZE 1
++
++/*!
++ * SDMA RAM scripts start addresses and sizes
++ */
++#define ext_mem__ipu_ram_ADDR 6144
++#define ext_mem__ipu_ram_SIZE 123
++
++#define uart_2_per_ADDR 6267
++#define uart_2_per_SIZE 73
++
++#define uartsh_2_per_ADDR 6340
++#define uartsh_2_per_SIZE 67
++
++/*!
++ * SDMA RAM image start address and size
++ */
++#define RAM_CODE_START_ADDR 6144
++#define RAM_CODE_SIZE ARRAY_SIZE(sdma_code)
++
++/*!
++ * Buffer that holds the SDMA RAM image
++ */
++__attribute__ ((__aligned__(4)))
++#ifndef CONFIG_XIP_KERNEL
++const
++#endif
++static const short sdma_code[] = {
++ 0x0e70, 0x0611, 0x5616, 0xc18a, 0x7d2a, 0x5ade, 0x008e, 0xc19c,
++ 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff,
++ 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5,
++ 0xd84f, 0x982b, 0x6b05, 0xc6d8, 0x7e27, 0x7f29, 0x982b, 0x6d01,
++ 0x03df, 0x7d05, 0x6bd5, 0xc702, 0x7e18, 0x7f1a, 0x982b, 0x6b05,
++ 0xc678, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc1a8, 0x7dd7, 0x0200,
++ 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc2ad,
++ 0x048b, 0x0498, 0x0454, 0x068a, 0x982b, 0x0207, 0x680c, 0x6ddf,
++ 0x0107, 0x68ff, 0x60d0, 0x9834, 0x0207, 0x68ff, 0x6d28, 0x0107,
++ 0x6004, 0x680c, 0x9834, 0x0007, 0x68ff, 0x60d0, 0x9834, 0x0288,
++ 0x03a5, 0x3b03, 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da,
++ 0x7d1a, 0x02a0, 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804,
++ 0x02d0, 0x7d11, 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf,
++ 0x0015, 0x0015, 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb,
++ 0x3a03, 0x6dcd, 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3,
++ 0x65ff, 0x7ed1, 0x0006, 0xc23a, 0x57db, 0x52f3, 0x6ad5, 0x56fb,
++ 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1e, 0x1e94, 0x6ee3,
++ 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3, 0x6ac8, 0x2694, 0x52eb,
++ 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27, 0x6ac8, 0x7f23, 0x2501,
++ 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3, 0x0260,
++ 0x7df1, 0x62d0, 0xc2d1, 0x98c0, 0x6ee3, 0x008f, 0x2001, 0x00d5,
++ 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a,
++ 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d09, 0xc251,
++ 0x57db, 0x987f, 0x0007, 0x6aff, 0x62d0, 0xc2d1, 0x0458, 0x0454,
++ 0x6add, 0x7ff8, 0xc261, 0x987c, 0xc230, 0xc23a, 0x57db, 0x52f3,
++ 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d17, 0x1e94,
++ 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d26, 0x6ac8,
++ 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e, 0x1a98, 0x5202, 0x0260,
++ 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc2d1, 0x9903, 0x008f, 0x2001,
++ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d0e, 0x6ac8,
++ 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d0b,
++ 0xc251, 0x57db, 0x98c9, 0x0007, 0x6aff, 0x6add, 0x7ffc, 0x62d0,
++ 0xc2d1, 0x0458, 0x0454, 0x6add, 0x7ff6, 0xc261, 0x98c6,
++};
++#endif
+diff -urN linux.35.old/arch/arm/mach-mx25/vmx-baseboard.c linux.35.new/arch/arm/mach-mx25/vmx-baseboard.c
+--- linux.35.old/arch/arm/mach-mx25/vmx-baseboard.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/mach-mx25/vmx-baseboard.c 2011-01-12 14:24:20.076493613 +0100
+@@ -0,0 +1,1559 @@
++/*
++ * arch/arm/mach-mx25/vmx-baseboard.c
++ *
++ * Copyright (C) 2010 Voipac <support@voipac.com>
++ *
++ * Based on arch/arm/mach-mx25/stk5-baseboard.c
++ * Copyright (C) 2009 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the:
++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
++ *
++ * This file adds support for devices found on Voipac baseboard
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/input.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/serial.h>
++#include <linux/fsl_devices.h>
++#include <linux/irq.h>
++#include <linux/mmc/host.h>
++#include <linux/leds.h>
++#include <linux/dma-mapping.h>
++#include <linux/pwm_backlight.h>
++#include <linux/i2c.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/eeprom.h>
++#include <linux/spi/ads7846.h>
++#include <linux/can/platform/mcp251x.h>
++
++#include <asm/setup.h>
++#include <asm/irq.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/time.h>
++
++#include <mach/common.h>
++#include <mach/hardware.h>
++#include <mach/gpio.h>
++#include <mach/iomux.h>
++#include <mach/iomux-v1.h>
++#include <mach/iomux-mx25.h>
++#include <mach/irqs.h>
++#include <mach/clock.h>
++#include <mach/imxfb.h>
++#include <mach/mmc.h>
++#include <mach/mxc_ehci.h>
++#include <mach/board-vmx25.h>
++#include <mach/sdhci.h>
++#include <mach/i2c.h>
++
++#include <linux/input/matrix_keypad.h>
++
++#include <mach/ssi.h>
++#include <mach/audmux.h>
++
++#include "devices.h"
++#include "devices-imx25.h"
++
++/*
++ * 1.uart
++ * 2.usb
++ * 3.i2c
++ * 5.flexcan
++ * 6.spican
++ * 4.spi
++ * 7.keypad
++ * 8.leds
++ * 9.audio
++ * 10.radio
++ */
++
++#define UART1_ENABLED 1
++#define UART2_ENABLED 1
++#define UART3_ENABLED 0 /* conflicts with SPI */
++#define UART4_ENABLED 0 /* conflicts with SSI */
++#define UART5_ENABLED 1
++
++//#define USE_SPI_GPIO_B5_CS 1 /* spi flash not work with intergrated cs */ - conflict with LCD
++
++#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
++static struct pad_desc vmx_uart_pads[][4] = {
++ {
++ MX25_PAD_UART1_TXD__UART1_TXD,
++ MX25_PAD_UART1_RXD__UART1_RXD,
++ MX25_PAD_UART1_CTS__UART1_CTS,
++ MX25_PAD_UART1_RTS__UART1_RTS,
++ },
++ {
++ MX25_PAD_UART2_TXD__UART2_TXD,
++ MX25_PAD_UART2_RXD__UART2_RXD,
++ MX25_PAD_UART2_CTS__UART2_CTS,
++ MX25_PAD_UART2_RTS__UART2_RTS,
++ },
++ {
++ /* UART 3 not useable on VMX25 */
++ },
++ {
++ /* UART 4 not useable on VMX25 */
++ },
++ {
++ MX25_PAD_ECB__UART5_TXD_MUX,
++ MX25_PAD_LBA__UART5_RXD_MUX,
++ MX25_PAD_CS4__UART5_CTS,
++ MX25_PAD_CS5__UART5_RTS,
++ },
++};
++
++static int vmx_uart_init(struct platform_device *pdev)
++{
++ if (pdev->id >= ARRAY_SIZE(vmx_uart_pads)) {
++ return -ENODEV;
++ }
++ return mxc_iomux_v3_setup_multiple_pads(vmx_uart_pads[pdev->id],
++ ARRAY_SIZE(vmx_uart_pads[pdev->id]));
++}
++
++static void vmx_uart_exit(struct platform_device *pdev)
++{
++ BUG_ON(pdev->id >= ARRAY_SIZE(vmx_uart_pads));
++ mxc_iomux_v3_release_multiple_pads(vmx_uart_pads[pdev->id],
++ ARRAY_SIZE(vmx_uart_pads[pdev->id]));
++}
++
++static const struct imxuart_platform_data vmx_uart_pdata[] __initconst = {
++ {
++ .init = vmx_uart_init,
++ .exit = vmx_uart_exit,
++ .flags = IMXUART_HAVE_RTSCTS,
++ }, {
++ .init = vmx_uart_init,
++ .exit = vmx_uart_exit,
++ .flags = IMXUART_HAVE_RTSCTS,
++ }, {
++ .init = vmx_uart_init,
++ .exit = vmx_uart_exit,
++ .flags = IMXUART_HAVE_RTSCTS,
++ }, {
++ .init = vmx_uart_init,
++ .exit = vmx_uart_exit,
++ .flags = IMXUART_HAVE_RTSCTS,
++ }, {
++ .init = vmx_uart_init,
++ .exit = vmx_uart_exit,
++ .flags = IMXUART_HAVE_RTSCTS,
++ }, {
++
++ },
++};
++#endif // CONFIG_SERIAL_IMX
++
++#if defined(CONFIG_USB_EHCI_MXC) || defined(CONFIG_USB_EHCI_MXC_MODULE) || \
++ defined(CONFIG_USB_FSL_USB2) || defined(CONFIG_USB_FSL_USB2_MODULE)
++/*
++ * The USB power switch (MAX893L) used on the STK5 base board
++ * produces a pulse (~100us) on the OC output whenever
++ * the ON input is activated. This disturbs the USB controller.
++ * As a workaround don't use USB power switching.
++ * If you have a hardware that works cleanly you may
++ * #define USE_USB_PWR to enable port power control for
++ * the EHCI controller.
++ */
++static struct pad_desc vmx_usbh2_pads[] = {
++#ifdef USE_USB_PWR
++ MX25_PAD_D9__USBH2_PWR,
++ MX25_PAD_D8__USBH2_OC,
++#else
++ MX25_PAD_D9__GPIO_4_11,
++ MX25_PAD_D8__GPIO_4_12,
++#endif
++};
++
++static int vmx_usbh2_init(struct platform_device *pdev)
++{
++ int ret;
++#ifndef USE_USB_PWR
++ const int pwr_gpio = 3 * 32 + 11;
++#endif
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_usbh2_pads,
++ ARRAY_SIZE(vmx_usbh2_pads));
++#ifdef USE_USB_PWR
++ if (ret) {
++ return ret;
++ }
++#else
++ ret = gpio_request(pwr_gpio, "USBH2_PWR");
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ pwr_gpio);
++ mxc_iomux_v3_release_multiple_pads(vmx_usbh2_pads,
++ ARRAY_SIZE(vmx_usbh2_pads));
++ return ret;
++ }
++
++ gpio_direction_output(pwr_gpio, 1);
++#endif
++ if (ret != 0) {
++ mxc_iomux_v3_release_multiple_pads(vmx_usbh2_pads,
++ ARRAY_SIZE(vmx_usbh2_pads));
++ goto exit;
++ }
++
++exit:
++#ifndef USE_USB_PWR
++ gpio_free(pwr_gpio);
++#endif
++ return ret;
++}
++
++static int vmx_usbh2_exit(struct platform_device *pdev)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx_usbh2_pads,
++ ARRAY_SIZE(vmx_usbh2_pads));
++ return 0;
++}
++
++static struct pad_desc vmx_usbotg_pads[] = {
++#ifdef USE_USB_PWR
++ MX25_PAD_GPIO_A__USBOTG_PWR,
++ MX25_PAD_GPIO_B__USBOTG_OC,
++#else
++ MX25_PAD_GPIO_A__GPIO_A,
++ MX25_PAD_GPIO_B__GPIO_B,
++#endif
++};
++
++static int vmx_usbotg_init(struct platform_device *pdev)
++{
++ int ret;
++#ifndef USE_USB_PWR
++ const int pwr_gpio = 0 * 32 + 0;
++#endif
++ printk(KERN_INFO "%s: \n", __FUNCTION__);
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_usbotg_pads,
++ ARRAY_SIZE(vmx_usbotg_pads));
++#ifdef USE_USB_PWR
++ if (ret) {
++ return ret;
++ }
++#else
++
++ ret = gpio_request(pwr_gpio, "USBOTG_PWR");
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ pwr_gpio);
++ mxc_iomux_v3_release_multiple_pads(vmx_usbh2_pads,
++ ARRAY_SIZE(vmx_usbh2_pads));
++ return ret;
++ }
++
++ gpio_direction_output(pwr_gpio, 1);
++#endif
++ if (ret != 0) {
++ mxc_iomux_v3_release_multiple_pads(vmx_usbotg_pads,
++ ARRAY_SIZE(vmx_usbotg_pads));
++ goto exit;
++ }
++
++exit:
++#ifndef USE_USB_PWR
++ gpio_free(pwr_gpio);
++#endif
++
++ return ret;
++}
++
++static int vmx_usbotg_exit(struct platform_device *pdev)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx_usbotg_pads,
++ ARRAY_SIZE(vmx_usbotg_pads));
++ return 0;
++}
++#endif // CONFIG_USB_EHCI_MXC || CONFIG_USB_FSL_USB2
++
++static int otg_mode_host = 1;
++
++static int __init vmx_otg_mode(char *options)
++{
++ if (!strcmp(options, "host"))
++ otg_mode_host = 1;
++ else if (!strcmp(options, "device"))
++ otg_mode_host = 0;
++ else
++ pr_info("otg_mode neither \"host\" nor \"device\". "
++ "Defaulting to host\n");
++ return 0;
++}
++__setup("otg_mode=", vmx_otg_mode);
++
++#if defined(CONFIG_USB_EHCI_MXC) || defined(CONFIG_USB_EHCI_MXC_MODULE)
++static struct mxc_usbh_platform_data vmx_usbotg_pdata = {
++ .init = vmx_usbotg_init,
++ .exit = vmx_usbotg_exit,
++ .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_UTMI_16BIT,
++ .flags = MXC_EHCI_INTERFACE_DIFF_UNI /* Differential/unidirectional (6-wire) */
++// MXC_EHCI_INTERNAL_PHY /* USB transceiver enable */ | \
++// MXC_EHCI_POWER_PINS_ENABLED /* assertion of the OC input is reported to the OTG core */
++};
++
++static struct mxc_usbh_platform_data vmx_usbh2_pdata = {
++ .init = vmx_usbh2_init,
++ .exit = vmx_usbh2_exit,
++ .portsc = MXC_EHCI_MODE_SERIAL,
++ .flags = MXC_EHCI_INTERFACE_SINGLE_UNI /* Single-ended/unidirectional (6-wire) */ | \
++ MXC_EHCI_INTERNAL_PHY /* USB transceiver enable */ | \
++ MXC_EHCI_IPPUE_DOWN /* Software has control over ipp_pue_pulldwn_dpdm */
++// MXC_EHCI_POWER_PINS_ENABLED /* the assertion of the OC input is reported to the host core */
++
++};
++#endif // CONFIG_USB_EHCI_MXC
++
++#if defined(CONFIG_USB_FSL_USB2) || defined(CONFIG_USB_FSL_USB2_MODULE)
++static struct fsl_usb2_platform_data vmx_usb_pdata = {
++ .operating_mode = FSL_USB2_DR_DEVICE,
++ .phy_mode = FSL_USB2_PHY_UTMI,
++};
++#endif // CONFIG_USB_FSL_USB2
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++#include <linux/i2c/at24.h>
++#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
++static struct pad_desc mxc_i2c1_pads[] = {
++ MX25_PAD_I2C1_CLK__I2C1_CLK,
++ MX25_PAD_I2C1_DAT__I2C1_DAT,
++};
++#elif defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++static struct pad_desc mxc_i2c1_pads[] = {
++ MX25_PAD_I2C1_CLK__GPIO_1_12,
++ MX25_PAD_I2C1_DAT__GPIO_1_13,
++};
++#else
++#error No suitable I2C bus driver configured
++#endif
++
++static int vmx_i2c1_init(struct device *dev)
++{
++ return mxc_iomux_v3_setup_multiple_pads(mxc_i2c1_pads,
++ ARRAY_SIZE(mxc_i2c1_pads));
++}
++
++static void vmx_i2c1_exit(struct device *dev)
++{
++ mxc_iomux_v3_release_multiple_pads(mxc_i2c1_pads,
++ ARRAY_SIZE(mxc_i2c1_pads));
++}
++
++static struct imxi2c_platform_data vmx_i2c1_data = {
++ .init = vmx_i2c1_init,
++ .exit = vmx_i2c1_exit,
++ .bitrate = 100000,
++};
++
++static struct at24_platform_data vmx_eeprom = {
++ .byte_len = SZ_512K / 8,
++ .page_size = 128,
++ .flags = AT24_FLAG_ADDR16,
++};
++
++#define RADIO_SI4705_IRQ (GPIO_PORTC | 16)
++
++static struct i2c_board_info vmx_i2c1_boardinfo[] __initdata = {
++ {
++ I2C_BOARD_INFO("sgtl5000-i2c", 0x0a),
++ },
++ {
++ I2C_BOARD_INFO("radio-si4705", 0x63),
++ .irq = gpio_to_irq(RADIO_SI4705_IRQ),
++ },
++ {
++ I2C_BOARD_INFO("24c512", 0x56),
++ .platform_data = &vmx_eeprom,
++ },
++ {
++ I2C_BOARD_INFO("rtc-ds1307", 0x68),
++ .type = "ds1339",
++ },
++};
++#endif /* CONFIG_I2C */
++
++#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
++static struct pad_desc vmx_can2_pads[] = {
++ MX25_PAD_GPIO_C__CAN2_TX,
++ MX25_PAD_GPIO_D__CAN2_RX,
++};
++
++static int vmx_can2_init(struct device *dev)
++{
++ return mxc_iomux_v3_setup_multiple_pads(vmx_can2_pads,
++ ARRAY_SIZE(vmx_can2_pads));
++}
++
++static void vmx_can2_exit(struct device *dev)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx_can2_pads,
++ ARRAY_SIZE(vmx_can2_pads));
++}
++#endif // CONFIG_CAN_FLEXCAN
++
++#if defined(CONFIG_CAN_MCP251X) || defined(CONFIG_CAN_MCP251X_MODULE)
++#define CAN_MCP251X_IRQ (GPIO_PORTB | 6)
++//#define CAN_MCP251X_RESET TODO
++
++static struct pad_desc vmx_can_mcp251x_pads[] = {
++ MX25_PAD_A20__GPIO_2_6,
++};
++
++int mcp251x_setup(struct spi_device *spi)
++{
++ int ret;
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_can_mcp251x_pads,
++ ARRAY_SIZE(vmx_can_mcp251x_pads));
++ if (ret)
++ return ret;
++
++ ret = gpio_request(CAN_MCP251X_IRQ, "MCP251X CS");
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ CAN_MCP251X_IRQ);
++ mxc_iomux_v3_release_multiple_pads(vmx_can_mcp251x_pads,
++ ARRAY_SIZE(vmx_can_mcp251x_pads));
++ return ret;
++ }
++
++ gpio_direction_input(CAN_MCP251X_IRQ);
++ gpio_free(CAN_MCP251X_IRQ);
++
++ return ret;
++}
++
++static struct mcp251x_platform_data mcp251x_info = {
++ .oscillator_frequency = 16000000,
++ .model = CAN_MCP251X_MCP2515,
++ .board_specific_setup = &mcp251x_setup,
++ .power_enable = NULL,
++ .transceiver_enable = NULL,
++};
++#endif // CONFIG_CAN_MCP251X
++
++#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
++#define TSC2046_PENDOWN (GPIO_PORTB | 7)
++
++static struct pad_desc vmx_touch_tsc2046_pads[] = {
++ MX25_PAD_A21__GPIO_2_7,
++};
++
++int tsc2046_setup(void)
++{
++ int ret;
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_touch_tsc2046_pads,
++ ARRAY_SIZE(vmx_touch_tsc2046_pads));
++ if (ret)
++ return ret;
++
++ ret = gpio_request(TSC2046_PENDOWN, "TSC2046 pendown");
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ TSC2046_PENDOWN);
++ mxc_iomux_v3_release_multiple_pads(vmx_touch_tsc2046_pads,
++ ARRAY_SIZE(vmx_touch_tsc2046_pads));
++ return ret;
++ }
++
++ gpio_direction_input(TSC2046_PENDOWN);
++
++ return ret;
++}
++
++static int ads7846_get_pendown_state(void)
++{
++ return !gpio_get_value(TSC2046_PENDOWN);
++}
++
++static struct ads7846_platform_data ads7846_config __initdata = {
++ .get_pendown_state = ads7846_get_pendown_state,
++ .keep_vref_on = 1,
++ .x_min = 270,
++ .y_min = 650,
++ .x_max = 3915,
++ .y_max = 3660,
++ .swap_xy = 1,
++};
++#endif // CONFIG_TOUCHSCREEN_ADS7846
++
++#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
++#define VMX_SPI_FLASH_CS_GPIO (GPIO_PORTB | 5)
++#define VMX_SPI_CAN_CS_GPIO (GPIO_PORTB | 10)
++#define VMX_SPI_TOUCH_CS_GPIO (GPIO_PORTB | 11)
++static struct pad_desc vmx_cspi1_pads[] = {
++ MX25_PAD_CSPI1_MOSI__CSPI1_MOSI,
++ MX25_PAD_CSPI1_MISO__CSPI1_MISO,
++ MX25_PAD_CSPI1_SS0__CSPI1_SS0,
++ MX25_PAD_CSPI1_SS1__CSPI1_SS1,
++ MX25_PAD_CSPI1_SCLK__CSPI1_SCLK,
++ MX25_PAD_CSPI1_RDY__CSPI1_RDY,
++#if defined(USE_SPI_GPIO_B5_CS)
++ MX25_PAD_A19__GPIO_2_5,
++#endif // USE_SPI_GPIO_B5_CS
++#if defined(CONFIG_CAN_MCP251X) || defined(CONFIG_CAN_MCP251X_MODULE)
++ MX25_PAD_A24__GPIO_2_10,
++#endif // CONFIG_CAN_MCP251X
++#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
++ MX25_PAD_A25__GPIO_2_11,
++#endif // CONFIG_TOUCHSCREEN_ADS7846
++};
++
++static int vmx_spi_chipselect[] = {
++#if defined(USE_SPI_GPIO_B5_CS)
++ VMX_SPI_FLASH_CS_GPIO,
++#else
++ MXC_SPI_CS(0),
++#endif // USE_SPI_GPIO_B5_CS
++ MXC_SPI_CS(1),
++ VMX_SPI_CAN_CS_GPIO,
++ VMX_SPI_TOUCH_CS_GPIO,
++};
++
++static int vmx_cspi1_init(struct device *dev)
++{
++ int ret;
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_cspi1_pads,
++ ARRAY_SIZE(vmx_cspi1_pads));
++
++ if (ret)
++ return ret;
++
++#if defined(USE_SPI_GPIO_B5_CS)
++ ret = gpio_request(VMX_SPI_FLASH_CS_GPIO, "SPI FLASH CS");
++
++ if (ret == 0) {
++ gpio_direction_output(VMX_SPI_FLASH_CS_GPIO, 1);
++ /* Free the CS GPIO, to allow SPI driver to register it again */
++ gpio_free(VMX_SPI_FLASH_CS_GPIO);
++ } else {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ VMX_SPI_FLASH_CS_GPIO);
++ }
++#endif // USE_SPI_GPIO_B5_CS
++#if defined(CONFIG_CAN_MCP251X) || defined(CONFIG_CAN_MCP251X_MODULE)
++ ret = gpio_request(VMX_SPI_CAN_CS_GPIO, "MCP251X CS");
++
++ if (ret == 0) {
++ gpio_direction_output(VMX_SPI_CAN_CS_GPIO, 1);
++ /* Free the CS GPIO, to allow SPI driver to register it again */
++ gpio_free(VMX_SPI_CAN_CS_GPIO);
++ } else {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ VMX_SPI_CAN_CS_GPIO);
++ }
++
++#endif // CONFIG_CAN_MCP251X
++#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
++ ret = gpio_request(VMX_SPI_TOUCH_CS_GPIO, "TSC2046 CS");
++
++ if (ret == 0) {
++ gpio_direction_output(VMX_SPI_TOUCH_CS_GPIO, 1);
++ /* Free the CS GPIO, to allow SPI driver to register it again */
++ gpio_free(VMX_SPI_TOUCH_CS_GPIO);
++ } else {
++ printk(KERN_INFO "%s: Failed to request GPIO %d\n", __FUNCTION__,
++ VMX_SPI_TOUCH_CS_GPIO);
++ }
++
++ tsc2046_setup();
++#endif
++
++ return 0;
++}
++
++static void vmx_cspi1_exit(struct device *dev)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx_cspi1_pads,
++ ARRAY_SIZE(vmx_cspi1_pads));
++}
++
++static struct spi_imx_master vmx_spi1_data = {
++ .chipselect = vmx_spi_chipselect,
++ .num_chipselect = ARRAY_SIZE(vmx_spi_chipselect),
++};
++
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++#include <linux/mtd/partitions.h>
++#include <mtd/mtd-abi.h>
++#include <linux/spi/flash.h>
++static struct mtd_partition spi_flash_partitions[] = {
++ {
++ .name = "vmx_rom(spi)",
++ .size = 0x00040000,
++ .offset = 0,
++ .mask_flags = MTD_CAP_ROM
++ }, {
++ .name = "vmx_rwm(spi)",
++ .size = MTDPART_SIZ_FULL,
++ .offset = MTDPART_OFS_APPEND,
++ }
++};
++
++static struct flash_platform_data spi_flash_data = {
++ .name = "m25p80",
++ .parts = spi_flash_partitions,
++ .nr_parts = ARRAY_SIZE(spi_flash_partitions),
++ .type = "sst25vf016b"
++};
++#endif // CONFIG_MTD_M25P80
++
++static struct spi_board_info vmx_spi_info[] __initdata = {
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++ {
++ /* the modalias must be the same as spi device driver name */
++ .modalias = "m25p80", /* Name of spi_driver for this device */
++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
++ .bus_num = 0, /* Framework bus number */
++ .chip_select = 0, /* On vmx it's SPI0_SS0 */
++ .platform_data = &spi_flash_data,
++ .mode = SPI_MODE_3,
++ },
++#endif // CONFIG_MTD_M25P80
++#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
++ {
++ .modalias = "spidev",
++ .max_speed_hz = 2000000,
++ .bus_num = 0,
++ .chip_select = 1,
++ },
++#endif // CONFIG_SPI_SPIDEV
++#if defined(CONFIG_CAN_MCP251X) || defined(CONFIG_CAN_MCP251X_MODULE)
++ {
++ .modalias = "mcp251x",
++ .irq = gpio_to_irq(CAN_MCP251X_IRQ),
++ .max_speed_hz = 2000000,
++ .chip_select = 2,
++ .platform_data = &mcp251x_info,
++ .mode = SPI_MODE_0,
++ },
++#endif // CONFIG_CAN_MCP251X
++#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
++ {
++ .modalias = "ads7846",
++ .irq = gpio_to_irq(TSC2046_PENDOWN),
++ .max_speed_hz = 1500000,
++ .chip_select = 3,
++ .platform_data = &ads7846_config,
++ .mode = SPI_MODE_2,
++ },
++#endif // CONFIG_TOUCHSCREEN_ADS7846
++};
++#endif // CONFIG_SPI_IMX
++
++#if defined(CONFIG_KEYBOARD_IMX) || defined(CONFIG_KEYBOARD_IMX_MODULE)
++/*
++ * This array is used for mapping keypad scancodes to keyboard keycodes.
++ */
++static const uint32_t vmx25_kpd_keycodes[] = {
++ /* specify your keymap with KEY(row, col, keycode), */
++// KEY(0, 0, KEY_POWER),
++ KEY(0, 1, KEY_HOME),
++ KEY(0, 3, KEY_BACK),
++ KEY(2, 1, KEY_MENU),
++ KEY(2, 3, KEY_ZOOM),
++};
++
++static struct matrix_keymap_data vmx25_keypad_data = {
++ .keymap = vmx25_kpd_keycodes,
++ .keymap_size = ARRAY_SIZE(vmx25_kpd_keycodes),
++};
++
++static struct pad_desc vmx25_keypad_pads[] __initdata = {
++ MX25_PAD_KPP_ROW0__KPP_ROW0,
++ MX25_PAD_KPP_ROW1__KPP_ROW1,
++ MX25_PAD_KPP_ROW2__KPP_ROW2,
++ MX25_PAD_KPP_ROW3__KPP_ROW3,
++
++ MX25_PAD_KPP_COL0__KPP_COL0,
++ MX25_PAD_KPP_COL1__KPP_COL1,
++ MX25_PAD_KPP_COL2__KPP_COL2,
++ MX25_PAD_KPP_COL3__KPP_COL3,
++};
++
++static int vmx25_keypad_init(struct device *dev)
++{
++ return mxc_iomux_v3_setup_multiple_pads(vmx25_keypad_pads,
++ ARRAY_SIZE(vmx25_keypad_pads));
++}
++
++static void vmx25_keypad_exit(struct device *dev)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx25_keypad_pads,
++ ARRAY_SIZE(vmx25_keypad_pads));
++}
++#endif // CONFIG_KEYBOARD_IMX
++
++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
++#define VMX_GPIO_LED0 (GPIO_PORTB | 4)
++#define VMX_GPIO_LED1 (GPIO_PORTB | 5)
++
++static struct pad_desc vmx_led_pads[] = {
++ MX25_PAD_A18__GPIO_2_4,
++ MX25_PAD_A19__GPIO_2_5,
++};
++
++static struct gpio_led vmx_leds[] = {
++ {
++ .name = "red",
++ .default_trigger = "heartbeat",
++ .gpio = VMX_GPIO_LED0,
++ },
++ {
++ .name = "orange",
++ .default_trigger = "none",
++ .gpio = VMX_GPIO_LED1,
++ }
++};
++
++static struct gpio_led_platform_data vmx_led_data = {
++ .leds = vmx_leds,
++ .num_leds = ARRAY_SIZE(vmx_leds),
++};
++
++static struct platform_device vmx_led_device = {
++ .name = "leds-gpio",
++ .id = -1,
++ .dev = {
++ .platform_data = &vmx_led_data,
++ },
++};
++
++static int __init vmx_led_init(void)
++{
++ int ret;
++
++ ret = mxc_iomux_v3_setup_multiple_pads(vmx_led_pads,
++ ARRAY_SIZE(vmx_led_pads));
++ if (ret)
++ printk(KERN_INFO "%s: Failed to setup PADS for LED: %d\n",
++ __FUNCTION__, ret);
++
++ ret = gpio_request(VMX_GPIO_LED0, "LED0");
++ if (ret)
++ printk(KERN_INFO "%s: Failed to request GPIO%d_%d for LED: %d\n",
++ __FUNCTION__, VMX_GPIO_LED0 / 32,
++ VMX_GPIO_LED0 % 32, ret);
++
++ ret = gpio_request(VMX_GPIO_LED1, "LED1");
++ if (ret)
++ printk(KERN_INFO "%s: Failed to request GPIO%d_%d for LED: %d\n",
++ __FUNCTION__, VMX_GPIO_LED1 / 32,
++ VMX_GPIO_LED1 % 32, ret);
++
++
++ gpio_direction_output(VMX_GPIO_LED0, 0);
++ gpio_direction_output(VMX_GPIO_LED1, 0);
++
++ /* free the GPIO, so that the LED driver can grab it */
++ gpio_free(VMX_GPIO_LED0);
++ gpio_free(VMX_GPIO_LED1);
++
++ return ret;
++}
++arch_initcall(vmx_led_init);
++#endif
++
++#if defined(CONFIG_SND_IMX_SOC) || defined(CONFIG_SND_IMX_SOC_MODULE)
++struct imx_ssi_platform_data vmx_ssi_pdata = {
++ .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
++};
++#endif // CONFIG_SND_IMX_SOC
++
++#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
++static struct pad_desc vmx_aud4_pads[] = {
++ MX25_PAD_EB0__AUD4_TXD,
++ MX25_PAD_EB1__AUD4_RXD,
++ MX25_PAD_RW__AUD4_TXFS,
++ MX25_PAD_OE__AUD4_TXC,
++};
++
++/*!
++ * This function activates DAM port 4 to enable
++ * audio I/O.
++ */
++static int sgtl5000_plat_init(void)
++{
++ return mxc_iomux_v3_setup_multiple_pads(vmx_aud4_pads,
++ ARRAY_SIZE(vmx_aud4_pads));
++}
++
++/*!
++ * This function inactivates DAM port 4 for
++ * audio I/O
++ */
++static int sgtl5000_plat_exit(void)
++{
++ mxc_iomux_v3_release_multiple_pads(vmx_aud4_pads,
++ ARRAY_SIZE(vmx_aud4_pads));
++ return 0;
++}
++
++static struct mxc_audio_platform_data stk5_sgtl5000_data = {
++ .ssi_num = 0, // MASU fixme
++ .src_port = 1,
++ .ext_port = 4,
++ .init = sgtl5000_plat_init, /* board specific init */
++ .finit = sgtl5000_plat_exit, /* board specific finit */
++ .hp_irq = 0,
++ .hp_status = NULL,
++ .amp_enable = NULL,
++ .sysclk = 12288000,
++};
++
++static struct platform_device vmx_sgtl5000_device = {
++ .name = "imx-3stack-sgtl5000",
++ .dev = {
++ .platform_data = &stk5_sgtl5000_data,
++ },
++};
++#endif // CONFIG_SND_SOC_IMX_3STACK_SGTL5000
++
++#if defined(CONFIG_RADIO_SI4705) || defined(CONFIG_RADIO_SI4705_MODULE)
++static struct pad_desc vmx_radio_pads[] = {
++ MX25_PAD_VSTBY_ACK__GPIO_3_18, /* RESET_OUT_3V3 */
++ MX25_PAD_UPLL_BYPCLK__GPIO_3_16, /* SSI2_INT */
++};
++
++#define RADIO_GPIO82 (GPIO_PORTC | 18) // Reset
++#define RADIO_GPIO80 RADIO_SI4705_IRQ // IRQ
++
++static int radio_si4705_reset(void) {
++ int err = 0;
++
++ err |= mxc_iomux_v3_setup_multiple_pads(vmx_radio_pads,
++ ARRAY_SIZE(vmx_radio_pads));
++
++ err |= gpio_request(RADIO_GPIO82, "GPIO82");
++ err |= gpio_request(RADIO_GPIO80, "GPIO80");
++ if (err) {
++ return err;
++ }
++
++ gpio_direction_output(RADIO_GPIO82, 0);
++ gpio_direction_output(RADIO_GPIO80, 0);
++
++ gpio_set_value(RADIO_GPIO82, 0);
++ gpio_set_value(RADIO_GPIO80, 0);
++
++ err = 0; // FIXME active delay
++ while (--err) ;
++
++ gpio_set_value(RADIO_GPIO82, 1);
++ gpio_direction_input(RADIO_GPIO80);
++
++ gpio_free(RADIO_GPIO80);
++
++ return 0;
++}
++#endif // CONFIG_RADIO_SI4705
++
++#if defined(CONFIG_FB_IMX) || defined(CONFIG_FB_IMX_MODULE)
++#define VMX_LCD_BACKLIGHT_GPIO (GPIO_PORTA | 26)
++//#define VMX_LCD_RESET_GPIO (GPIO_PORTB | 4)
++//#define VMX_LCD_POWER_GPIO (GPIO_PORTB | 5)
++
++/*
++ * Setup GPIO for LCDC device to be active
++ *
++ */
++static struct pad_desc mx25_lcdc_gpios[] = {
++#ifdef VMX_LCD_BACKLIGHT_GPIO
++// MX25_PAD_A18__GPIO_2_4, /* LCD Reset (active LOW) */
++#if !defined(CONFIG_MXC_PWM) && !defined(CONFIG_MXC_PWM_MODULE)
++ MX25_PAD_PWM__GPIO_1_26, /* LCD Backlight brightness 0: full 1: off */
++#endif
++// MX25_PAD_A19__GPIO_2_5, /* LCD Power Enable 0: off 1: on */
++#endif
++ MX25_PAD_LSCLK__LSCLK,
++ MX25_PAD_LD0__LD0,
++ MX25_PAD_LD1__LD1,
++ MX25_PAD_LD2__LD2,
++ MX25_PAD_LD3__LD3,
++ MX25_PAD_LD4__LD4,
++ MX25_PAD_LD5__LD5,
++ MX25_PAD_LD6__LD6,
++ MX25_PAD_LD7__LD7,
++ MX25_PAD_LD8__LD8,
++ MX25_PAD_LD9__LD9,
++ MX25_PAD_LD10__LD10,
++ MX25_PAD_LD11__LD11,
++ MX25_PAD_LD12__LD12,
++ MX25_PAD_LD13__LD13,
++ MX25_PAD_LD14__LD14,
++ MX25_PAD_LD15__LD15,
++ MX25_PAD_D15__LD16,
++ MX25_PAD_D14__LD17,
++ MX25_PAD_HSYNC__HSYNC,
++ MX25_PAD_VSYNC__VSYNC,
++ MX25_PAD_OE_ACD__OE_ACD,
++};
++
++static int vmx_gpio_lcdc_active(struct platform_device *dev)
++{
++ int ret;
++
++ printk(KERN_INFO "%s: Setting up GPIO pins for LCD\n", __FUNCTION__);
++ ret = mxc_iomux_v3_setup_multiple_pads(mx25_lcdc_gpios,
++ ARRAY_SIZE(mx25_lcdc_gpios));
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to setup GPIO pins for LCD: %d\n",
++ __FUNCTION__, ret);
++ return ret;
++ }
++#ifdef VMX_LCD_BACKLIGHT_GPIO
++// ret = gpio_request(VMX_LCD_POWER_GPIO, "LCD POWER");
++// if (ret) {
++// printk(KERN_INFO "%s: Failed to request GPIO for LCD POWER: %d\n",
++// __FUNCTION__, ret);
++// goto release_pins;
++// }
++#if !defined(CONFIG_MXC_PWM) && !defined(CONFIG_MXC_PWM_MODULE)
++ ret = gpio_request(VMX_LCD_BACKLIGHT_GPIO, "LCD Backlight");
++ if (ret) {
++ printk(KERN_INFO "%s: Failed to request GPIO for backlight control: %d\n",
++ __FUNCTION__, ret);
++ goto free_gpio1;
++ }
++#endif
++// ret = gpio_request(VMX_LCD_RESET_GPIO, "LCD RESET");
++// if (ret) {
++// printk(KERN_INFO "%s: Failed to request GPIO for LCD RESET: %d\n",
++// __FUNCTION__, ret);
++// goto free_gpio2;
++// }
++
++// gpio_direction_output(VMX_LCD_POWER_GPIO, 1);
++#if !defined(CONFIG_MXC_PWM) && !defined(CONFIG_MXC_PWM_MODULE)
++ gpio_direction_output(VMX_LCD_BACKLIGHT_GPIO, 1);
++#endif
++// gpio_direction_output(VMX_LCD_RESET_GPIO, 0);
++#endif
++ return 0;
++
++//free_gpio2:
++#if !defined(CONFIG_MXC_PWM) && !defined(CONFIG_MXC_PWM_MODULE)
++ gpio_free(VMX_LCD_BACKLIGHT_GPIO);
++free_gpio1:
++#endif
++// gpio_free(VMX_LCD_POWER_GPIO);
++//release_pins:
++ mxc_iomux_v3_release_multiple_pads(mx25_lcdc_gpios,
++ ARRAY_SIZE(mx25_lcdc_gpios));
++ return ret;
++}
++
++/*
++ * Setup GPIO for LCDC device to be inactive
++ *
++ */
++static void vmx_gpio_lcdc_inactive(struct platform_device *dev)
++{
++ mxc_iomux_v3_release_multiple_pads(mx25_lcdc_gpios,
++ ARRAY_SIZE(mx25_lcdc_gpios));
++}
++
++#ifdef VMX_LCD_BACKLIGHT_GPIO
++#if !defined(CONFIG_MXC_PWM) && !defined(CONFIG_MXC_PWM_MODULE)
++static void vmx_lcdc_backlight(int on)
++{
++ printk(KERN_INFO "%s: Switching LCD backlight %s\n", __FUNCTION__, on ? "on" : "off");
++ if (on) {
++ gpio_set_value(VMX_LCD_BACKLIGHT_GPIO, 0);
++ } else {
++ gpio_set_value(VMX_LCD_BACKLIGHT_GPIO, 1);
++ }
++}
++#else
++#define vmx_lcdc_backlight NULL
++#endif
++
++static void vmx_lcdc_power(int on)
++{
++ printk(KERN_INFO "%s: Switching LCD reset %s\n", __FUNCTION__, on ? "off" : "on");
++// if (on) {
++// gpio_set_value(VMX_LCD_RESET_GPIO, 1);
++// } else {
++// gpio_set_value(VMX_LCD_RESET_GPIO, 0);
++// }
++}
++#else
++#define vmx_lcdc_backlight NULL
++#define vmx_lcdc_power NULL
++#endif
++
++static struct imx_fb_videomode vmx_fb_modes[] = {
++ {
++ .bpp = 16,
++ .mode = {
++ .name = "VGA-16@60",
++
++ .pixclock = KHZ2PICOS(24000),
++ .xres = 640,
++ .yres = 480,
++
++ .hsync_len = 44,
++ .left_margin = 66+8, /* Back porch */
++ .right_margin = 2, /* Front porch */
++
++ .vsync_len = 2,
++ .upper_margin = 25+8, /* Back porch */
++ .lower_margin = 2+8, /* Front porch */
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_BPIX_16 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL,
++ },
++ {
++ .bpp = 32,
++ .mode = {
++ .name = "VGA-32@60",
++
++ .pixclock = KHZ2PICOS(24000),
++ .xres = 640,
++ .yres = 480,
++
++ .hsync_len = 44,
++ .left_margin = 66+8, /* Back porch */
++ .right_margin = 2, /* Front porch */
++
++ .vsync_len = 2,
++ .upper_margin = 25+8, /* Back porch */
++ .lower_margin = 2+8, /* Front porch */
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_BPIX_18 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL | PCR_END_SEL,
++ },
++ {
++ /* fH=30KHz HSYNC=1000px, fV=60Hz VSYNC=500lines, fCLK=30000*/
++ .bpp = 16,
++ .mode = {
++ .name = "WVGA-LCD",
++ .pixclock = KHZ2PICOS(30000),
++
++ .xres = 800,
++ .yres = 480,
++
++ .hsync_len = 64,
++ .left_margin = 120, /* Back porch */
++ .right_margin = 16, /* Front porch */
++
++ .vsync_len = 2,
++ .upper_margin = 16, /* Back porch */
++ .lower_margin = 2, /* Front porch */
++
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, // -PCR_CLKPOL, +PCR_OEPOL
++ },
++ {
++ .bpp = 16,
++ .mode = {
++ .name = "WVGA-16@60",
++ .pixclock = KHZ2PICOS(30000),
++
++ .xres = 800,
++ .yres = 480,
++
++ .hsync_len = 54,
++ .left_margin = 100, /* Back porch */
++ .right_margin = 16, /* Front porch */
++
++ .vsync_len = 4,
++ .upper_margin = 28, /* Back porch */
++ .lower_margin = 4, /* Front porch */
++
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL,
++ },
++ {
++ .bpp = 32,
++ .mode = {
++ .name = "WVGA-32@60",
++ .pixclock = KHZ2PICOS(30000),
++
++ .xres = 800,
++ .yres = 480,
++
++ .hsync_len = 54,
++ .left_margin = 100, /* Back porch */
++ .right_margin = 16, /* Front porch */
++
++ .vsync_len = 4,
++ .upper_margin = 28, /* Back porch */
++ .lower_margin = 4, /* Front porch */
++
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_18 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL | PCR_END_SEL,
++
++ },
++ {
++ .bpp = 16,
++ .mode = {
++ .name = "SVGA-16@60",
++ .pixclock = KHZ2PICOS(40000),
++
++ .xres = 800,
++ .yres = 600,
++
++ .hsync_len = 64,
++ .left_margin = 170, /* Back porch */
++ .right_margin = 24, /* Front porch */
++
++ .vsync_len = 5,
++ .upper_margin = 23, /* Back porch */
++ .lower_margin = 2, /* Front porch */
++
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL,
++ },
++ {
++ .bpp = 32,
++ .mode = {
++ .name = "SVGA-32@60",
++ .pixclock = KHZ2PICOS(40000),
++
++ .xres = 800,
++ .yres = 600,
++
++ .hsync_len = 64,
++ .left_margin = 170, /* Back porch */
++ .right_margin = 24, /* Front porch */
++
++ .vsync_len = 5,
++ .upper_margin = 23, /* Back porch */
++ .lower_margin = 2, /* Front porch */
++
++ },
++
++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_18 |
++ PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL | PCR_END_SEL,
++
++ },
++};
++
++static struct imx_fb_platform_data vmx_fb_data = {
++ .init = vmx_gpio_lcdc_active,
++ .exit = vmx_gpio_lcdc_inactive,
++ .lcd_power = vmx_lcdc_power,
++ .backlight_power = vmx_lcdc_backlight,
++
++ .mode = vmx_fb_modes,
++ .num_modes = ARRAY_SIZE(vmx_fb_modes),
++
++ .dmacr = 0x00040060,
++
++ .cmap_greyscale = 0,
++ .cmap_inverse = 0,
++ .cmap_static = 0,
++
++ .fixed_screen_cpu = NULL,
++};
++#endif
++
++#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
++static struct pad_desc vmx_pwm_pads[] = {
++ MX25_PAD_PWM__PWM,
++};
++
++static int vmx_backlight_init(struct device *dev)
++{
++ int ret;
++ ret = mxc_iomux_v3_setup_pad(&vmx_pwm_pads[0]);
++ return ret;
++}
++
++static int vmx_backlight_notify(struct device *dev, int brightness)
++{
++ printk(KERN_INFO "%s: brightness=%d\n", __FUNCTION__, brightness);
++ return brightness;
++}
++
++static void vmx_backlight_exit(struct device *dev)
++{
++ mxc_iomux_v3_release_pad(&vmx_pwm_pads[0]);
++}
++
++static struct platform_pwm_backlight_data vmx_backlight_data = {
++ .pwm_id = 0,
++ .max_brightness = 100,
++ .dft_brightness = 50,
++ .pwm_period_ns = KHZ2PICOS(20000), /* kHz -> ps is the same as Hz -> ns */
++ .init = vmx_backlight_init,
++ .notify = vmx_backlight_notify,
++ .exit = vmx_backlight_exit,
++};
++
++static struct platform_device vmx_backlight_pwm_device = {
++ .name = "pwm-backlight",
++ .dev = {
++ .platform_data = &vmx_backlight_data,
++ },
++};
++#endif /* CONFIG_BACKLIGHT_PWM || CONFIG_BACKLIGHT_PWM_MODULE */
++
++#if defined(CONFIG_MMC_SDHCI_MXC) || defined(CONFIG_MMC_SDHCI_MXC_MODULE)
++#define SDHC1_CD_GPIO (GPIO_PORTD | 4)
++#define SDHC1_SEL_SLOT (GPIO_PORTD | 10)
++
++/*
++ * Resource definition for the SDHC1
++ */
++static struct resource vmx_sdhc1_resources[] = {
++ {
++ .start = MMC_SDHC1_BASE_ADDR,
++ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = MXC_INT_SDHC1,
++ .end = MXC_INT_SDHC1,
++ .flags = IORESOURCE_IRQ,
++ }, {
++ .start = gpio_to_irq(SDHC1_CD_GPIO),
++ .end = gpio_to_irq(SDHC1_CD_GPIO),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static inline int vmx_esdhci_get_irq(int id)
++{
++ int irq;
++
++ switch (id) {
++ case 0:
++ irq = vmx_sdhc1_resources[2].start;
++ break;
++ default:
++ BUG();
++ }
++ return irq;
++}
++
++static const char *vmx_esdhci_irqdesc[] = {
++ "ESDHCI card 0 detect",
++};
++
++static struct pad_desc vmx_sdhc_pads[] = {
++ MX25_PAD_SD1_CMD__SD1_CMD,
++ MX25_PAD_SD1_CLK__SD1_CLK,
++ MX25_PAD_SD1_DATA0__SD1_DATA0,
++ MX25_PAD_SD1_DATA2__SD1_DATA2,
++ MX25_PAD_SD1_DATA3__SD1_DATA3,
++ /* card detect GPIO */
++ MX25_PAD_BCLK__GPIO_4_4,
++ /* SD CLK switch GPIO */
++ MX25_PAD_D10__GPIO_4_10,
++};
++
++static int vmx_esdhci_status(struct device *dev)
++{
++ return !!gpio_get_value(SDHC1_CD_GPIO);
++}
++
++static int vmx_esdhci_init(struct device *dev, irqreturn_t (*esdhci_detect_irq)(int, void *),
++ void *data)
++{
++ int err;
++ struct mmc_host *host = data;
++ int id = to_platform_device(dev)->id;
++ int irq = vmx_esdhci_get_irq(id);
++
++ err = mxc_iomux_v3_setup_multiple_pads(vmx_sdhc_pads,
++ ARRAY_SIZE(vmx_sdhc_pads));
++ if (err) {
++ return err;
++ }
++
++ err = gpio_request(SDHC1_SEL_SLOT, "SD card slot select");
++// if (err) {
++// return err;
++// }
++ gpio_direction_output(SDHC1_SEL_SLOT, 0);
++
++#if defined(CONFIG_VMX_SD_ON_MODULE)
++ gpio_set_value(SDHC1_SEL_SLOT, 1);
++#elif defined(CONFIG_VMX_SD_ON_BOARD)
++ gpio_set_value(SDHC1_SEL_SLOT, 0);
++#else
++#error "Choice active SD slot internal/external"
++#endif
++
++ host->caps |= MMC_CAP_4_BIT_DATA;
++
++ printk(KERN_INFO "%s: Requesting IRQ %d\n", __FUNCTION__, irq);
++ err = request_irq(irq, esdhci_detect_irq,
++ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
++ vmx_esdhci_irqdesc[id], data);
++ if (err) {
++ dev_err(dev, "Error %d requesting ESDHCI card detect IRQ %d\n",
++ err, irq);
++ return err;
++ }
++ device_set_wakeup_capable(dev, 1);
++
++ return 0;
++}
++
++static void vmx_esdhci_exit(struct device *dev, void *data)
++{
++ int id = to_platform_device(dev)->id;
++ int irq = vmx_esdhci_get_irq(id);
++
++ printk(KERN_INFO "%s: Freeing IRQ %d\n", __FUNCTION__, irq);
++ free_irq(irq, data);
++ gpio_free(SDHC1_SEL_SLOT);
++ mxc_iomux_v3_release_multiple_pads(vmx_sdhc_pads,
++ ARRAY_SIZE(vmx_sdhc_pads));
++}
++
++static int vmx_esdhci_suspend(struct device *dev)
++{
++ int id = to_platform_device(dev)->id;
++ int irq = vmx_esdhci_get_irq(id);
++
++ if (device_may_wakeup(dev)) {
++ printk(KERN_INFO "%s: Enabling IRQ %d wakeup\n", __FUNCTION__, irq);
++ return enable_irq_wake(irq);
++ }
++ return 0;
++}
++
++static int vmx_esdhci_resume(struct device *dev)
++{
++ int id = to_platform_device(dev)->id;
++ int irq = vmx_esdhci_get_irq(id);
++
++ if (device_may_wakeup(dev)) {
++ printk(KERN_INFO "%s: Disabling IRQ %d wakeup\n", __FUNCTION__, irq);
++ return disable_irq_wake(irq);
++ }
++ return 0;
++}
++
++static struct mxc_sdhci_platform_data vmx_sdhc1_data = {
++ .ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34,
++ .init = vmx_esdhci_init,
++ .exit = vmx_esdhci_exit,
++ .suspend = vmx_esdhci_suspend,
++ .resume = vmx_esdhci_resume,
++ .status = vmx_esdhci_status,
++ .min_clk = 150000,
++ .max_clk = 25000000,
++ .detect_delay = 100,
++#if defined(CONFIG_VMX_SD_ON_MODULE)
++ .force_sd_detect=1
++#else
++ .force_sd_detect=0
++#endif
++};
++
++static struct platform_device vmx_sdhc1_device = {
++ .name = "sdhci",
++ .id = 0,
++ .dev = {
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ .platform_data = &vmx_sdhc1_data,
++ },
++ .num_resources = ARRAY_SIZE(vmx_sdhc1_resources),
++ .resource = vmx_sdhc1_resources,
++};
++#endif
++
++static struct platform_dev_list {
++ struct platform_device *pdev;
++ void *pdata;
++} vmx_devices[] __initdata = {
++#if defined(CONFIG_FB_IMX) || defined(CONFIG_FB_IMX_MODULE)
++ { .pdev = &mx25_fb_device, .pdata = &vmx_fb_data, },
++#endif
++#if defined(CONFIG_MXC_PWM) || defined(CONFIG_MXC_PWM_MODULE)
++ { .pdev = &mxc_pwm_device0, },
++#endif
++#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
++ { .pdev = &vmx_backlight_pwm_device, .pdata = &vmx_backlight_data, },
++#endif
++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
++ { .pdev = &vmx_led_device, },
++#endif
++#if defined(CONFIG_MMC_SDHCI_MXC) || defined(CONFIG_MMC_SDHCI_MXC_MODULE)
++ { .pdev = &vmx_sdhc1_device, },
++#endif
++#if defined(CONFIG_SND_IMX_SOC) || defined(CONFIG_SND_IMX_SOC_MODULE)
++ { .pdev = &imx_ssi_device0, .pdata = &vmx_ssi_pdata, },
++#endif
++#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
++ { .pdev = &vmx_sgtl5000_device, },
++#endif
++};
++#define VMX_NUM_DEVICES ARRAY_SIZE(vmx_devices)
++
++static __init int vmx_board_init(void)
++{
++ int ret;
++ int i;
++
++ /* Do UART init */
++#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
++#if UART1_ENABLED
++ imx25_add_imx_uart0(&vmx_uart_pdata[0]);
++#endif
++#if UART2_ENABLED
++ imx25_add_imx_uart1(&vmx_uart_pdata[1]);
++#endif
++#if UART3_ENABLED
++ imx25_add_imx_uart2(&vmx_uart_pdata[2]);
++#endif
++#if UART4_ENABLED
++ imx25_add_imx_uart3(&vmx_uart_pdata[3]);
++#endif
++#if UART5_ENABLED
++ imx25_add_imx_uart4(&vmx_uart_pdata[4]);
++#endif
++#endif // CONFIG_SERIAL_IMX
++
++
++ // Do USB init
++#if defined(CONFIG_USB_EHCI_MXC) || defined(CONFIG_USB_EHCI_MXC_MODULE)
++ if (otg_mode_host) { // HOST
++ mxc_register_device(&mxc_otg, &vmx_usbotg_pdata);
++ } else { // OTG
++ #if defined(CONFIG_USB_FSL_USB2) || defined(CONFIG_USB_FSL_USB2_MODULE)
++ mxc_register_device(&otg_udc_device, &vmx_usb_pdata);
++ #endif // CONFIG_USB_FSL_USB2
++ }
++
++ mxc_register_device(&mxc_usbh2, &vmx_usbh2_pdata);
++#endif // CONFIG_USB_EHCI_MXC
++
++
++ // Do I2C init
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++ imx25_add_imx_i2c0(&vmx_i2c1_data);
++ ret = i2c_register_board_info(0, vmx_i2c1_boardinfo,
++ ARRAY_SIZE(vmx_i2c1_boardinfo));
++ if (ret)
++ printk(KERN_ERR "Failed to register I2C board info: %d\n", ret);
++#endif // CONFIG_I2C
++
++ // Do SPI init
++#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
++ ret = vmx_cspi1_init(NULL);
++ if (ret) {
++ printk(KERN_ERR "Failed to configure CSPI1 pads\n");
++ } else {
++ imx25_add_spi_imx0(&vmx_spi1_data);
++ ret = spi_register_board_info(vmx_spi_info,
++ ARRAY_SIZE(vmx_spi_info));
++ if (ret) {
++ printk(KERN_ERR "Failed to register SPI board info: %d\n", ret);
++ } else {
++// vmx_cspi1_exit(NULL);
++ }
++ }
++#endif // CONFIG_SPI_IMX
++
++
++ // Do CAN1 init
++#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
++ ret = vmx_can2_init(NULL);
++ if (ret) {
++ printk(KERN_ERR "Failed to configure FLEXCAN2 pads\n");
++// vmx_can2_exit(NULL);
++ } else {
++ imx25_add_flexcan1(NULL);
++ }
++#endif // CONFIG_CAN_FLEXCAN
++
++ // Do KEYPAD init
++#if defined(CONFIG_KEYBOARD_IMX) || defined(CONFIG_KEYBOARD_IMX_MODULE)
++ ret = vmx25_keypad_init(NULL);
++ if (ret) {
++ printk(KERN_ERR "Failed to configure Keypad pads\n");
++ } else {
++ ret = mxc_register_device(&mxc_keypad_device, &vmx25_keypad_data);
++ if (ret) {
++ printk(KERN_WARNING "%s: Failed to register platform_device: %s\n",
++ __FUNCTION__, mxc_keypad_device.name);
++ vmx25_keypad_exit(NULL);
++ }
++ }
++#endif // CONFIG_KEYBOARD_IMX
++
++ // Do audmux interconnection
++#if defined(CONFIG_SND_IMX_SOC) || defined(CONFIG_SND_IMX_SOC_MODULE)
++ /* SSI unit master I2S codec connected to SSI_AUD4*/
++ mxc_audmux_v2_configure_port(0, 0, 0); // reset the ports
++ mxc_audmux_v2_configure_port(3, 0, 0);
++ mxc_audmux_v2_configure_port(0,
++ MXC_AUDMUX_V2_PTCR_SYN |
++ MXC_AUDMUX_V2_PTCR_TFSDIR |
++ MXC_AUDMUX_V2_PTCR_TFSEL(3) |
++ MXC_AUDMUX_V2_PTCR_TCLKDIR |
++ MXC_AUDMUX_V2_PTCR_TCSEL(3),
++ MXC_AUDMUX_V2_PDCR_RXDSEL(3)
++ );
++ mxc_audmux_v2_configure_port(3,
++ MXC_AUDMUX_V2_PTCR_SYN,
++ MXC_AUDMUX_V2_PDCR_RXDSEL(0)
++ );
++#endif // CONFIG_SND_IMX_SOC
++
++#if defined(CONFIG_RADIO_SI4705) || defined(CONFIG_RADIO_SI4705_MODULE)
++ radio_si4705_reset();
++#endif // CONFIG_RADIO_SI4705
++
++ for (i = 0; i < VMX_NUM_DEVICES; i++) {
++ if (vmx_devices[i].pdev == NULL) continue;
++ printk(KERN_INFO "%s: Registering platform device[%d] @ %p dev %p: %s\n",
++ __FUNCTION__, i, vmx_devices[i].pdev, &vmx_devices[i].pdev->dev,
++ vmx_devices[i].pdev->name);
++ if (vmx_devices[i].pdata) {
++ ret = mxc_register_device(vmx_devices[i].pdev,
++ vmx_devices[i].pdata);
++ } else {
++ ret = platform_device_register(vmx_devices[i].pdev);
++ }
++ if (ret) {
++ printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n",
++ __FUNCTION__, i, vmx_devices[i].pdev->name, ret);
++ }
++ }
++ printk(KERN_INFO "%s: Done\n", __FUNCTION__);
++
++ return 0;
++}
++subsys_initcall(vmx_board_init);
+diff -urN linux.35.old/arch/arm/plat-mxc/audmux-v2.c linux.35.new/arch/arm/plat-mxc/audmux-v2.c
+--- linux.35.old/arch/arm/plat-mxc/audmux-v2.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/audmux-v2.c 2010-12-03 09:51:55.360347257 +0100
+@@ -13,10 +13,6 @@
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+ #include <linux/module.h>
+@@ -191,6 +187,7 @@
+ {
+ int ret;
+
++#if defined(CONFIG_ARCH_MX3)
+ if (cpu_is_mx31())
+ audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
+
+@@ -204,7 +201,19 @@
+ }
+ audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
+ }
+-
++#endif
++#if defined(CONFIG_ARCH_MX25)
++ if (cpu_is_mx25()) {
++ audmux_clk = clk_get(NULL, "audmux");
++ if (IS_ERR(audmux_clk)) {
++ ret = PTR_ERR(audmux_clk);
++ printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
++ ret);
++ return ret;
++ }
++ audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
++ }
++#endif
+ audmux_debugfs_init();
+
+ return 0;
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/Kconfig linux.35.new/arch/arm/plat-mxc/devices/Kconfig
+--- linux.35.old/arch/arm/plat-mxc/devices/Kconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/Kconfig 2010-12-03 09:51:55.360347257 +0100
+@@ -0,0 +1,15 @@
++config IMX_HAVE_PLATFORM_FLEXCAN
++ select HAVE_CAN_FLEXCAN
++ bool
++
++config IMX_HAVE_PLATFORM_IMX_I2C
++ bool
++
++config IMX_HAVE_PLATFORM_IMX_UART
++ bool
++
++config IMX_HAVE_PLATFORM_MXC_NAND
++ bool
++
++config IMX_HAVE_PLATFORM_SPI_IMX
++ bool
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/Makefile linux.35.new/arch/arm/plat-mxc/devices/Makefile
+--- linux.35.old/arch/arm/plat-mxc/devices/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/Makefile 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,8 @@
++ifdef CONFIG_CAN_FLEXCAN
++# the ifdef can be removed once the flexcan driver has been merged
++obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
++endif
++obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
++obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
++#obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
++obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/platform-flexcan.c linux.35.new/arch/arm/plat-mxc/devices/platform-flexcan.c
+--- linux.35.old/arch/arm/plat-mxc/devices/platform-flexcan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/platform-flexcan.c 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2010 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++
++#include <mach/devices-common.h>
++
++struct platform_device *__init imx_add_flexcan(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irq,
++ const struct flexcan_platform_data *pdata)
++{
++ struct resource res[] = {
++ {
++ .start = iobase,
++ .end = iobase + iosize - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = irq,
++ .end = irq,
++ .flags = IORESOURCE_IRQ,
++ },
++ };
++
++ return imx_add_platform_device("flexcan", id, res, ARRAY_SIZE(res),
++ pdata, sizeof(*pdata));
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/platform-imx-i2c.c linux.35.new/arch/arm/plat-mxc/devices/platform-imx-i2c.c
+--- linux.35.old/arch/arm/plat-mxc/devices/platform-imx-i2c.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/platform-imx-i2c.c 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2009-2010 Pengutronix
++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <mach/devices-common.h>
++
++struct platform_device *__init imx_add_imx_i2c(int id,
++ resource_size_t iobase, resource_size_t iosize, int irq,
++ const struct imxi2c_platform_data *pdata)
++{
++ struct resource res[] = {
++ {
++ .start = iobase,
++ .end = iobase + iosize - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = irq,
++ .end = irq,
++ .flags = IORESOURCE_IRQ,
++ },
++ };
++
++ return imx_add_platform_device("imx-i2c", id, res, ARRAY_SIZE(res),
++ pdata, sizeof(*pdata));
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/platform-imx-uart.c linux.35.new/arch/arm/plat-mxc/devices/platform-imx-uart.c
+--- linux.35.old/arch/arm/plat-mxc/devices/platform-imx-uart.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/platform-imx-uart.c 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2009-2010 Pengutronix
++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <mach/devices-common.h>
++
++struct platform_device *__init imx_add_imx_uart_3irq(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irqrx, resource_size_t irqtx,
++ resource_size_t irqrts,
++ const struct imxuart_platform_data *pdata)
++{
++ struct resource res[] = {
++ {
++ .start = iobase,
++ .end = iobase + iosize - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = irqrx,
++ .end = irqrx,
++ .flags = IORESOURCE_IRQ,
++ }, {
++ .start = irqtx,
++ .end = irqtx,
++ .flags = IORESOURCE_IRQ,
++ }, {
++ .start = irqrts,
++ .end = irqrx,
++ .flags = IORESOURCE_IRQ,
++ },
++ };
++
++ return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
++ pdata, sizeof(*pdata));
++}
++
++struct platform_device *__init imx_add_imx_uart_1irq(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irq,
++ const struct imxuart_platform_data *pdata)
++{
++ struct resource res[] = {
++ {
++ .start = iobase,
++ .end = iobase + iosize - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = irq,
++ .end = irq,
++ .flags = IORESOURCE_IRQ,
++ },
++ };
++
++ return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
++ pdata, sizeof(*pdata));
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/devices/platform-spi_imx.c linux.35.new/arch/arm/plat-mxc/devices/platform-spi_imx.c
+--- linux.35.old/arch/arm/plat-mxc/devices/platform-spi_imx.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/devices/platform-spi_imx.c 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2009-2010 Pengutronix
++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <asm/sizes.h>
++#include <mach/devices-common.h>
++
++struct platform_device *__init imx_add_spi_imx(int id,
++ resource_size_t iobase, resource_size_t iosize, int irq,
++ const struct spi_imx_master *pdata)
++{
++ struct resource res[] = {
++ {
++ .start = iobase,
++ .end = iobase + iosize - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = irq,
++ .end = irq,
++ .flags = IORESOURCE_IRQ,
++ },
++ };
++
++ return imx_add_platform_device("spi_imx", id, res, ARRAY_SIZE(res),
++ pdata, sizeof(*pdata));
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/devices.c linux.35.new/arch/arm/plat-mxc/devices.c
+--- linux.35.old/arch/arm/plat-mxc/devices.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/devices.c 2010-12-03 09:51:55.364349489 +0100
+@@ -18,6 +18,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/err.h>
+ #include <linux/platform_device.h>
+ #include <mach/common.h>
+
+@@ -35,3 +36,35 @@
+ return ret;
+ }
+
++struct platform_device *__init imx_add_platform_device(const char *name, int id,
++ const struct resource *res, unsigned int num_resources,
++ const void *data, size_t size_data)
++{
++ int ret = -ENOMEM;
++ struct platform_device *pdev;
++
++ pdev = platform_device_alloc(name, id);
++ if (!pdev)
++ goto err;
++
++ if (res) {
++ ret = platform_device_add_resources(pdev, res, num_resources);
++ if (ret)
++ goto err;
++ }
++
++ if (data) {
++ ret = platform_device_add_data(pdev, data, size_data);
++ if (ret)
++ goto err;
++ }
++
++ ret = platform_device_add(pdev);
++ if (ret) {
++err:
++ platform_device_put(pdev);
++ return ERR_PTR(ret);
++ }
++
++ return pdev;
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/ehci.c linux.35.new/arch/arm/plat-mxc/ehci.c
+--- linux.35.old/arch/arm/plat-mxc/ehci.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/ehci.c 2010-12-03 09:51:55.364349489 +0100
+@@ -11,10 +11,6 @@
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software Foundation,
+- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+ #include <linux/platform_device.h>
+@@ -25,6 +21,19 @@
+
+ #define USBCTRL_OTGBASE_OFFSET 0x600
+
++
++#define MX25_OTG_SIC_SHIFT 29
++#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
++#define MX25_OTG_PM_BIT (1 << 24)
++
++#define MX25_H1_SIC_SHIFT 21
++#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
++#define MX25_H1_PM_BIT (1 << 16)
++#define MX25_H1_IPPUE_UP_BIT (1 << 7)
++#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
++#define MX25_H1_TLL_BIT (1 << 5)
++#define MX25_H1_USBTE_BIT (1 << 4)
++
+ #define MX31_OTG_SIC_SHIFT 29
+ #define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
+ #define MX31_OTG_PM_BIT (1 << 24)
+@@ -73,7 +82,51 @@
+ int mxc_initialize_usb_hw(int port, unsigned int flags)
+ {
+ unsigned int v;
+-#ifdef CONFIG_ARCH_MX3
++#if defined(CONFIG_ARCH_MX25)
++ if (cpu_is_mx25()) {
++ v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
++ USBCTRL_OTGBASE_OFFSET));
++
++ switch (port) {
++ case 0: /* OTG port */
++ v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT);
++ v |= (flags & MXC_EHCI_INTERFACE_MASK)
++ << MX25_OTG_SIC_SHIFT;
++ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
++ v |= MX25_OTG_PM_BIT;
++
++ break;
++ case 1: /* H1 port */
++ v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_TLL_BIT |
++ MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
++ v |= (flags & MXC_EHCI_INTERFACE_MASK)
++ << MX35_H1_SIC_SHIFT;
++ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
++ v |= MX25_H1_PM_BIT;
++
++ if (!(flags & MXC_EHCI_TTL_ENABLED))
++ v |= MX25_H1_TLL_BIT;
++
++ if (flags & MXC_EHCI_INTERNAL_PHY)
++ v |= MX25_H1_USBTE_BIT;
++
++ if (flags & MXC_EHCI_IPPUE_DOWN)
++ v |= MX25_H1_IPPUE_DOWN_BIT;
++
++ if (flags & MXC_EHCI_IPPUE_UP)
++ v |= MX25_H1_IPPUE_UP_BIT;
++
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
++ USBCTRL_OTGBASE_OFFSET));
++ return 0;
++ }
++#endif /* CONFIG_ARCH_MX25 */
++#if defined(CONFIG_ARCH_MX3)
+ if (cpu_is_mx31()) {
+ v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/board-vmx25.h linux.35.new/arch/arm/plat-mxc/include/mach/board-vmx25.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/board-vmx25.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/board-vmx25.h 2010-12-03 09:51:55.364349489 +0100
+@@ -0,0 +1,15 @@
++/*
++ * Copyright 2010 <support@voipac.com>
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#ifndef __ASM_ARCH_MXC_BOARD_VMX25_H__
++#define __ASM_ARCH_MXC_BOARD_VMX25_H__
++
++#endif /* __ASM_ARCH_MXC_BOARD_VMX25_H__ */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/devices-common.h linux.35.new/arch/arm/plat-mxc/include/mach/devices-common.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/devices-common.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/devices-common.h 2010-12-03 09:51:55.368349274 +0100
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2009-2010 Pengutronix
++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/init.h>
++
++struct platform_device *imx_add_platform_device(const char *name, int id,
++ const struct resource *res, unsigned int num_resources,
++ const void *data, size_t size_data);
++
++#if defined (CONFIG_CAN_FLEXCAN) || defined (CONFIG_CAN_FLEXCAN_MODULE)
++#include <linux/can/platform/flexcan.h>
++struct platform_device *__init imx_add_flexcan(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irq,
++ const struct flexcan_platform_data *pdata);
++#else
++/* the ifdef can be removed once the flexcan driver has been merged */
++struct flexcan_platform_data;
++static inline struct platform_device *__init imx_add_flexcan(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irq,
++ const struct flexcan_platform_data *pdata)
++{
++ return NULL;
++}
++#endif
++
++#include <mach/i2c.h>
++struct platform_device *__init imx_add_imx_i2c(int id,
++ resource_size_t iobase, resource_size_t iosize, int irq,
++ const struct imxi2c_platform_data *pdata);
++
++#include <mach/imx-uart.h>
++struct platform_device *__init imx_add_imx_uart_3irq(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irqrx, resource_size_t irqtx,
++ resource_size_t irqrts,
++ const struct imxuart_platform_data *pdata);
++struct platform_device *__init imx_add_imx_uart_1irq(int id,
++ resource_size_t iobase, resource_size_t iosize,
++ resource_size_t irq,
++ const struct imxuart_platform_data *pdata);
++
++#include <mach/mxc_nand.h>
++struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
++ int irq, const struct mxc_nand_platform_data *pdata);
++struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
++ int irq, const struct mxc_nand_platform_data *pdata);
++
++#include <mach/spi.h>
++struct platform_device *__init imx_add_spi_imx(int id,
++ resource_size_t iobase, resource_size_t iosize, int irq,
++ const struct spi_imx_master *pdata);
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/dma.h linux.35.new/arch/arm/plat-mxc/include/mach/dma.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/dma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/dma.h 2010-12-03 09:51:55.368349274 +0100
+@@ -0,0 +1,293 @@
++/*
++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_MXC_DMA_H__
++#define __ASM_ARCH_MXC_DMA_H__
++
++#define MXC_DMA_DYNAMIC_CHANNEL 255
++
++#define MXC_DMA_DONE 0x0
++#define MXC_DMA_REQUEST_TIMEOUT 0x1
++#define MXC_DMA_TRANSFER_ERROR 0x2
++
++/*! This defines the list of device ID's for DMA */
++typedef enum mxc_dma_device {
++ MXC_DMA_UART1_RX,
++ MXC_DMA_UART1_TX,
++ MXC_DMA_UART2_RX,
++ MXC_DMA_UART2_TX,
++ MXC_DMA_UART3_RX,
++ MXC_DMA_UART3_TX,
++ MXC_DMA_UART4_RX,
++ MXC_DMA_UART4_TX,
++ MXC_DMA_UART5_RX,
++ MXC_DMA_UART5_TX,
++ MXC_DMA_UART6_RX,
++ MXC_DMA_UART6_TX,
++ MXC_DMA_MMC1_WIDTH_1,
++ MXC_DMA_MMC1_WIDTH_4,
++ MXC_DMA_MMC2_WIDTH_1,
++ MXC_DMA_MMC2_WIDTH_4,
++ MXC_DMA_SSI1_8BIT_RX0,
++ MXC_DMA_SSI1_8BIT_TX0,
++ MXC_DMA_SSI1_16BIT_RX0,
++ MXC_DMA_SSI1_16BIT_TX0,
++ MXC_DMA_SSI1_24BIT_RX0,
++ MXC_DMA_SSI1_24BIT_TX0,
++ MXC_DMA_SSI1_8BIT_RX1,
++ MXC_DMA_SSI1_8BIT_TX1,
++ MXC_DMA_SSI1_16BIT_RX1,
++ MXC_DMA_SSI1_16BIT_TX1,
++ MXC_DMA_SSI1_24BIT_RX1,
++ MXC_DMA_SSI1_24BIT_TX1,
++ MXC_DMA_SSI2_8BIT_RX0,
++ MXC_DMA_SSI2_8BIT_TX0,
++ MXC_DMA_SSI2_16BIT_RX0,
++ MXC_DMA_SSI2_16BIT_TX0,
++ MXC_DMA_SSI2_24BIT_RX0,
++ MXC_DMA_SSI2_24BIT_TX0,
++ MXC_DMA_SSI2_8BIT_RX1,
++ MXC_DMA_SSI2_8BIT_TX1,
++ MXC_DMA_SSI2_16BIT_RX1,
++ MXC_DMA_SSI2_16BIT_TX1,
++ MXC_DMA_SSI2_24BIT_RX1,
++ MXC_DMA_SSI2_24BIT_TX1,
++ MXC_DMA_FIR_RX,
++ MXC_DMA_FIR_TX,
++ MXC_DMA_CSPI1_RX,
++ MXC_DMA_CSPI1_TX,
++ MXC_DMA_CSPI2_RX,
++ MXC_DMA_CSPI2_TX,
++ MXC_DMA_CSPI3_RX,
++ MXC_DMA_CSPI3_TX,
++ MXC_DMA_ATA_RX,
++ MXC_DMA_ATA_TX,
++ MXC_DMA_MEMORY,
++ MXC_DMA_FIFO_MEMORY,
++ MXC_DMA_DSP_PACKET_DATA0_RD,
++ MXC_DMA_DSP_PACKET_DATA0_WR,
++ MXC_DMA_DSP_PACKET_DATA1_RD,
++ MXC_DMA_DSP_PACKET_DATA1_WR,
++ MXC_DMA_DSP_LOG0_CHNL,
++ MXC_DMA_DSP_LOG1_CHNL,
++ MXC_DMA_DSP_LOG2_CHNL,
++ MXC_DMA_DSP_LOG3_CHNL,
++ MXC_DMA_CSI_RX,
++ MXC_DMA_SPDIF_16BIT_TX,
++ MXC_DMA_SPDIF_16BIT_RX,
++ MXC_DMA_SPDIF_32BIT_TX,
++ MXC_DMA_SPDIF_32BIT_RX,
++ MXC_DMA_ASRC_A_RX,
++ MXC_DMA_ASRC_A_TX,
++ MXC_DMA_ASRC_B_RX,
++ MXC_DMA_ASRC_B_TX,
++ MXC_DMA_ASRC_C_RX,
++ MXC_DMA_ASRC_C_TX,
++ MXC_DMA_ASRCA_ESAI,
++ MXC_DMA_ASRCB_ESAI,
++ MXC_DMA_ASRCC_ESAI,
++ MXC_DMA_ASRCA_SSI1_TX0,
++ MXC_DMA_ASRCA_SSI1_TX1,
++ MXC_DMA_ASRCA_SSI2_TX0,
++ MXC_DMA_ASRCA_SSI2_TX1,
++ MXC_DMA_ASRCB_SSI1_TX0,
++ MXC_DMA_ASRCB_SSI1_TX1,
++ MXC_DMA_ASRCB_SSI2_TX0,
++ MXC_DMA_ASRCB_SSI2_TX1,
++ MXC_DMA_ESAI_16BIT_RX,
++ MXC_DMA_ESAI_16BIT_TX,
++ MXC_DMA_ESAI_24BIT_RX,
++ MXC_DMA_ESAI_24BIT_TX,
++ MXC_DMA_TEST_RAM2D2RAM,
++ MXC_DMA_TEST_RAM2RAM2D,
++ MXC_DMA_TEST_RAM2D2RAM2D,
++ MXC_DMA_TEST_RAM2RAM,
++ MXC_DMA_TEST_HW_CHAINING,
++ MXC_DMA_TEST_SW_CHAINING
++} mxc_dma_device_t;
++
++/*! This defines the prototype of callback funtion registered by the drivers */
++typedef void (*mxc_dma_callback_t) (void *arg, int error_status,
++ unsigned int count);
++
++/*! This defines the type of DMA transfer requested */
++typedef enum mxc_dma_mode {
++ MXC_DMA_MODE_READ,
++ MXC_DMA_MODE_WRITE,
++} mxc_dma_mode_t;
++
++/*! This defines the DMA channel parameters */
++typedef struct mxc_dma_channel {
++ unsigned int active:1; /* When there has a active tranfer, it is set to 1 */
++ unsigned int lock; /* Defines the channel is allocated or not */
++ int curr_buf; /* Current buffer */
++ mxc_dma_mode_t mode; /* Read or Write */
++ unsigned int channel; /* Channel number */
++ unsigned int dynamic:1; /* Channel not statically allocated when 1 */
++ char *dev_name; /* Device name */
++ void *private; /* Private structure for platform */
++ mxc_dma_callback_t cb_fn; /*!< The callback function */
++ void *cb_args; /* The argument of callback function */
++} mxc_dma_channel_t;
++
++/*! This structure contains the information about a dma transfer */
++typedef struct mxc_dma_requestbuf {
++ dma_addr_t src_addr; /* source address */
++ dma_addr_t dst_addr; /* destination address */
++ int num_of_bytes; /* the length of this transfer : bytes */
++} mxc_dma_requestbuf_t;
++
++/*! This struct contains the information for asrc special*/
++struct dma_channel_asrc_info {
++ u32 channs; /* data channels in asrc */
++};
++
++/*! This struct contains the information for device special*/
++struct dma_channel_info {
++ struct dma_channel_asrc_info asrc; /* asrc special information */
++};
++
++#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX21)
++#include <mach/mx2_dma.h>
++#else
++#include <mach/sdma.h>
++#endif
++
++struct scatterlist;
++
++/*!
++ * This function is generally called by the driver at open time.
++ * The DMA driver would do any initialization steps that is required
++ * to get the channel ready for data transfer.
++ *
++ * @param channel_id a pre-defined id. The peripheral driver would specify
++ * the id associated with its peripheral. This would be
++ * used by the DMA driver to identify the peripheral
++ * requesting DMA and do the necessary setup on the
++ * channel associated with the particular peripheral.
++ * The DMA driver could use static or dynamic DMA channel
++ * allocation.
++ * @param dev_name module name or device name
++ * @param data the customized parameter for special channel.
++ * @return returns a negative number on error if request for a DMA channel did not
++ * succeed, returns the channel number to be used on success.
++ */
++extern int mxc_dma_request_ext(mxc_dma_device_t channel_id, char *dev_name,
++ struct dma_channel_info *info);
++
++static inline int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
++{
++ return mxc_dma_request_ext(channel_id, dev_name, NULL);
++}
++
++/*!
++ * This function is generally called by the driver at close time. The DMA
++ * driver would do any cleanup associated with this channel.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++extern int mxc_dma_free(int channel_num);
++
++/*!
++ * This function would just configure the buffers specified by the user into
++ * dma channel. The caller must call mxc_dma_enable to start this transfer.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param dma_buf an array of physical addresses to the user defined
++ * buffers. The caller must guarantee the dma_buf is
++ * available until the transfer is completed.
++ * @param num_buf number of buffers in the array
++ * @param mode specifies whether this is READ or WRITE operation
++ * @return This function returns a negative number on error if buffer could not be
++ * added with DMA for transfer. On Success, it returns 0
++ */
++extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t *dma_buf,
++ int num_buf, mxc_dma_mode_t mode);
++
++/*!
++ * This function would just configure the scatterlist specified by the
++ * user into dma channel. This is a slight variation of mxc_dma_config(),
++ * it is provided for the convenience of drivers that have a scatterlist
++ * passed into them. It is the calling driver's responsibility to have the
++ * correct physical address filled in the "dma_address" field of the
++ * scatterlist.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param sg a scatterlist of buffers. The caller must guarantee
++ * the dma_buf is available until the transfer is
++ * completed.
++ * @param num_buf number of buffers in the array
++ * @param num_of_bytes total number of bytes to transfer. If set to 0, this
++ * would imply to use the length field of the scatterlist
++ * for each DMA transfer. Else it would calculate the size
++ * for each DMA transfer.
++ * @param mode specifies whether this is READ or WRITE operation
++ * @return This function returns a negative number on error if buffer could not
++ * be added with DMA for transfer. On Success, it returns 0
++ */
++extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
++ int num_buf, int num_of_bytes,
++ mxc_dma_mode_t mode);
++
++/*!
++ * This function is provided if the driver would like to set/change its
++ * callback function.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param callback a callback function to provide notification on transfer
++ * completion, user could specify NULL if he does not wish
++ * to be notified
++ * @param arg an argument that gets passed in to the callback
++ * function, used by the user to do any driver specific
++ * operations.
++ * @return this function returns a negative number on error if the callback
++ * could not be set for the channel or 0 on success
++ */
++extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
++ void *arg);
++
++/*!
++ * This stops the DMA channel and any ongoing transfers. Subsequent use of
++ * mxc_dma_enable() will restart the channel and restart the transfer.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++extern int mxc_dma_disable(int channel_num);
++
++/*!
++ * This starts DMA transfer. Or it restarts DMA on a stopped channel
++ * previously stopped with mxc_dma_disable().
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++extern int mxc_dma_enable(int channel_num);
++
++#endif
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/imxfb.h linux.35.new/arch/arm/plat-mxc/include/mach/imxfb.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/imxfb.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/imxfb.h 2010-12-03 09:51:55.368349274 +0100
+@@ -17,6 +17,7 @@
+ #define PCR_BPIX_12 (4 << 25)
+ #define PCR_BPIX_16 (5 << 25)
+ #define PCR_BPIX_18 (6 << 25)
++#define PCR_BPIX_24 (7 << 25)
+ #define PCR_PIXPOL (1 << 24)
+ #define PCR_FLMPOL (1 << 23)
+ #define PCR_LPPOL (1 << 22)
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux.35.new/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/iomux-mx25.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/iomux-mx25.h 2010-12-03 09:51:55.368349274 +0100
+@@ -155,7 +155,7 @@
+
+ #define MX25_PAD_D10__D10 IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
+ #define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
+-#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_22K_UP)
+
+ #define MX25_PAD_D9__D9 IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
+ #define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
+@@ -163,7 +163,7 @@
+
+ #define MX25_PAD_D8__D8 IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
+ #define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
+-#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_22K_UP)
+
+ #define MX25_PAD_D7__D7 IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL)
+ #define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL)
+@@ -371,31 +371,31 @@
+ #define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL)
+ #define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE)
+-#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE)
+-#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE)
+-#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
+-#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x03, 0x488, 2, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE)
+-#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
+-#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
++#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x03, 0x48c, 2, NO_PAD_CTRL)
++#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+-#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
++#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+-#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
++#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+-#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
++#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x05, 0, 0, NO_PAD_CTRL)
+
+-#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+-#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
++#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x00, 0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
++#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x05, 0, 0, NO_PAD_CTRL)
+
+ #define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL)
+ #define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
+@@ -442,7 +442,7 @@
+ #define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE)
+
+ #define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL)
+-#define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K)
++#define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K_UP)
+ #define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP)
+
+ #define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL)
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/iomux-v3.h linux.35.new/arch/arm/plat-mxc/include/mach/iomux-v3.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/iomux-v3.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/iomux-v3.h 2010-12-03 09:51:55.372348122 +0100
+@@ -101,6 +101,19 @@
+ int mxc_iomux_v3_setup_multiple_pads(struct pad_desc *pad_list, unsigned count);
+
+ /*
++ * releases a single pad:
++ * - make it available for a future use by another driver
++ * - DOES NOT reconfigure the IOMUX in its reset state
++ */
++void mxc_iomux_v3_release_pad(struct pad_desc *pad);
++
++/*
++ * releases multiple pads
++ * convenvient way to call the above function with tables
++ */
++void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count);
++
++/*
+ * Initialise the iomux controller
+ */
+ void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/memory.h linux.35.new/arch/arm/plat-mxc/include/mach/memory.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/memory.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/memory.h 2011-01-12 14:23:34.124489511 +0100
+@@ -50,6 +50,13 @@
+ * This is required for i.MX camera driver to capture at least four VGA frames.
+ */
+ #define CONSISTENT_DMA_SIZE SZ_4M
++
++#elif defined(CONFIG_ARCH_MX25)
++/*
++ * Increase size of DMA-consistent memory region.
++ * This is required for i.MX fb driver to support android on VGA screens at 32 bit.
++ */
++#define CONSISTENT_DMA_SIZE SZ_4M
+ #endif /* CONFIG_MX1_VIDEO */
+
+ #endif /* __ASM_ARCH_MXC_MEMORY_H__ */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/mx25.h linux.35.new/arch/arm/plat-mxc/include/mach/mx25.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/mx25.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/mx25.h 2010-12-03 09:51:55.372348122 +0100
+@@ -1,6 +1,10 @@
+ #ifndef __MACH_MX25_H__
+ #define __MACH_MX25_H__
+
++#define SDMA_V2
++
++#define CSD0_BASE_ADDR 0x80000000
++
+ #define MX25_AIPS1_BASE_ADDR 0x43f00000
+ #define MX25_AIPS1_BASE_ADDR_VIRT 0xfc000000
+ #define MX25_AIPS1_SIZE SZ_1M
+@@ -10,9 +14,19 @@
+ #define MX25_AVIC_BASE_ADDR 0x68000000
+ #define MX25_AVIC_BASE_ADDR_VIRT 0xfc400000
+ #define MX25_AVIC_SIZE SZ_1M
+-
++#define MX25_SPBA0_BASE_ADDR UL(0x50000000)
++#define MX25_SPBA0_BASE_ADDR_VIRT 0xFC100000
++#define MX25_SPBA0_SIZE SZ_1M
++
++#define MX25_I2C1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x80000)
++#define MX25_I2C3_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x84000)
++#define MX25_CAN1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x88000)
++#define MX25_CAN2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x8c000)
++#define MX25_I2C2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x98000)
++#define MX25_OWIRE_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x9c000)
++#define MX25_CSPI1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xa4000)
+ #define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000)
+-
++#define AUDMUX_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xb0000)
+ #define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
+ #define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000)
+ #define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000)
+@@ -27,22 +41,205 @@
+ IMX_IO_ADDRESS(x, MX25_AIPS2) ?: \
+ IMX_IO_ADDRESS(x, MX25_AVIC))
+
++#define MX25_AIPS1_IO_ADDRESS(x) \
++ (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
++#define MX25_AIPS2_IO_ADDRESS(x) \
++ (((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
++#define MX25_AVIC_IO_ADDRESS(x) \
++ (((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
++
+ #define MX25_UART1_BASE_ADDR 0x43f90000
+ #define MX25_UART2_BASE_ADDR 0x43f94000
++#define MX25_AUDMUX_BASE_ADDR 0x43fb0000
++#define MX25_UART3_BASE_ADDR 0x5000c000
++#define MX25_UART4_BASE_ADDR 0x50008000
++#define MX25_UART5_BASE_ADDR 0x5002c000
+
++#define MX25_CSPI3_BASE_ADDR 0x50004000
++#define MX25_CSPI2_BASE_ADDR 0x50010000
+ #define MX25_FEC_BASE_ADDR 0x50038000
++#define MX25_SSI2_BASE_ADDR 0x50014000
++#define MX25_SSI1_BASE_ADDR 0x50034000
+ #define MX25_NFC_BASE_ADDR 0xbb000000
+-#define MX25_DRYICE_BASE_ADDR 0x53ffc000
+ #define MX25_LCDC_BASE_ADDR 0x53fbc000
++#define MX25_OTG_BASE_ADDR 0x53ff4000
+
+-#define MX25_INT_DRYICE 25
+-#define MX25_INT_FEC 57
+ #define MX25_INT_NANDFC 33
+ #define MX25_INT_LCDC 39
+
+-#if defined(IMX_NEEDS_DEPRECATED_SYMBOLS)
+-#define UART1_BASE_ADDR MX25_UART1_BASE_ADDR
+-#define UART2_BASE_ADDR MX25_UART2_BASE_ADDR
++#define IO_ADDRESS(x) MX25_IO_ADDRESS(x)
++#define AVIC_IO_ADDRESS(x) MX25_AVIC_IO_ADDRESS(x)
++#define AVIC_BASE_ADDR MX25_AVIC_BASE_ADDR
++#define FEC_BASE_ADDR (MX25_FEC_BASE_ADDR)
++#define IIM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000F0000)
++//MMC
++#define MMC_SDHC1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000B4000)
++#define MMC_SDHC2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000B8000)
++//SDMA(MMC) + (audio)
++#define SSI1_BASE_ADDR (MX25_SPBA0_BASE_ADDR + 0x00034000)
++#define SSI2_BASE_ADDR (MX25_SPBA0_BASE_ADDR + 0x00014000)
++#define ESAI_BASE_ADDR (MX25_SPBA0_BASE_ADDR + 0x00018000)
++#define SDMA_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000D4000)
++//WTD
++#define WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000DC000)
++//ADC
++#define SPBA0_BASE_ADDR 0x50000000
++#define TSC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00030000)
++//SCC
++#define SCC_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000AC000)
++//RNG module
++#define RNGB_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000B0000)
++//DRYICE
++#define DRYICE_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x000FC000)
++
++/*!
++ * Defines for modules using static and dynamic DMA channels
++ */
++#define MXC_DMA_CHANNEL_IRAM 30
++#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART4_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART4_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART5_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_UART5_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
++#ifdef CONFIG_SDMA_IRAM
++#define MXC_DMA_CHANNEL_SSI1_TX (MXC_DMA_CHANNEL_IRAM + 1)
++#else
++#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+ #endif
++#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_ESAI_RX MXC_DMA_DYNAMIC_CHANNEL
++#define MXC_DMA_CHANNEL_ESAI_TX MXC_DMA_DYNAMIC_CHANNEL
++
++/*
++ * DMA request assignments
++ */
++#define DMA_REQ_EXTREQ0 0
++#define DMA_REQ_CCM 1
++#define DMA_REQ_ATA_TX_END 2
++#define DMA_REQ_ATA_TX 3
++#define DMA_REQ_ATA_RX 4
++#define DMA_REQ_CSPI2_RX 6
++#define DMA_REQ_CSPI2_TX 7
++#define DMA_REQ_CSPI1_RX 8
++#define DMA_REQ_CSPI1_TX 9
++#define DMA_REQ_UART3_RX 10
++#define DMA_REQ_UART3_TX 11
++#define DMA_REQ_UART4_RX 12
++#define DMA_REQ_UART4_TX 13
++#define DMA_REQ_EXTREQ1 14
++#define DMA_REQ_EXTREQ2 15
++#define DMA_REQ_UART2_RX 16
++#define DMA_REQ_UART2_TX 17
++#define DMA_REQ_UART1_RX 18
++#define DMA_REQ_UART1_TX 19
++#define DMA_REQ_SSI2_RX1 22
++#define DMA_REQ_SSI2_TX1 23
++#define DMA_REQ_SSI2_RX0 24
++#define DMA_REQ_SSI2_TX0 25
++#define DMA_REQ_SSI1_RX1 26
++#define DMA_REQ_SSI1_TX1 27
++#define DMA_REQ_SSI1_RX0 28
++#define DMA_REQ_SSI1_TX0 29
++#define DMA_REQ_NFC 30
++#define DMA_REQ_ECT 31
++#define DMA_REQ_ESAI_RX 32
++#define DMA_REQ_ESAI_TX 33
++#define DMA_REQ_CSPI3_RX 34
++#define DMA_REQ_CSPI3_TX 35
++#define DMA_REQ_SIM2_RX 36
++#define DMA_REQ_SIM2_TX 37
++#define DMA_REQ_SIM1_RX 38
++#define DMA_REQ_SIM1_TX 39
++#define DMA_REQ_TSC_GCQ 44
++#define DMA_REQ_TSC_TCQ 45
++#define DMA_REQ_UART5_RX 46
++#define DMA_REQ_UART5_TX 47
++
++/*
++ * Interrupt numbers
++ */
++#define MX25_INT_CSPI3 0
++#define MXC_INT_GPT4 1
++#define MXC_INT_OWIRE 2
++#define MX25_INT_I2C1 3
++#define MX25_INT_I2C2 4
++#define MX25_INT_UART4 5
++#define MXC_INT_RTIC 6
++#define MXC_INT_ESAI 7
++#define MXC_INT_SDHC2 8
++#define MXC_INT_SDHC1 9
++#define MX25_INT_I2C3 10
++#define MX25_INT_SSI2 11
++#define MX25_INT_SSI1 12
++#define MX25_INT_CSPI2 13
++#define MX25_INT_CSPI1 14
++#define MXC_INT_ATA 15
++#define MXC_INT_GPIO3 16
++#define MXC_INT_CSI 17
++#define MX25_INT_UART3 18
++#define MXC_INT_IIM 19
++#define MXC_INT_SIM1 20
++#define MXC_INT_SIM2 21
++#define MXC_INT_RNG 22
++#define MXC_INT_GPIO4 23
++#define MXC_INT_KPP 24
++#define MXC_INT_DRYICE_NORM 25
++#define MXC_INT_PWM 26
++#define MXC_INT_EPIT2 27
++#define MXC_INT_EPIT1 28
++#define MXC_INT_GPT3 29
++#define MXC_INT_POWER_FAIL 30
++#define MXC_INT_CCM 31
++#define MX25_INT_UART2 32
++#define MXC_INT_NANDFC 33
++#define MXC_INT_SDMA 34
++#define MXC_INT_USB_H2 35
++#define MXC_INT_PWM2 36
++#define MXC_INT_USB_OTG 37
++#define MXC_INT_SLCDC 38
++#define MXC_INT_LCDC 39
++#define MX25_INT_UART5 40
++#define MXC_INT_PWM3 41
++#define MXC_INT_PWM4 42
++#define MX25_INT_CAN1 43
++#define MX25_INT_CAN2 44
++#define MX25_INT_UART1 45
++#define MXC_INT_TSC 46
++#define MXC_INT_ECT 48
++#define MXC_INT_SCC_SCM 49
++#define MXC_INT_SCC_SMN 50
++#define MXC_INT_GPIO2 51
++#define MXC_INT_GPIO1 52
++#define MXC_INT_GPT2 53
++#define MXC_INT_GPT1 54
++#define MXC_INT_WDOG 55
++#define MXC_INT_DRYICE_SEC 56
++#define MX25_INT_FEC 57
++#define MXC_INT_EXT_INT5 58
++#define MXC_INT_EXT_INT4 59
++#define MXC_INT_EXT_INT3 60
++#define MXC_INT_EXT_INT2 61
++#define MXC_INT_EXT_INT1 62
++#define MXC_INT_EXT_INT0 63
++
++#define MXC_INT_GPT MXC_INT_GPT1
++
+
+ #endif /* ifndef __MACH_MX25_H__ */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/mxc.h linux.35.new/arch/arm/plat-mxc/include/mach/mxc.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/mxc.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/mxc.h 2010-12-03 09:51:55.372348122 +0100
+@@ -143,4 +143,35 @@
+ #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
+ #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
+
++#ifndef __ASSEMBLY__
++
++#include <linux/types.h>
++
++/*
++ * This struct is to define the number of SSIs on a platform,
++ * DAM source port config, DAM external port config,
++ * regulator names, and other stuff audio needs.
++ */
++struct mxc_audio_platform_data {
++ int ssi_num;
++ int src_port;
++ int ext_port;
++
++ int intr_id_hp;
++ int ext_ram;
++ struct clk *ssi_clk[2];
++
++ int hp_irq;
++ int (*hp_status) (void);
++
++ int sysclk;
++
++ int (*init) (void); /* board specific init */
++ int (*amp_enable) (int enable);
++ int (*finit) (void); /* board specific finit */
++ void *priv; /* used by board specific functions */
++};
++
++#endif //__ASSEMBLY__
++
+ #endif /* __ASM_ARCH_MXC_H__ */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/mxc_nand.h linux.35.new/arch/arm/plat-mxc/include/mach/mxc_nand.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/mxc_nand.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/mxc_nand.h 2010-12-03 09:51:55.372348122 +0100
+@@ -20,9 +20,14 @@
+ #ifndef __ASM_ARCH_NAND_H
+ #define __ASM_ARCH_NAND_H
+
++struct mtd_partition;
++struct mtd_info;
++
+ struct mxc_nand_platform_data {
+ int width; /* data bus width in bytes */
+ int hw_ecc:1; /* 0 if supress hardware ECC */
+ int flash_bbt:1; /* set to 1 to use a flash based bbt */
++ struct mtd_partition *parts; /* optional array of mtd_partitions for static partitioning */
++ unsigned int nr_parts; /* number of mtd_partitions for static partitoning */
+ };
+ #endif /* __ASM_ARCH_NAND_H */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/mxc_tsc.h linux.35.new/arch/arm/plat-mxc/include/mach/mxc_tsc.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/mxc_tsc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/mxc_tsc.h 2010-12-03 09:51:55.376350318 +0100
+@@ -0,0 +1,32 @@
++/*
++ * Freescale i.MX25 Touch Screen Driver
++ *
++ * Copyright (c) 2009 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ * Based on code from Freescale BSP
++ *
++ * 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.
++ */
++
++typedef enum {
++ MXC_TSC_4WIRE,
++ MXC_TSC_5WIRE,
++} mxc_tsc_mode;
++
++struct mxc_tsc_pdata {
++ int pen_debounce_time; /* 0: disable debounce;
++ * 1..128: # of ADC clock cycles / 8 */
++ unsigned int intref:1, /* 0|1: internal reference disabled|enabled */
++ hsyncen:1, /* synchronize measurements with LCD HSYNC */
++ hsyncpol:1; /* select HSYNC polarity: 1 == active low */
++ unsigned int r_xplate; /* resistance (in Ohms) of X plate
++ * (required for pressure measurement */
++ unsigned int settle_detect; /* Settling time for touch detection (in ADC clock cycles) */
++ unsigned int settle_measure; /* Settling time for measurement (in ADC clock cycles) */
++ unsigned int settle_precharge; /* Settling time for precharge (in ADC clock cycles) */
++ int adc_clk; /* ADC clock frequency in Hz (max. 1750000);
++ * <= 0: use default (1666667) */
++ mxc_tsc_mode tsc_mode; /* select 4 wire or 5 wire mode */
++};
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/sdhci.h linux.35.new/arch/arm/plat-mxc/include/mach/sdhci.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/sdhci.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/sdhci.h 2010-12-20 14:58:29.196000606 +0100
+@@ -0,0 +1,50 @@
++#ifndef __MACH_SDHCI_H
++#define __MACH_SDHCI_H
++
++#include <linux/mmc/host.h>
++struct device;
++
++struct mxc_sdhci_platform_data {
++ /* Return values for the get_ro callback should be:
++ * 0 for a read/write card
++ * 1 for a read-only card
++ * -ENOSYS when not supported (equal to NULL callback)
++ * or a negative errno value when something bad happened
++ */
++ int (*get_ro)(struct device *);
++
++ /* board specific hook to (de)initialize the SD slot.
++ * The board code can call 'handler' on a card detection
++ * change giving data as argument.
++ */
++ int (*init)(struct device *dev, irq_handler_t handler, void *data);
++ void (*exit)(struct device *dev, void *data);
++
++ /* delay in ms between card detect IRQ and scanning for
++ * card insertion/removal
++ */
++ int detect_delay;
++
++ /* available voltages. If not given, assume
++ * MMC_VDD_32_33 | MMC_VDD_33_34
++ */
++ unsigned int ocr_avail;
++ unsigned int caps;
++ unsigned int min_clk;
++ unsigned int max_clk;
++ unsigned int mxc_quirks;
++
++ /* adjust slot voltage */
++ int (*setpower)(struct device *dev, unsigned int vdd);
++#if 1
++ // FIXME: get rid of this
++ int (*status)(struct device *dev);
++#endif
++ int (*suspend)(struct device *dev);
++ int (*resume)(struct device *dev);
++
++ /* Set card detection state to 1 */
++ unsigned int force_sd_detect;
++};
++
++#endif /* __MACH_SDHCI_H */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/sdma.h linux.35.new/arch/arm/plat-mxc/include/mach/sdma.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/sdma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/sdma.h 2010-12-03 09:51:55.376350318 +0100
+@@ -0,0 +1,563 @@
++
++/*
++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#ifndef __ASM_ARCH_MXC_SDMA_H__
++#define __ASM_ARCH_MXC_SDMA_H__
++
++/*!
++ * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver
++ */
++
++/*!
++ * @file arch-mxc/sdma.h
++ *
++ * @brief This file contains the SDMA API declarations.
++ *
++ * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP).
++ *
++ * @ingroup SDMA
++ */
++
++#include <stdarg.h>
++#include <linux/interrupt.h>
++
++#include <mach/dma.h>
++#include <mach/hardware.h>
++
++/*!
++ * This defines maximum DMA address
++ */
++#define MAX_DMA_ADDRESS 0xffffffff
++
++#define DMA_ADDR_INVALID ((dma_addr_t)0)
++
++/*!
++ * This defines maximum number of DMA channels
++ */
++#ifdef CONFIG_MXC_SDMA_API
++#define MAX_DMA_CHANNELS 32
++#define MXC_SDMA_DEFAULT_PRIORITY 1
++#define MXC_SDMA_MIN_PRIORITY 1
++#define MXC_SDMA_MAX_PRIORITY 7
++#else
++#define MAX_DMA_CHANNELS 0
++#endif
++
++#define MXC_FIFO_MEM_DEST_FIXED 0x1
++#define MXC_FIFO_MEM_SRC_FIXED 0x2
++
++#define SDMA_ASRC_INFO_WML_OFF 0
++#define SDMA_ASRC_INFO_WML_MASK ((1 << 10) - 1)
++#define SDMA_ASRC_INFO_PS (1 << 10)
++#define SDMA_ASRC_INFO_PA (1 << 11)
++#define SDMA_ASRC_INFO_TXFR_DIR (1 << 14)
++#define SDMA_ASRC_INFO_N_OFF 24
++#define SDMA_ASRC_INFO_N_MASK ((1 << 4) - 1)
++
++#define SDMA_ASRC_P2P_INFO_LWML_OFF 0
++#define SDMA_ASRC_P2P_INFO_LWML_MASK ((1 << 8) - 1)
++#define SDMA_ASRC_P2P_INFO_PS (1 << 8)
++#define SDMA_ASRC_P2P_INFO_PA (1 << 9)
++#define SDMA_ASRC_P2P_INFO_SPDIF (1 << 10)
++#define SDMA_ASRC_P2P_INFO_SP (1 << 11)
++#define SDMA_ASRC_P2P_INFO_DP (1 << 12)
++#define SDMA_ASRC_P2P_INFO_HWML_OFF 14
++#define SDMA_ASRC_P2P_INFO_HWML_MASK ((1 << 10) - 1)
++#define SDMA_ASRC_P2P_INFO_LWE (1 << 28)
++#define SDMA_ASRC_P2P_INFO_HWE (1 << 29)
++#define SDMA_ASRC_P2P_INFO_CONT (1 << 31)
++
++/*!
++ * This enumerates transfer types
++ */
++typedef enum {
++ emi_2_per = 0, /*!< EMI memory to peripheral */
++ emi_2_int, /*!< EMI memory to internal RAM */
++ emi_2_emi, /*!< EMI memory to EMI memory */
++ emi_2_dsp, /*!< EMI memory to DSP memory */
++ per_2_int, /*!< Peripheral to internal RAM */
++ per_2_emi, /*!< Peripheral to internal EMI memory */
++ per_2_dsp, /*!< Peripheral to DSP memory */
++ per_2_per, /*!< Peripheral to Peripheral */
++ int_2_per, /*!< Internal RAM to peripheral */
++ int_2_int, /*!< Internal RAM to Internal RAM */
++ int_2_emi, /*!< Internal RAM to EMI memory */
++ int_2_dsp, /*!< Internal RAM to DSP memory */
++ dsp_2_per, /*!< DSP memory to peripheral */
++ dsp_2_int, /*!< DSP memory to internal RAM */
++ dsp_2_emi, /*!< DSP memory to EMI memory */
++ dsp_2_dsp, /*!< DSP memory to DSP memory */
++ emi_2_dsp_loop, /*!< EMI memory to DSP memory loopback */
++ dsp_2_emi_loop, /*!< DSP memory to EMI memory loopback */
++ dvfs_pll, /*!< DVFS script with PLL change */
++ dvfs_pdr /*!< DVFS script without PLL change */
++} sdma_transferT;
++
++/*!
++ * This enumerates peripheral types
++ */
++typedef enum {
++ SSI, /*!< MCU domain SSI */
++ SSI_SP, /*!< Shared SSI */
++ MMC, /*!< MMC */
++ SDHC, /*!< SDHC */
++ UART, /*!< MCU domain UART */
++ UART_SP, /*!< Shared UART */
++ FIRI, /*!< FIRI */
++ CSPI, /*!< MCU domain CSPI */
++ CSPI_SP, /*!< Shared CSPI */
++ SIM, /*!< SIM */
++ ATA, /*!< ATA */
++ CCM, /*!< CCM */
++ EXT, /*!< External peripheral */
++ MSHC, /*!< Memory Stick Host Controller */
++ MSHC_SP, /*!< Shared Memory Stick Host Controller */
++ DSP, /*!< DSP */
++ MEMORY, /*!< Memory */
++ FIFO_MEMORY, /*!< FIFO type Memory */
++ SPDIF, /*!< SPDIF */
++ IPU_MEMORY, /*!< IPU Memory */
++ ASRC, /*!< ASRC */
++ ESAI, /*!< ESAI */
++} sdma_periphT;
++
++#ifndef TRANSFER_32BIT
++/*!
++ * This defines SDMA access data size
++ */
++#define TRANSFER_32BIT 0x00
++#define TRANSFER_8BIT 0x01
++#define TRANSFER_16BIT 0x02
++#define TRANSFER_24BIT 0x03
++
++#endif
++
++/*!
++ * This defines maximum device name length passed during mxc_request_dma().
++ */
++#define MAX_DEVNAME_LENGTH 32
++
++/*!
++ * This defines SDMA interrupt callback function prototype.
++ */
++typedef void (*dma_callback_t) (void *arg);
++
++/*!
++ * Structure containing sdma channel parameters.
++ */
++typedef struct {
++ __u32 watermark_level; /* Lower/upper threshold that
++ * triggers SDMA event
++ * for p2p, this is event1 watermark level
++ */
++ __u32 per_address; /* Peripheral source/destination
++ * physical address
++ * for p2p, this is destination address
++ */
++ sdma_periphT peripheral_type; /* Peripheral type */
++ sdma_transferT transfer_type; /* Transfer type */
++ int event_id; /* Event number,
++ * needed by all channels
++ * that started by peripherals dma
++ * request (per_2_*,*_2_per)
++ * Not used for memory and DSP
++ * transfers.
++ */
++ int event_id2; /* Second event number,
++ * used in ATA scripts only.
++ */
++ int bd_number; /* Buffer descriptors number.
++ * If not set, single buffer
++ * descriptor will be used.
++ */
++ dma_callback_t callback;/* callback function */
++ void *arg; /* callback argument */
++ unsigned long word_size:8; /* SDMA data access word size */
++ unsigned long ext:1; /* 1: extend parameter structure */
++} dma_channel_params;
++
++typedef struct {
++ dma_channel_params common;
++ unsigned long p2p_dir:1; /* 0: per2 to per.
++ * the device of peripheral_type is per.
++ * 1: per to per2
++ * the device of peripheral_type is per2
++ */
++ unsigned long info_bits; /* info field in context */
++ unsigned long info_mask; /* info field mask in context */
++ __u32 watermark_level2; /* event2 threshold that triggers SDMA event
++ * just valid for per_2_per.
++ */
++ __u32 per_address2; /* Peripheral source physical address.
++ * only valid for per_2_per.
++ */
++ struct dma_channel_info info; /* the channel special parameter */
++} dma_channel_ext_params;
++
++/*!
++ * Structure containing sdma request parameters.
++ */
++typedef struct {
++ /*! physical source memory address */
++ dma_addr_t sourceAddr;
++ /*! physical destination memory address */
++ dma_addr_t destAddr;
++ /*! amount of data to transfer,
++ * updated during mxc_dma_get_config
++ */
++ __u16 count;
++ /*!< DONE bit of the buffer descriptor,
++ * updated during mxc_dma_get_config
++ * 0 - means the BD is done and closed by SDMA
++ * 1 - means the BD is still being processed by SDMA
++ */
++ unsigned int bd_done:1,
++ /*!< CONT bit of the buffer descriptor,
++ * set it if full multi-buffer descriptor mechanism
++ * required.
++ */
++ bd_cont:1,
++ /*!< ERROR bit of the buffer descriptor,
++ * updated during mxc_dma_get_config.
++ * If it is set - there was an error during BD processing.
++ */
++ bd_error:1,
++ bd_wrap:1;
++} dma_request_t;
++
++/*!
++ * Structure containing sdma request parameters.
++ */
++typedef struct {
++ /*! address of ap_2_ap script */
++ int mxc_sdma_ap_2_ap_addr;
++ /*! address of ap_2_bp script */
++ int mxc_sdma_ap_2_bp_addr;
++ /*! address of ap_2_ap_fixed script */
++ int mxc_sdma_ap_2_ap_fixed_addr;
++ /*! address of bp_2_ap script */
++ int mxc_sdma_bp_2_ap_addr;
++ /*! address of loopback_on_dsp_side script */
++ int mxc_sdma_loopback_on_dsp_side_addr;
++ /*! address of mcu_interrupt_only script */
++ int mxc_sdma_mcu_interrupt_only_addr;
++
++ /*! address of firi_2_per script */
++ int mxc_sdma_firi_2_per_addr;
++ /*! address of firi_2_mcu script */
++ int mxc_sdma_firi_2_mcu_addr;
++ /*! address of per_2_firi script */
++ int mxc_sdma_per_2_firi_addr;
++ /*! address of mcu_2_firi script */
++ int mxc_sdma_mcu_2_firi_addr;
++
++ /*! address of uart_2_per script */
++ int mxc_sdma_uart_2_per_addr;
++ /*! address of uart_2_mcu script */
++ int mxc_sdma_uart_2_mcu_addr;
++ /*! address of per_2_app script */
++ int mxc_sdma_per_2_app_addr;
++ /*! address of mcu_2_app script */
++ int mxc_sdma_mcu_2_app_addr;
++ /*! address of per_2_per script */
++ int mxc_sdma_per_2_per_addr;
++
++ /*! address of uartsh_2_per script */
++ int mxc_sdma_uartsh_2_per_addr;
++ /*! address of uartsh_2_mcu script */
++ int mxc_sdma_uartsh_2_mcu_addr;
++ /*! address of per_2_shp script */
++ int mxc_sdma_per_2_shp_addr;
++ /*! address of mcu_2_shp script */
++ int mxc_sdma_mcu_2_shp_addr;
++
++ /*! address of ata_2_mcu script */
++ int mxc_sdma_ata_2_mcu_addr;
++ /*! address of mcu_2_ata script */
++ int mxc_sdma_mcu_2_ata_addr;
++
++ /*! address of app_2_per script */
++ int mxc_sdma_app_2_per_addr;
++ /*! address of app_2_mcu script */
++ int mxc_sdma_app_2_mcu_addr;
++ /*! address of shp_2_per script */
++ int mxc_sdma_shp_2_per_addr;
++ /*! address of shp_2_mcu script */
++ int mxc_sdma_shp_2_mcu_addr;
++
++ /*! address of mshc_2_mcu script */
++ int mxc_sdma_mshc_2_mcu_addr;
++ /*! address of mcu_2_mshc script */
++ int mxc_sdma_mcu_2_mshc_addr;
++
++ /*! address of spdif_2_mcu script */
++ int mxc_sdma_spdif_2_mcu_addr;
++ /*! address of mcu_2_spdif script */
++ int mxc_sdma_mcu_2_spdif_addr;
++
++ /*! address of asrc_2_mcu script */
++ int mxc_sdma_asrc_2_mcu_addr;
++
++ /*! address of ext_mem_2_ipu script */
++ int mxc_sdma_ext_mem_2_ipu_addr;
++
++ /*! address of descrambler script */
++ int mxc_sdma_descrambler_addr;
++
++ /*! address of dptc_dvfs script */
++ int mxc_sdma_dptc_dvfs_addr;
++
++ int mxc_sdma_utra_addr;
++
++ /*! address where ram code starts */
++ int mxc_sdma_ram_code_start_addr;
++ /*! size of the ram code */
++ int mxc_sdma_ram_code_size;
++ /*! RAM image address */
++ unsigned short *mxc_sdma_start_addr;
++} sdma_script_start_addrs;
++
++/*! Structure to store the initialized dma_channel parameters */
++typedef struct mxc_sdma_channel_params {
++ /*! Channel type (static channel number or dynamic channel) */
++ unsigned int channel_num;
++ /*! Channel priority [0x1(lowest) - 0x7(highest)] */
++ unsigned int chnl_priority;
++ /*! Channel params */
++ dma_channel_params chnl_params;
++} mxc_sdma_channel_params_t;
++
++/*! Structure to store the initialized dma_channel extend parameters */
++typedef struct mxc_sdma_channel_ext_params {
++ /*! Channel type (static channel number or dynamic channel) */
++ unsigned int channel_num;
++ /*! Channel priority [0x1(lowest) - 0x7(highest)] */
++ unsigned int chnl_priority;
++ /*! Channel extend params */
++ dma_channel_ext_params chnl_ext_params;
++} mxc_sdma_channel_ext_params_t;
++
++/*! Private SDMA data structure */
++typedef struct mxc_dma_channel_private {
++ /*! ID of the buffer that was processed */
++ unsigned int buf_tail;
++ /*! Tasklet for the channel */
++ struct tasklet_struct chnl_tasklet;
++ /*! Flag indicates if interrupt is required after every BD transfer */
++ unsigned int intr_after_every_bd:1,
++ circular:1; /* circular BD chain */
++} mxc_dma_channel_private_t;
++
++/*!
++ * Setup channel according to parameters.
++ * Must be called once after mxc_request_dma()
++ *
++ * @param channel channel number
++ * @param p channel parameters pointer
++ * @return 0 on success, error code on fail
++ */
++extern int mxc_dma_setup_channel(int channel, dma_channel_params * p);
++
++/*!
++ * Setup the channel priority. This can be used to change the default priority
++ * for the channel.
++ *
++ * @param channel channel number
++ * @param priority priority to be set for the channel
++ *
++ * @return 0 on success, error code on failure
++ */
++extern int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority);
++
++/*!
++ * Allocates dma channel.
++ * If channel's value is 0, then the function allocates a free channel
++ * dynamically and sets its value to channel.
++ * Else allocates requested channel if it is free.
++ * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned.
++ *
++ * @param channel pointer to channel number
++ * @param devicename device name
++ * @return 0 on success, error code on fail
++ */
++extern int mxc_request_dma(int *channel, const char *devicename);
++
++/*!
++ * Configures request parameters. Can be called multiple times after
++ * mxc_request_dma() and mxc_dma_setup_channel().
++ *
++ *
++ * @param channel channel number
++ * @param p request parameters pointer
++ * @param bd_index index of buffer descriptor to set
++ * @return 0 on success, error code on fail
++ */
++/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */
++extern int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index);
++
++/*!
++ * Returns request parameters.
++ *
++ * @param channel channel number
++ * @param p request parameters pointer
++ * @param bd_index index of buffer descriptor to get
++ * @return 0 on success, error code on fail
++ */
++/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */
++extern int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index);
++
++/*!
++ * This function is used by MXC IPC's write_ex2. It passes the a pointer to the
++ * data control structure to iapi_write_ipcv2()
++ *
++ * @param channel SDMA channel number
++ * @param ctrl_ptr Data Control structure pointer
++ */
++extern int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr);
++
++/*!
++ * This function is used by MXC IPC's read_ex2. It passes the a pointer to the
++ * data control structure to iapi_read_ipcv2()
++ *
++ * @param channel SDMA channel number
++ * @param ctrl_ptr Data Control structure pointer
++ */
++extern int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr);
++
++/*!
++ * Starts dma channel.
++ *
++ * @param channel channel number
++ */
++extern int mxc_dma_start(int channel);
++
++/*!
++ * Stops dma channel.
++ *
++ * @param channel channel number
++ */
++extern int mxc_dma_stop(int channel);
++
++/*!
++ * Frees dma channel.
++ *
++ * @param channel channel number
++ */
++extern void mxc_free_dma(int channel);
++
++/*!
++ * Sets callback function. Used with standard dma api
++ * for supporting interrupts
++ *
++ * @param channel channel number
++ * @param callback callback function pointer
++ * @param arg argument for callback function
++ */
++extern void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg);
++
++/*!
++ * Allocates uncachable buffer. Uses hash table.
++ *
++ * @param size size of allocated buffer
++ * @return pointer to buffer
++ */
++extern void *sdma_malloc(size_t size);
++
++#ifdef CONFIG_SDMA_IRAM
++/*!
++ * Allocates uncachable buffer from IRAM..
++ *
++ * @param size size of allocated buffer
++ * @return pointer to buffer
++ */
++extern void *sdma_iram_malloc(size_t size);
++#endif /* CONFIG_SDMA_IRAM */
++
++/*!
++ * Frees uncachable buffer. Uses hash table.
++ */
++void sdma_free(void *buf);
++
++/*!
++ * Converts virtual to physical address. Uses hash table.
++ *
++ * @param buf virtual address pointer
++ * @return physical address value
++ */
++extern dma_addr_t sdma_virt_to_phys(void *buf);
++
++/*!
++ * Converts physical to virtual address. Uses hash table.
++ *
++ * @param buf physical address value
++ * @return virtual address pointer
++ */
++extern void *sdma_phys_to_virt(dma_addr_t buf);
++
++/*!
++ * Configures the BD_INTR bit on a buffer descriptor parameters.
++ *
++ *
++ * @param channel channel number
++ * @param bd_index index of buffer descriptor to set
++ * @param bd_intr flag to set or clear the BD_INTR bit
++ */
++extern void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr);
++
++/*!
++ * Gets the BD_INTR bit on a buffer descriptor.
++ *
++ *
++ * @param channel channel number
++ * @param bd_index index of buffer descriptor to set
++ *
++ * @return returns the BD_INTR bit status
++ */
++extern int mxc_dma_get_bd_intr(int channel, int bd_index);
++
++/*!
++ * Stop the current transfer
++ *
++ * @param channel channel number
++ * @param buffer_number number of buffers (beginning with 0),
++ * whose done bits should be reset to 0
++ */
++extern int mxc_dma_reset(int channel, int buffer_number);
++
++/*!
++ * This functions Returns the SDMA paramaters associated for a module
++ *
++ * @param channel_id the ID of the module requesting DMA
++ * @return returns the sdma parameters structure for the device
++ */
++extern mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
++ channel_id);
++
++/*!
++ * This functions marks the SDMA channels that are statically allocated
++ *
++ * @param chnl the channel array used to store channel information
++ */
++extern void mxc_get_static_channels(mxc_dma_channel_t * chnl);
++
++/*!
++ * Initializes SDMA driver
++ */
++extern int __init sdma_init(void);
++
++extern void mxc_sdma_get_script_info(sdma_script_start_addrs *sdma_script_addr);
++
++#define DEFAULT_ERR 1
++
++#endif
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/spba.h linux.35.new/arch/arm/plat-mxc/include/mach/spba.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/spba.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/spba.h 2010-12-03 09:51:55.376350318 +0100
+@@ -0,0 +1,66 @@
++
++/*
++ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/*!
++ * @defgroup SPBA Shared Peripheral Bus Arbiter (SPBA)
++ * @ingroup MSL_MX31 MSL_MX35 MSL_MX37 MSL_MX51 MSL_MXC91321
++ */
++
++/*!
++ * @file arch-mxc/spba.h
++ * @brief This file contains the Shared Peripheral Bus Arbiter (spba) API.
++ *
++ * @ingroup SPBA
++ */
++
++#ifndef __ASM_ARCH_MXC_SPBA_H__
++#define __ASM_ARCH_MXC_SPBA_H__
++
++#ifdef __KERNEL__
++
++#define MXC_SPBA_RAR_MASK 0x7
++
++/*!
++ * Defines three SPBA masters: A - ARM, C - SDMA (no master B for MX31)
++ */
++enum spba_masters {
++ SPBA_MASTER_A = 1,
++ SPBA_MASTER_B = 2,
++ SPBA_MASTER_C = 4,
++};
++
++/*!
++ * This function allows the three masters (A, B, C) to take ownership of a
++ * shared peripheral.
++ *
++ * @param mod specified module as defined in \b enum \b #spba_module
++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
++ *
++ * @return 0 if successful; -1 otherwise.
++ */
++int spba_take_ownership(int mod, int master);
++
++/*!
++ * This function releases the ownership for a shared peripheral.
++ *
++ * @param mod specified module as defined in \b enum \b #spba_module
++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
++ *
++ * @return 0 if successful; -1 otherwise.
++ */
++int spba_rel_ownership(int mod, int master);
++
++#endif /* __KERNEL__ */
++
++#endif /* __ASM_ARCH_MXC_SPBA_H__ */
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/ssi.h linux.35.new/arch/arm/plat-mxc/include/mach/ssi.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/ssi.h 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/include/mach/ssi.h 2010-12-03 09:51:55.380349316 +0100
+@@ -10,6 +10,9 @@
+ unsigned int flags;
+ #define IMX_SSI_DMA (1 << 0)
+ #define IMX_SSI_USE_AC97 (1 << 1)
++#define IMX_SSI_NET (1 << 2)
++#define IMX_SSI_SYN (1 << 3)
++#define IMX_SSI_USE_I2S_SLAVE (1 << 4)
+ void (*ac97_reset) (struct snd_ac97 *ac97);
+ void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+ };
+diff -urN linux.35.old/arch/arm/plat-mxc/include/mach/ssi_port.h linux.35.new/arch/arm/plat-mxc/include/mach/ssi_port.h
+--- linux.35.old/arch/arm/plat-mxc/include/mach/ssi_port.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/include/mach/ssi_port.h 2010-12-03 09:51:55.380349316 +0100
+@@ -0,0 +1,31 @@
++/*
++ * include/asm-arm/arch-mxc/ssi_port.h
++ *
++ * Copyright (C) 2008 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the:
++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
++ */
++
++struct mxc_ssi_port {
++ int num;
++ struct module *owner;
++ struct platform_device *parent;
++ struct resource *res;
++ struct clk *ssi_clk;
++ int in_use;
++};
++
++extern int mxc_ssi_request_port(int num, struct platform_device *parent,
++ struct mxc_ssi_port **ssi_port);
++extern void mxc_ssi_release_port(struct mxc_ssi_port *ssi_port);
+diff -urN linux.35.old/arch/arm/plat-mxc/iomux-v3.c linux.35.new/arch/arm/plat-mxc/iomux-v3.c
+--- linux.35.old/arch/arm/plat-mxc/iomux-v3.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/iomux-v3.c 2010-12-03 09:51:55.380349316 +0100
+@@ -30,12 +30,34 @@
+ #include <mach/iomux-v3.h>
+
+ static void __iomem *base;
++#ifdef CONFIG_ARCH_MX25
++#define NUM_PADS 0x228
++#else
++#define NUM_PADS 0x200
++#endif
++
++static unsigned long iomux_v3_pad_alloc_map[NUM_PADS / BITS_PER_LONG];
++
++static inline int mxc_iomux_v3_pad_offset(struct pad_desc *pad)
++{
++ int pad_ofs;
++ if (cpu_is_mx25())
++ pad_ofs = pad->mux_ctrl_ofs;
++ else
++ pad_ofs = pad->pad_ctrl_ofs;
++ BUG_ON((pad_ofs >> 7) >= ARRAY_SIZE(iomux_v3_pad_alloc_map));
++ return pad_ofs;
++}
+
+ /*
+ * setups a single pad in the iomuxer
+ */
+ int mxc_iomux_v3_setup_pad(struct pad_desc *pad)
+ {
++ unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad);
++
++ if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map))
++ return -EBUSY;
+ if (pad->mux_ctrl_ofs)
+ __raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs);
+
+@@ -65,6 +87,26 @@
+ }
+ EXPORT_SYMBOL(mxc_iomux_v3_setup_multiple_pads);
+
++void mxc_iomux_v3_release_pad(struct pad_desc *pad)
++{
++ unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad);
++
++ clear_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map);
++}
++EXPORT_SYMBOL(mxc_iomux_v3_release_pad);
++
++void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count)
++{
++ struct pad_desc *p = pad_list;
++ int i;
++
++ for (i = 0; i < count; i++) {
++ mxc_iomux_v3_release_pad(p);
++ p++;
++ }
++}
++EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads);
++
+ void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
+ {
+ base = iomux_v3_base;
+diff -urN linux.35.old/arch/arm/plat-mxc/Kconfig linux.35.new/arch/arm/plat-mxc/Kconfig
+--- linux.35.old/arch/arm/plat-mxc/Kconfig 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/Kconfig 2010-12-03 09:51:55.380349316 +0100
+@@ -1,5 +1,7 @@
+ if ARCH_MXC
+
++source "arch/arm/plat-mxc/devices/Kconfig"
++
+ menu "Freescale MXC Implementations"
+
+ choice
+@@ -25,6 +27,7 @@
+ select CPU_ARM926T
+ select ARCH_MXC_IOMUX_V3
+ select HAVE_FB_IMX
++ select ARCH_MXC_AUDMUX_V2
+ help
+ This enables support for systems based on the Freescale i.MX25 family
+
+@@ -99,4 +102,14 @@
+ config ARCH_MXC_AUDMUX_V2
+ bool
+
++config MXC_SSI_PORTS
++ bool "Generic SSI Layer"
++ depends on ARCH_MXC
++ help
++ This option enables the generic SSI layer that makes it possible to
++ write drivers that decide at runtime which SSI port to use.
++ Since the SSI signals must be routed through the AUDMUX, there is no
++ reason to hardwire any driver that utilizes the SSI interface to a specific
++ SSI port.
++
+ endif
+diff -urN linux.35.old/arch/arm/plat-mxc/Makefile linux.35.new/arch/arm/plat-mxc/Makefile
+--- linux.35.old/arch/arm/plat-mxc/Makefile 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/arch/arm/plat-mxc/Makefile 2010-12-03 09:51:55.380349316 +0100
+@@ -13,6 +13,7 @@
+ obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
+ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+ obj-$(CONFIG_MXC_PWM) += pwm.o
++obj-$(CONFIG_MXC_SDMA_API) += sdma/
+ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
+ obj-$(CONFIG_MXC_ULPI) += ulpi.o
+ obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
+@@ -21,3 +22,8 @@
+ obj-y += ssi-fiq.o
+ obj-y += ssi-fiq-ksym.o
+ endif
++
++obj-y += devices/
++
++mxc-ssi-ports-objs := ssi.o
++obj-$(CONFIG_MXC_SSI_PORTS) += mxc-ssi-ports.o
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/dma_sdma.c linux.35.new/arch/arm/plat-mxc/sdma/dma_sdma.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/dma_sdma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/dma_sdma.c 2010-12-03 09:51:55.384181534 +0100
+@@ -0,0 +1,763 @@
++/*
++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/*!
++ * @file plat-mxc/sdma/dma_sdma.c
++ * @brief Front-end to the DMA handling. This handles the allocation/freeing
++ * of DMA channels, and provides a unified interface to the machines
++ * DMA facilities. This file contains functions for Smart DMA.
++ *
++ * @ingroup SDMA
++ */
++
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <mach/dma.h>
++#include <mach/hardware.h>
++#include <linux/slab.h>
++
++#include <epm.h>
++#include "sdma.h"
++
++#ifdef CONFIG_MXC_SDMA_API
++
++static mxc_dma_channel_t mxc_sdma_channels[MAX_DMA_CHANNELS];
++static mxc_dma_channel_private_t mxc_sdma_private[MAX_DMA_CHANNELS];
++
++/*!
++ * Tasket to handle processing the channel buffers
++ *
++ * @param arg channel id
++ */
++static void mxc_sdma_channeltasklet(unsigned long arg)
++{
++ dma_request_t req;
++ mxc_sdma_channel_params_t *chnl;
++ dma_channel_params *chnl_param;
++ mxc_dma_channel_t *chnl_info;
++ mxc_dma_channel_private_t *data_priv;
++ int ret;
++
++ chnl_info = &mxc_sdma_channels[arg];
++ data_priv = chnl_info->private;
++ chnl = mxc_sdma_get_channel_params(chnl_info->channel);
++ BUG_ON(chnl == NULL);
++ chnl_param = &chnl->chnl_params;
++
++ ret = mxc_dma_get_config(arg, &req, data_priv->buf_tail);
++ if (ret) {
++ DBG(0, "%s: Failed to get config for channel %ld buffer %u: %d\n",
++ __FUNCTION__, arg, data_priv->buf_tail, ret);
++ return;
++ }
++
++ DBG(0, "%s: dma_request %u: src: %08x dst: %08x done=%d cont=%d wrap=%d\n",
++ __FUNCTION__, data_priv->buf_tail, req.sourceAddr, req.destAddr,
++ req.bd_done, req.bd_cont, req.bd_wrap);
++
++ while (!req.bd_done) {
++ int error = MXC_DMA_DONE;
++ int bd_intr = mxc_dma_get_bd_intr(arg, data_priv->buf_tail);
++
++ if (bd_intr < 0) {
++ DBG(0, "%s: Failed to get bd_intr for channel %ld buffer %u: %d\n",
++ __FUNCTION__, arg, data_priv->buf_tail, ret);
++ return;
++ }
++
++ DBG(0, "%s: desc %u of %u\n", __FUNCTION__,
++ data_priv->buf_tail, chnl_param->bd_number);
++
++ if (!data_priv->circular || req.bd_error) {
++ DBG(0, "%s: Deactivating channel\n", __FUNCTION__);
++ chnl_info->active = 0;
++ }
++ if (req.bd_error) {
++ error = MXC_DMA_TRANSFER_ERROR;
++ }
++
++ DBG(0, "%s: bd_intr=%d\n", __FUNCTION__, bd_intr);
++ if (bd_intr) {
++ chnl_info->cb_fn(chnl_info->cb_args, error,
++ req.count);
++ }
++
++ if (data_priv->buf_tail == chnl_info->curr_buf) {
++ break;
++ }
++
++ ret = mxc_dma_set_config(arg, &req, data_priv->buf_tail);
++ if (ret) {
++ DBG(0, "%s: Failed to set config for channel %ld buffer %u: %d\n",
++ __FUNCTION__, arg, data_priv->buf_tail, ret);
++ return;
++ }
++
++ data_priv->buf_tail++;
++ if (data_priv->buf_tail >= chnl_param->bd_number || req.bd_wrap)
++ data_priv->buf_tail = 0;
++ memset(&req, 0, sizeof(req));
++ ret = mxc_dma_get_config(arg, &req, data_priv->buf_tail);
++ if (ret) {
++ DBG(0, "%s: Failed to get config for channel %ld buffer %u: %d\n",
++ __FUNCTION__, arg, data_priv->buf_tail, ret);
++ return;
++ }
++ DBG(0, "%s: dma_request %u: src: %08x dst: %08x done=%d cont=%d wrap=%d\n",
++ __FUNCTION__, data_priv->buf_tail, req.sourceAddr, req.destAddr,
++ req.bd_done, req.bd_cont, req.bd_wrap);
++ }
++}
++
++/*!
++ * This function is generally called by the driver at open time.
++ * The DMA driver would do any initialization steps that is required
++ * to get the channel ready for data transfer.
++ *
++ * @param channel_id a pre-defined id. The peripheral driver would specify
++ * the id associated with its peripheral. This would be
++ * used by the DMA driver to identify the peripheral
++ * requesting DMA and do the necessary setup on the
++ * channel associated with the particular peripheral.
++ * The DMA driver could use static or dynamic DMA channel
++ * allocation.
++ * @param dev_name module name or device name
++ * @return returns a negative number on error if request for a DMA channel did not
++ * succeed, returns the channel number to be used on success.
++ */
++int mxc_dma_request_ext(mxc_dma_device_t channel_id, char *dev_name,
++ struct dma_channel_info *info)
++{
++ mxc_sdma_channel_params_t *chnl;
++ mxc_dma_channel_private_t *data_priv;
++ int ret, i, channel_num;
++ mxc_sdma_channel_ext_params_t *p;
++
++ chnl = mxc_sdma_get_channel_params(channel_id);
++ if (chnl == NULL) {
++ return -EINVAL;
++ }
++
++ if (info) {
++ if (!chnl->chnl_params.ext)
++ return -EINVAL;
++ p = (mxc_sdma_channel_ext_params_t *)chnl;
++ memcpy(&p->chnl_ext_params.info, info, sizeof(info));
++ }
++
++ /* Enable the SDMA clock */
++ clk_enable(mxc_sdma_clk);
++
++ channel_num = chnl->channel_num;
++ if (chnl->channel_num == MXC_DMA_DYNAMIC_CHANNEL) {
++ ret = -EBUSY;
++ /* Get the first free channel */
++ for (i = MAX_DMA_CHANNELS - 1; i > 0; i--) {
++ /* See if channel is available */
++ if (!mxc_sdma_channels[i].dynamic ||
++ mxc_sdma_channels[i].lock) {
++ continue;
++ }
++ channel_num = i;
++ /* Check to see if we can get this channel */
++ ret = mxc_request_dma(&channel_num, dev_name);
++ if (ret == 0) {
++ break;
++ } else {
++ continue;
++ }
++ }
++ if (ret != 0) {
++ /* No free channel */
++ goto err_ret;
++ }
++ } else {
++ if (mxc_sdma_channels[chnl->channel_num].lock) {
++ ret = -EBUSY;
++ goto err_ret;
++ }
++ ret = mxc_request_dma(&channel_num, dev_name);
++ if (ret != 0) {
++ goto err_ret;
++ }
++ }
++
++ ret = mxc_dma_setup_channel(channel_num, &chnl->chnl_params);
++ if (ret != 0) {
++ DBG(0, "%s: Failed to setup DMA channel %d: %d\n", __FUNCTION__,
++ channel_num, ret);
++ goto err_free;
++ }
++ if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) {
++ ret = mxc_dma_set_channel_priority(channel_num,
++ chnl->chnl_priority);
++ if (ret != 0) {
++ pr_info("Failed to set channel prority, continuing with the existing priority\n");
++ }
++ }
++ mxc_sdma_channels[channel_num].lock = 1;
++ if ((chnl->chnl_params.transfer_type == per_2_emi) ||
++ (chnl->chnl_params.transfer_type == dsp_2_emi)) {
++ mxc_sdma_channels[channel_num].mode =
++ MXC_DMA_MODE_READ;
++ } else {
++ mxc_sdma_channels[channel_num].mode =
++ MXC_DMA_MODE_WRITE;
++ }
++ mxc_sdma_channels[channel_num].channel = channel_id;
++ data_priv = mxc_sdma_channels[channel_num].private;
++ tasklet_init(&data_priv->chnl_tasklet,
++ mxc_sdma_channeltasklet, channel_num);
++ if ((channel_id == MXC_DMA_ATA_RX) ||
++ (channel_id == MXC_DMA_ATA_TX)) {
++ data_priv->intr_after_every_bd = 0;
++ } else {
++ data_priv->intr_after_every_bd = 1;
++ }
++ return channel_num;
++
++err_free:
++ mxc_free_dma(channel_num);
++err_ret:
++ clk_disable(mxc_sdma_clk);
++ return ret;
++}
++
++/*!
++ * This function is generally called by the driver at close time. The DMA
++ * driver would do any cleanup associated with this channel.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++int mxc_dma_free(int channel_num)
++{
++ mxc_dma_channel_private_t *data_priv;
++
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
++ return -EINVAL;
++ }
++
++ if (!mxc_sdma_channels[channel_num].lock) {
++ return -EINVAL;
++ }
++
++ mxc_free_dma(channel_num);
++
++ /* Disable the SDMA clock */
++ clk_disable(mxc_sdma_clk);
++
++ mxc_sdma_channels[channel_num].lock = 0;
++ mxc_sdma_channels[channel_num].active = 0;
++ mxc_sdma_channels[channel_num].curr_buf = 0;
++ data_priv = mxc_sdma_channels[channel_num].private;
++ data_priv->buf_tail = 0;
++ tasklet_kill(&data_priv->chnl_tasklet);
++
++ return 0;
++}
++
++/*!
++ * Callback function called from the SDMA Interrupt routine
++ *
++ * @param arg driver specific argument that was registered
++ */
++static void mxc_dma_chnl_callback(void *arg)
++{
++ int channel;
++ mxc_dma_channel_private_t *data_priv;
++
++ channel = (int)arg;
++ DBG(0, "%s: channel %d\n", __FUNCTION__, channel);
++ data_priv = mxc_sdma_channels[channel].private;
++ /* Process the buffers in a tasklet */
++ tasklet_schedule(&data_priv->chnl_tasklet);
++}
++
++/*!
++ * This function would just configure the buffers specified by the user into
++ * dma channel. The caller must call mxc_dma_enable to start this transfer.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param dma_buf an array of physical addresses to the user defined
++ * buffers. The caller must guarantee the dma_buf is
++ * available until the transfer is completed.
++ * @param num_buf number of buffers in the array
++ * @param mode specifies whether this is READ or WRITE operation
++ * @return This function returns a negative number on error if buffer could not be
++ * added with DMA for transfer. On Success, it returns 0
++ */
++int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t *dma_buf,
++ int num_buf, mxc_dma_mode_t mode)
++{
++ int ret, i, prev_buf;
++ mxc_dma_channel_t *chnl_info;
++ mxc_dma_channel_private_t *data_priv;
++ mxc_sdma_channel_params_t *chnl;
++ dma_channel_params chnl_param;
++ dma_request_t req;
++
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0))
++ return -EINVAL;
++
++ if (num_buf <= 0)
++ return -EINVAL;
++
++ chnl_info = &mxc_sdma_channels[channel_num];
++ data_priv = chnl_info->private;
++ if (chnl_info->lock != 1)
++ return -ENODEV;
++
++ /* Check to see if all buffers are taken */
++ if (chnl_info->active)
++ return -EBUSY;
++
++ chnl = mxc_sdma_get_channel_params(chnl_info->channel);
++ chnl_param = chnl->chnl_params;
++
++ /* Re-setup the SDMA channel if the transfer direction or
++ * the number of assigned BDs is changed
++ */
++ if (chnl_param.peripheral_type != MEMORY &&
++ mode != chnl_info->mode) {
++
++ if (chnl_param.bd_number != num_buf)
++ DBG(0, "%s: Changing number of BDs for channel %u from %u to %u\n", __FUNCTION__,
++ channel_num, chnl_param.bd_number, num_buf);
++
++ chnl_param.bd_number = num_buf;
++ if (chnl_param.peripheral_type == DSP) {
++ if (mode == MXC_DMA_MODE_READ)
++ chnl_param.transfer_type = dsp_2_emi;
++ else
++ chnl_param.transfer_type = emi_2_dsp;
++ } else if (chnl_param.peripheral_type == FIFO_MEMORY) {
++ if (mode == MXC_DMA_MODE_READ)
++ chnl_param.per_address =
++ MXC_FIFO_MEM_SRC_FIXED;
++ else
++ chnl_param.per_address =
++ MXC_FIFO_MEM_DEST_FIXED;
++ } else {
++ if (mode == MXC_DMA_MODE_READ)
++ chnl_param.transfer_type = per_2_emi;
++ else
++ chnl_param.transfer_type = emi_2_per;
++ }
++ chnl_param.callback = mxc_dma_chnl_callback;
++ chnl_param.arg = (void *)channel_num;
++ ret = mxc_dma_setup_channel(channel_num, &chnl_param);
++ if (ret != 0)
++ return ret;
++
++ if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) {
++ ret = mxc_dma_set_channel_priority(channel_num,
++ chnl->chnl_priority);
++ if (ret != 0) {
++ pr_info("Failed to set channel prority, continuing with the existing priority\n");
++ }
++ }
++ chnl_info->mode = mode;
++ }
++
++ for (i = 0; i < num_buf; i++, dma_buf++) {
++ memset(&req, 0, sizeof(req));
++ /* Check to see if all buffers are taken */
++ if (chnl_info->active) {
++ DBG(0, "%s: bd %u is already active\n",
++ __FUNCTION__, i);
++ break;
++ }
++ req.destAddr = dma_buf->dst_addr;
++ req.sourceAddr = dma_buf->src_addr;
++ if (chnl_param.peripheral_type == ASRC)
++ req.count = dma_buf->num_of_bytes / 4;
++ else
++ req.count = dma_buf->num_of_bytes;
++ req.bd_cont = 1;
++ if (data_priv->circular && i == num_buf - 1) {
++ DBG(0, "%s: Setting bd_wrap for desc[%d/%d]\n",
++ __FUNCTION__, i, num_buf);
++ req.bd_wrap = 1;
++ }
++ ret = mxc_dma_set_config(channel_num, &req,
++ chnl_info->curr_buf);
++ if (ret != 0) {
++ DBG(0, "%s: Failed to configure DMA: %d\n",
++ __FUNCTION__, ret);
++ return ret;
++ }
++ if (data_priv->intr_after_every_bd ||
++ (i == num_buf - 1)) {
++ mxc_dma_set_bd_intr(channel_num,
++ chnl_info->curr_buf, 1);
++ } else {
++ mxc_dma_set_bd_intr(channel_num,
++ chnl_info->curr_buf, 0);
++ }
++
++ prev_buf = chnl_info->curr_buf;
++ chnl_info->curr_buf++;
++ if (chnl_info->curr_buf >= chnl_param.bd_number) {
++ chnl_info->curr_buf = 0;
++ }
++ if (chnl_info->curr_buf == data_priv->buf_tail) {
++ if (!(data_priv->intr_after_every_bd) &&
++ (i != num_buf - 1)) {
++ /*
++ * Set the BD_INTR flag on the last BD that
++ * was queued
++ */
++ mxc_dma_set_bd_intr(channel_num, prev_buf, 1);
++ }
++ chnl_info->active = 1;
++ }
++ }
++
++ if (i == 0) {
++ return -EBUSY;
++ }
++ return 0;
++}
++
++/*!
++ * This function would just configure the scatterlist specified by the
++ * user into dma channel. This is a slight variation of mxc_dma_config(),
++ * it is provided for the convenience of drivers that have a scatterlist
++ * passed into them. It is the calling driver's responsibility to have the
++ * correct physical address filled in the "dma_address" field of the
++ * scatterlist.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param sg a scatterlist of buffers. The caller must guarantee
++ * the dma_buf is available until the transfer is
++ * completed.
++ * @param num_buf number of buffers in the array
++ * @param num_of_bytes total number of bytes to transfer. If set to 0, this
++ * would imply to use the length field of the scatterlist
++ * for each DMA transfer. Else it would calculate the size
++ * for each DMA transfer.
++ * @param mode specifies whether this is READ or WRITE operation
++ * @return This function returns a negative number on error if buffer could not
++ * be added with DMA for transfer. On Success, it returns 0
++ */
++int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
++ int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
++{
++ int ret, i;
++ mxc_dma_requestbuf_t *dma_buf;
++ gfp_t gfp_flags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
++ mxc_dma_channel_t *chnl_info;
++ mxc_dma_channel_private_t *data_priv;
++
++ DBG(0, "%s: chan %d %u buffers with %u bytes\n", __FUNCTION__,
++ channel_num, num_buf, num_of_bytes);
++
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
++ return -EINVAL;
++ }
++
++ if (!mxc_sdma_channels[channel_num].lock) {
++ return -EINVAL;
++ }
++
++ dma_buf = kmalloc(num_buf * sizeof(mxc_dma_requestbuf_t),
++ gfp_flags);
++ if (dma_buf == NULL) {
++ return -ENOMEM;
++ }
++
++ chnl_info = &mxc_sdma_channels[channel_num];
++ data_priv = chnl_info->private;
++ data_priv->intr_after_every_bd = 1;
++ data_priv->circular = 1;
++
++ for (i = 0; i < num_buf; i++) {
++ if (mode == MXC_DMA_MODE_READ) {
++ dma_buf[i].dst_addr = sg->dma_address;
++ dma_buf[i].src_addr = DMA_ADDR_INVALID;
++ } else {
++ dma_buf[i].dst_addr = DMA_ADDR_INVALID;
++ dma_buf[i].src_addr = sg->dma_address;
++ }
++
++ if ((num_of_bytes > sg->length) || (num_of_bytes == 0)) {
++ dma_buf[i].num_of_bytes = sg->length;
++ } else {
++ dma_buf[i].num_of_bytes = num_of_bytes;
++ }
++ sg = sg_next(sg);
++ if (num_of_bytes != 0)
++ num_of_bytes -= dma_buf[i].num_of_bytes;
++ DBG(0, "%s: desc[%d/%d] src: %08x dst: %08x len: %08x\n",
++ __FUNCTION__, i, num_buf, dma_buf[i].src_addr, dma_buf[i].dst_addr,
++ dma_buf[i].num_of_bytes);
++ }
++
++ ret = mxc_dma_config(channel_num, dma_buf, num_buf, mode);
++ kfree(dma_buf);
++ return ret;
++}
++
++/*!
++ * This function is provided if the driver would like to set/change its
++ * callback function.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @param callback a callback function to provide notification on transfer
++ * completion, user could specify NULL if he does not wish
++ * to be notified
++ * @param arg an argument that gets passed in to the callback
++ * function, used by the user to do any driver specific
++ * operations.
++ * @return this function returns a negative number on error if the callback
++ * could not be set for the channel or 0 on success
++ */
++int mxc_dma_callback_set(int channel_num,
++ mxc_dma_callback_t callback, void *arg)
++{
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
++ return -EINVAL;
++ }
++
++ if (!mxc_sdma_channels[channel_num].lock) {
++ return -EINVAL;
++ }
++
++ mxc_sdma_channels[channel_num].cb_fn = callback;
++ mxc_sdma_channels[channel_num].cb_args = arg;
++
++ mxc_dma_set_callback(channel_num, mxc_dma_chnl_callback,
++ (void *)channel_num);
++
++ return 0;
++}
++
++/*!
++ * This stops the DMA channel and any ongoing transfers. Subsequent use of
++ * mxc_dma_enable() will restart the channel and restart the transfer.
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++int mxc_dma_disable(int channel_num)
++{
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
++ return -EINVAL;
++ }
++
++ if (!mxc_sdma_channels[channel_num].lock) {
++ return -EINVAL;
++ }
++
++ mxc_dma_stop(channel_num);
++ return 0;
++}
++
++/*!
++ * This starts DMA transfer. Or it restarts DMA on a stopped channel
++ * previously stopped with mxc_dma_disable().
++ *
++ * @param channel_num the channel number returned at request time. This
++ * would be used by the DMA driver to identify the calling
++ * driver and do the necessary cleanup on the channel
++ * associated with the particular peripheral
++ * @return returns a negative number on error or 0 on success
++ */
++int mxc_dma_enable(int channel_num)
++{
++ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
++ return -EINVAL;
++ }
++
++ if (!mxc_sdma_channels[channel_num].lock) {
++ return -EINVAL;
++ }
++
++ mxc_dma_start(channel_num);
++ return 0;
++}
++
++/*!
++ * Initializes dma structure with dma_operations
++ *
++ * @param dma dma structure
++ * @return returns 0 on success
++ */
++static int __init mxc_dma_init(void)
++{
++ int i;
++
++ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
++ mxc_sdma_channels[i].active = 0;
++ mxc_sdma_channels[i].lock = 0;
++ mxc_sdma_channels[i].curr_buf = 0;
++ mxc_sdma_channels[i].dynamic = 1;
++ mxc_sdma_private[i].buf_tail = 0;
++ mxc_sdma_channels[i].private = &mxc_sdma_private[i];
++ }
++ /*
++ * Make statically allocated channels unavailable for dynamic channel
++ * requests
++ */
++ mxc_get_static_channels(mxc_sdma_channels);
++
++ return 0;
++}
++
++arch_initcall(mxc_dma_init);
++
++#else
++int mxc_request_dma(int *channel, const char *devicename)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_setup_channel(int channel, dma_channel_params * p)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_start(int channel)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_stop(int channel)
++{
++ return -ENODEV;
++}
++
++void mxc_free_dma(int channel)
++{
++}
++
++void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg)
++{
++}
++
++void *sdma_malloc(size_t size)
++{
++ return NULL;
++}
++
++void sdma_free(void *buf)
++{
++}
++
++void *sdma_phys_to_virt(dma_addr_t buf)
++{
++ return NULL;
++}
++
++dma_addr_t sdma_virt_to_phys(void *buf)
++{
++ return DMA_ADDR_INVALID;
++}
++
++int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_free(int channel_num)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf,
++ int num_buf, mxc_dma_mode_t mode)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
++ int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
++ void *arg)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_disable(int channel_num)
++{
++ return -ENODEV;
++}
++
++int mxc_dma_enable(int channel_num)
++{
++ return -ENODEV;
++}
++
++EXPORT_SYMBOL(mxc_request_dma);
++EXPORT_SYMBOL(mxc_dma_setup_channel);
++EXPORT_SYMBOL(mxc_dma_set_channel_priority);
++EXPORT_SYMBOL(mxc_dma_set_config);
++EXPORT_SYMBOL(mxc_dma_get_config);
++EXPORT_SYMBOL(mxc_dma_start);
++EXPORT_SYMBOL(mxc_dma_stop);
++EXPORT_SYMBOL(mxc_free_dma);
++EXPORT_SYMBOL(mxc_dma_set_callback);
++EXPORT_SYMBOL(sdma_malloc);
++EXPORT_SYMBOL(sdma_free);
++EXPORT_SYMBOL(sdma_phys_to_virt);
++EXPORT_SYMBOL(sdma_virt_to_phys);
++
++#endif
++
++EXPORT_SYMBOL(mxc_dma_request_ext);
++EXPORT_SYMBOL(mxc_dma_free);
++EXPORT_SYMBOL(mxc_dma_config);
++EXPORT_SYMBOL(mxc_dma_sg_config);
++EXPORT_SYMBOL(mxc_dma_callback_set);
++EXPORT_SYMBOL(mxc_dma_disable);
++EXPORT_SYMBOL(mxc_dma_enable);
++
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_DESCRIPTION("MXC Linux SDMA API");
++MODULE_LICENSE("GPL");
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/epm.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/epm.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/epm.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/epm.h 2010-12-03 09:51:55.384181534 +0100
+@@ -0,0 +1,254 @@
++/*
++ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#ifndef __ASM_ARCH_MXC_SDMA_REGS_H__
++#define __ASM_ARCH_MXC_SDMA_REGS_H__
++
++#ifdef DEBUG
++#ifdef CONFIG_MACH_TX25
++extern int tx25_debug;
++#define dbg_lvl(n) ((n) < tx25_debug)
++#elif defined(CONFIG_MACH_TX51)
++extern int tx51_debug;
++#define dbg_lvl(n) ((n) < tx51_debug)
++#else
++#error No debug support for this machine
++#endif
++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0)
++#else
++#define dbg_lvl(n) 0
++#define DBG(lvl, fmt...) do { } while (0)
++#endif
++
++#ifdef __KERNEL__
++#include <linux/kernel.h>
++#include <linux/bug.h>
++#include <linux/io.h>
++#include <asm/memory.h>
++#endif
++
++#include <linux/compiler.h>
++#include <mach/hardware.h>
++
++/* SDMA Reg definition */
++extern void __iomem *sdma_base_addr;
++#define SDMA_BASE_IO_ADDR sdma_base_addr
++
++#ifdef DEBUG
++#define __sdma_pa(a) ((a) - SDMA_BASE_IO_ADDR + SDMA_BASE_ADDR)
++
++static inline u32 iapi_raw_readl(void __iomem *addr,
++ const char *name, const char *fn)
++{
++ u32 val;
++
++ DBG(1, "%s: Reading %s[%08lx]\n", fn,
++ name, __sdma_pa(addr));
++ val = __raw_readl(addr);
++ DBG(0, "%s: Read %08x from %s[%08lx]\n", fn,
++ val, name, __sdma_pa(addr));
++ return val;
++}
++
++static inline void iapi_raw_writel(u32 val, void __iomem *addr,
++ const char *name, const char *fn)
++{
++ DBG(0, "%s: Writing %08x to %s[%08lx]\n", fn,
++ val, name, __sdma_pa(addr));
++ __raw_writel(val, addr);
++
++}
++
++#undef __raw_writel
++#undef __raw_readl
++
++#define __raw_readl(a) iapi_raw_readl(a, #a, __func__)
++#define __raw_writel(v, a) iapi_raw_writel(v, a, #a, __func__)
++#endif
++
++#define __REG32(base, offs) ((base) + (offs))
++#define __REG_ARRAY(base, offs, num, index) ({ \
++ BUG_ON((unsigned int)(index) >= (num)); \
++ __REG32(base, (offs) + ((index) << 2)); \
++})
++
++#define SDMA_H_C0PTR __REG32(SDMA_BASE_IO_ADDR, 0x000)
++#define SDMA_H_INTR __REG32(SDMA_BASE_IO_ADDR, 0x004)
++#define SDMA_H_STATSTOP __REG32(SDMA_BASE_IO_ADDR, 0x008)
++#define SDMA_H_START __REG32(SDMA_BASE_IO_ADDR, 0x00C)
++#define SDMA_H_EVTOVR __REG32(SDMA_BASE_IO_ADDR, 0x010)
++#define SDMA_H_DSPOVR __REG32(SDMA_BASE_IO_ADDR, 0x014)
++#define SDMA_H_HOSTOVR __REG32(SDMA_BASE_IO_ADDR, 0x018)
++#define SDMA_H_EVTPEND __REG32(SDMA_BASE_IO_ADDR, 0x01C)
++#define SDMA_H_DSPENBL __REG32(SDMA_BASE_IO_ADDR, 0x020)
++#define SDMA_H_RESET __REG32(SDMA_BASE_IO_ADDR, 0x024)
++#define SDMA_H_EVTERR __REG32(SDMA_BASE_IO_ADDR, 0x028)
++#define SDMA_H_INTRMSK __REG32(SDMA_BASE_IO_ADDR, 0x02C)
++#define SDMA_H_PSW __REG32(SDMA_BASE_IO_ADDR, 0x030)
++#define SDMA_H_EVTERRDBG __REG32(SDMA_BASE_IO_ADDR, 0x034)
++#define SDMA_H_CONFIG __REG32(SDMA_BASE_IO_ADDR, 0x038)
++#define SDMA_SDMA_LOCK __REG32(SDMA_BASE_IO_ADDR, 0x03C)
++#define SDMA_ONCE_ENB __REG32(SDMA_BASE_IO_ADDR, 0x040)
++#define SDMA_ONCE_DATA __REG32(SDMA_BASE_IO_ADDR, 0x044)
++#define SDMA_ONCE_INSTR __REG32(SDMA_BASE_IO_ADDR, 0x048)
++#define SDMA_ONCE_STAT __REG32(SDMA_BASE_IO_ADDR, 0x04C)
++#define SDMA_ONCE_CMD __REG32(SDMA_BASE_IO_ADDR, 0x050)
++#define SDMA_EVT_MIRROR __REG32(SDMA_BASE_IO_ADDR, 0x054)
++#define SDMA_ILLINSTADDR __REG32(SDMA_BASE_IO_ADDR, 0x058)
++#define SDMA_CHN0ADDR __REG32(SDMA_BASE_IO_ADDR, 0x05C)
++#define SDMA_ONCE_RTB __REG32(SDMA_BASE_IO_ADDR, 0x060)
++#define SDMA_XTRIG_CONF1 __REG32(SDMA_BASE_IO_ADDR, 0x070)
++#define SDMA_XTRIG_CONF2 __REG32(SDMA_BASE_IO_ADDR, 0x074)
++
++#ifdef SDMA_V2
++#define SDMA_CHNENBL(i) __REG_ARRAY(SDMA_BASE_IO_ADDR, 0x200, 48, i)
++#define SDMA_CHNENBL_0 __REG32(SDMA_BASE_IO_ADDR, 0x200)
++#define SDMA_CHNENBL_1 __REG32(SDMA_BASE_IO_ADDR, 0x204)
++#define SDMA_CHNENBL_2 __REG32(SDMA_BASE_IO_ADDR, 0x208)
++#define SDMA_CHNENBL_3 __REG32(SDMA_BASE_IO_ADDR, 0x20C)
++#define SDMA_CHNENBL_4 __REG32(SDMA_BASE_IO_ADDR, 0x210)
++#define SDMA_CHNENBL_5 __REG32(SDMA_BASE_IO_ADDR, 0x214)
++#define SDMA_CHNENBL_6 __REG32(SDMA_BASE_IO_ADDR, 0x218)
++#define SDMA_CHNENBL_7 __REG32(SDMA_BASE_IO_ADDR, 0x21C)
++#define SDMA_CHNENBL_8 __REG32(SDMA_BASE_IO_ADDR, 0x220)
++#define SDMA_CHNENBL_9 __REG32(SDMA_BASE_IO_ADDR, 0x224)
++#define SDMA_CHNENBL_10 __REG32(SDMA_BASE_IO_ADDR, 0x228)
++#define SDMA_CHNENBL_11 __REG32(SDMA_BASE_IO_ADDR, 0x22C)
++#define SDMA_CHNENBL_12 __REG32(SDMA_BASE_IO_ADDR, 0x230)
++#define SDMA_CHNENBL_13 __REG32(SDMA_BASE_IO_ADDR, 0x234)
++#define SDMA_CHNENBL_14 __REG32(SDMA_BASE_IO_ADDR, 0x238)
++#define SDMA_CHNENBL_15 __REG32(SDMA_BASE_IO_ADDR, 0x23C)
++#define SDMA_CHNENBL_16 __REG32(SDMA_BASE_IO_ADDR, 0x240)
++#define SDMA_CHNENBL_17 __REG32(SDMA_BASE_IO_ADDR, 0x244)
++#define SDMA_CHNENBL_18 __REG32(SDMA_BASE_IO_ADDR, 0x248)
++#define SDMA_CHNENBL_19 __REG32(SDMA_BASE_IO_ADDR, 0x24C)
++#define SDMA_CHNENBL_20 __REG32(SDMA_BASE_IO_ADDR, 0x250)
++#define SDMA_CHNENBL_21 __REG32(SDMA_BASE_IO_ADDR, 0x254)
++#define SDMA_CHNENBL_22 __REG32(SDMA_BASE_IO_ADDR, 0x258)
++#define SDMA_CHNENBL_23 __REG32(SDMA_BASE_IO_ADDR, 0x25C)
++#define SDMA_CHNENBL_24 __REG32(SDMA_BASE_IO_ADDR, 0x260)
++#define SDMA_CHNENBL_25 __REG32(SDMA_BASE_IO_ADDR, 0x264)
++#define SDMA_CHNENBL_26 __REG32(SDMA_BASE_IO_ADDR, 0x268)
++#define SDMA_CHNENBL_27 __REG32(SDMA_BASE_IO_ADDR, 0x26C)
++#define SDMA_CHNENBL_28 __REG32(SDMA_BASE_IO_ADDR, 0x270)
++#define SDMA_CHNENBL_29 __REG32(SDMA_BASE_IO_ADDR, 0x274)
++#define SDMA_CHNENBL_30 __REG32(SDMA_BASE_IO_ADDR, 0x278)
++#define SDMA_CHNENBL_31 __REG32(SDMA_BASE_IO_ADDR, 0x27C)
++#define SDMA_CHNENBL_32 __REG32(SDMA_BASE_IO_ADDR, 0x280)
++#define SDMA_CHNENBL_33 __REG32(SDMA_BASE_IO_ADDR, 0x284)
++#define SDMA_CHNENBL_34 __REG32(SDMA_BASE_IO_ADDR, 0x288)
++#define SDMA_CHNENBL_35 __REG32(SDMA_BASE_IO_ADDR, 0x28C)
++#define SDMA_CHNENBL_36 __REG32(SDMA_BASE_IO_ADDR, 0x290)
++#define SDMA_CHNENBL_37 __REG32(SDMA_BASE_IO_ADDR, 0x294)
++#define SDMA_CHNENBL_38 __REG32(SDMA_BASE_IO_ADDR, 0x298)
++#define SDMA_CHNENBL_39 __REG32(SDMA_BASE_IO_ADDR, 0x29C)
++#define SDMA_CHNENBL_40 __REG32(SDMA_BASE_IO_ADDR, 0x2A0)
++#define SDMA_CHNENBL_41 __REG32(SDMA_BASE_IO_ADDR, 0x2A4)
++#define SDMA_CHNENBL_42 __REG32(SDMA_BASE_IO_ADDR, 0x2A8)
++#define SDMA_CHNENBL_43 __REG32(SDMA_BASE_IO_ADDR, 0x2AC)
++#define SDMA_CHNENBL_44 __REG32(SDMA_BASE_IO_ADDR, 0x2B0)
++#define SDMA_CHNENBL_45 __REG32(SDMA_BASE_IO_ADDR, 0x2B4)
++#define SDMA_CHNENBL_46 __REG32(SDMA_BASE_IO_ADDR, 0x2B8)
++#define SDMA_CHNENBL_47 __REG32(SDMA_BASE_IO_ADDR, 0x2BC)
++
++#define SDMA_ONCE_COUNT __REG32(SDMA_BASE_IO_ADDR, 0x300)
++#define SDMA_ONCE_ECTL __REG32(SDMA_BASE_IO_ADDR, 0x304)
++#define SDMA_ONCE_EAA __REG32(SDMA_BASE_IO_ADDR, 0x308)
++#define SDMA_ONCE_EAB __REG32(SDMA_BASE_IO_ADDR, 0x30C)
++#define SDMA_ONCE_EAM __REG32(SDMA_BASE_IO_ADDR, 0x310)
++#define SDMA_ONCE_ED __REG32(SDMA_BASE_IO_ADDR, 0x314)
++#define SDMA_ONCE_EDM __REG32(SDMA_BASE_IO_ADDR, 0x318)
++#define SDMA_ONCE_PCMATCH __REG32(SDMA_BASE_IO_ADDR, 0x31C)
++
++#else
++
++#define SDMA_CHNENBL(i) __REG_ARRAY(SDMA_BASE_IO_ADDR, 0x80, 32, i)
++#define SDMA_CHNENBL_0 __REG32(SDMA_BASE_IO_ADDR, 0x080)
++#define SDMA_CHNENBL_1 __REG32(SDMA_BASE_IO_ADDR, 0x084)
++#define SDMA_CHNENBL_2 __REG32(SDMA_BASE_IO_ADDR, 0x088)
++#define SDMA_CHNENBL_3 __REG32(SDMA_BASE_IO_ADDR, 0x08C)
++#define SDMA_CHNENBL_4 __REG32(SDMA_BASE_IO_ADDR, 0x090)
++#define SDMA_CHNENBL_5 __REG32(SDMA_BASE_IO_ADDR, 0x094)
++#define SDMA_CHNENBL_6 __REG32(SDMA_BASE_IO_ADDR, 0x098)
++#define SDMA_CHNENBL_7 __REG32(SDMA_BASE_IO_ADDR, 0x09C)
++#define SDMA_CHNENBL_8 __REG32(SDMA_BASE_IO_ADDR, 0x0A0)
++#define SDMA_CHNENBL_9 __REG32(SDMA_BASE_IO_ADDR, 0x0A4)
++#define SDMA_CHNENBL_10 __REG32(SDMA_BASE_IO_ADDR, 0x0A8)
++#define SDMA_CHNENBL_11 __REG32(SDMA_BASE_IO_ADDR, 0x0AC)
++#define SDMA_CHNENBL_12 __REG32(SDMA_BASE_IO_ADDR, 0x0B0)
++#define SDMA_CHNENBL_13 __REG32(SDMA_BASE_IO_ADDR, 0x0B4)
++#define SDMA_CHNENBL_14 __REG32(SDMA_BASE_IO_ADDR, 0x0B8)
++#define SDMA_CHNENBL_15 __REG32(SDMA_BASE_IO_ADDR, 0x0BC)
++#define SDMA_CHNENBL_16 __REG32(SDMA_BASE_IO_ADDR, 0x0C0)
++#define SDMA_CHNENBL_17 __REG32(SDMA_BASE_IO_ADDR, 0x0C4)
++#define SDMA_CHNENBL_18 __REG32(SDMA_BASE_IO_ADDR, 0x0C8)
++#define SDMA_CHNENBL_19 __REG32(SDMA_BASE_IO_ADDR, 0x0CC)
++#define SDMA_CHNENBL_20 __REG32(SDMA_BASE_IO_ADDR, 0x0D0)
++#define SDMA_CHNENBL_21 __REG32(SDMA_BASE_IO_ADDR, 0x0D4)
++#define SDMA_CHNENBL_22 __REG32(SDMA_BASE_IO_ADDR, 0x0D8)
++#define SDMA_CHNENBL_23 __REG32(SDMA_BASE_IO_ADDR, 0x0DC)
++#define SDMA_CHNENBL_24 __REG32(SDMA_BASE_IO_ADDR, 0x0E0)
++#define SDMA_CHNENBL_25 __REG32(SDMA_BASE_IO_ADDR, 0x0E4)
++#define SDMA_CHNENBL_26 __REG32(SDMA_BASE_IO_ADDR, 0x0E8)
++#define SDMA_CHNENBL_27 __REG32(SDMA_BASE_IO_ADDR, 0x0EC)
++#define SDMA_CHNENBL_28 __REG32(SDMA_BASE_IO_ADDR, 0x0F0)
++#define SDMA_CHNENBL_29 __REG32(SDMA_BASE_IO_ADDR, 0x0F4)
++#define SDMA_CHNENBL_30 __REG32(SDMA_BASE_IO_ADDR, 0x0F8)
++#define SDMA_CHNENBL_31 __REG32(SDMA_BASE_IO_ADDR, 0x0FC)
++
++#define SDMA_ONCE_COUNT __REG32(SDMA_BASE_IO_ADDR, 0x200)
++#define SDMA_ONCE_ECTL __REG32(SDMA_BASE_IO_ADDR, 0x204)
++#define SDMA_ONCE_EAA __REG32(SDMA_BASE_IO_ADDR, 0x208)
++#define SDMA_ONCE_EAB __REG32(SDMA_BASE_IO_ADDR, 0x20C)
++#define SDMA_ONCE_EAM __REG32(SDMA_BASE_IO_ADDR, 0x210)
++#define SDMA_ONCE_ED __REG32(SDMA_BASE_IO_ADDR, 0x214)
++#define SDMA_ONCE_EDM __REG32(SDMA_BASE_IO_ADDR, 0x218)
++#define SDMA_ONCE_PCMATCH __REG32(SDMA_BASE_IO_ADDR, 0x21C)
++
++#endif /* SDMA_V2 */
++
++#define SDMA_CHNPRI(i) __REG_ARRAY(SDMA_BASE_IO_ADDR, 0x100, 32, i)
++#define SDMA_CHNPRI_0 __REG32(SDMA_BASE_IO_ADDR, 0x100)
++#define SDMA_CHNPRI_1 __REG32(SDMA_BASE_IO_ADDR, 0x104)
++#define SDMA_CHNPRI_2 __REG32(SDMA_BASE_IO_ADDR, 0x108)
++#define SDMA_CHNPRI_3 __REG32(SDMA_BASE_IO_ADDR, 0x10C)
++#define SDMA_CHNPRI_4 __REG32(SDMA_BASE_IO_ADDR, 0x110)
++#define SDMA_CHNPRI_5 __REG32(SDMA_BASE_IO_ADDR, 0x114)
++#define SDMA_CHNPRI_6 __REG32(SDMA_BASE_IO_ADDR, 0x118)
++#define SDMA_CHNPRI_7 __REG32(SDMA_BASE_IO_ADDR, 0x11C)
++#define SDMA_CHNPRI_8 __REG32(SDMA_BASE_IO_ADDR, 0x120)
++#define SDMA_CHNPRI_9 __REG32(SDMA_BASE_IO_ADDR, 0x124)
++#define SDMA_CHNPRI_10 __REG32(SDMA_BASE_IO_ADDR, 0x128)
++#define SDMA_CHNPRI_11 __REG32(SDMA_BASE_IO_ADDR, 0x12C)
++#define SDMA_CHNPRI_12 __REG32(SDMA_BASE_IO_ADDR, 0x130)
++#define SDMA_CHNPRI_13 __REG32(SDMA_BASE_IO_ADDR, 0x134)
++#define SDMA_CHNPRI_14 __REG32(SDMA_BASE_IO_ADDR, 0x138)
++#define SDMA_CHNPRI_15 __REG32(SDMA_BASE_IO_ADDR, 0x13C)
++#define SDMA_CHNPRI_16 __REG32(SDMA_BASE_IO_ADDR, 0x140)
++#define SDMA_CHNPRI_17 __REG32(SDMA_BASE_IO_ADDR, 0x144)
++#define SDMA_CHNPRI_18 __REG32(SDMA_BASE_IO_ADDR, 0x148)
++#define SDMA_CHNPRI_19 __REG32(SDMA_BASE_IO_ADDR, 0x14C)
++#define SDMA_CHNPRI_20 __REG32(SDMA_BASE_IO_ADDR, 0x150)
++#define SDMA_CHNPRI_21 __REG32(SDMA_BASE_IO_ADDR, 0x154)
++#define SDMA_CHNPRI_22 __REG32(SDMA_BASE_IO_ADDR, 0x158)
++#define SDMA_CHNPRI_23 __REG32(SDMA_BASE_IO_ADDR, 0x15C)
++#define SDMA_CHNPRI_24 __REG32(SDMA_BASE_IO_ADDR, 0x160)
++#define SDMA_CHNPRI_25 __REG32(SDMA_BASE_IO_ADDR, 0x164)
++#define SDMA_CHNPRI_26 __REG32(SDMA_BASE_IO_ADDR, 0x168)
++#define SDMA_CHNPRI_27 __REG32(SDMA_BASE_IO_ADDR, 0x16C)
++#define SDMA_CHNPRI_28 __REG32(SDMA_BASE_IO_ADDR, 0x170)
++#define SDMA_CHNPRI_29 __REG32(SDMA_BASE_IO_ADDR, 0x174)
++#define SDMA_CHNPRI_30 __REG32(SDMA_BASE_IO_ADDR, 0x178)
++#define SDMA_CHNPRI_31 __REG32(SDMA_BASE_IO_ADDR, 0x17C)
++
++#endif /* _mcuEpm_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,131 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiDefaults.h
++ *
++ * $Id iapiDefaults.h $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ *
++ *
++ *
++ *
++ * $Log iapiDefaults.h $
++ *
++ *****************************************************************************/
++
++
++#ifndef _iapi_defaults_h
++#define _iapi_defaults_h
++
++/******************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include "sdmaStruct.h"
++
++/* ****************************************************************************
++ * Macro-command Section
++ * ***************************************************************************/
++
++/**
++ * Error codes
++ * lower 5 bits free to include channel number when available
++ * and bit number 6 must be set when channel number is available
++ *
++ * Note :
++ * 1) Abbreviations / naming convention :
++ * - BD : Buffer Descriptor
++ * - CC : Channel Context
++ * - CCB : Channel Control Block
++ * - CD : Channel Descriptor
++ * - B : Buffer
++ * - CH : Channel
++ *
++ */
++#define IAPI_SUCCESS 0
++#define IAPI_FAILURE (-1)
++#define IAPI_ERR_CH_AVAILABLE 0x00020
++#define IAPI_ERR_NO_ERROR 0x00000
++#define IAPI_ERR_NO_CCB_DEFINED 0x01000
++#define IAPI_ERR_BD_UNINITIALIZED 0x02000
++#define IAPI_ERR_BD_ALLOCATED 0x03000
++#define IAPI_ERR_BD_ALLOCATION 0x04000
++#define IAPI_ERR_CCB_ALLOC_FAILED 0x05000
++#define IAPI_ERR_CCB_UNINITIALIZED 0x06000
++#define IAPI_ERR_CC_ALREADY_DEFINED 0x07000
++#define IAPI_ERR_CC_ALLOC_FAILED 0x08000
++#define IAPI_ERR_CD_ALREADY_DEFINED 0x09000
++#define IAPI_ERR_CD_ALLOC_FAILED 0x0A000
++#define IAPI_ERR_CD_CHANGE_CH_NUMBER 0x0B000
++#define IAPI_ERR_CD_CHANGE_CCB_PTR 0x0C000
++#define IAPI_ERR_CD_CHANGE_UNKNOWN 0x0D000
++#define IAPI_ERR_CD_CHANGE 0x0E000
++#define IAPI_ERR_CD_UNINITIALIZED 0x0F000
++#define IAPI_ERR_CLOSE 0x10000
++#define IAPI_ERR_B_ALLOC_FAILED 0x11000
++#define IAPI_ERR_CONFIG_OVERRIDE 0x12000
++#define IAPI_ERR_CH_IN_USE 0x13000
++#define IAPI_ERR_CALLBACKSYNCH_UNKNOWN 0x14000
++#define IAPI_ERR_INVALID_PARAMETER 0x15000
++#define IAPI_ERR_TRUST 0x16000
++#define IAPI_ERR_CHANNEL_UNINITIALIZED 0x17000
++#define IAPI_ERR_RROR_BIT_READ 0x18000
++#define IAPI_ERR_RROR_BIT_WRITE 0x19000
++#define IAPI_ERR_NOT_ALLOWED 0x1A000
++#define IAPI_ERR_NO_OS_FN 0x1B000
++
++
++/*
++ * Global Variable Section
++ */
++
++/*
++ * Table to hold pointers to the callback functions registered by the users of
++ *I.API
++ */
++extern void (*callbackIsrTable[CH_NUM])(channelDescriptor *cd_p, void *arg);
++
++/*
++ * Table to hold user registered data pointers, to be privided in the callback
++ *function
++ */
++extern void *userArgTable[CH_NUM];
++
++/* channelDescriptor data structure filled with default data*/
++extern channelDescriptor iapi_ChannelDefaults;
++
++/* Global variable to hold the last error encountered in I.API operations*/
++extern int iapi_errno;
++
++/* Used in synchronization, to mark started channels*/
++extern volatile unsigned long iapi_SDMAIntr;
++
++/* Hold a pointer to the start of the CCB array, to be used in the IRQ routine
++ *to find the channel descriptor for the channed sending the interrupt to the
++ *core.
++ */
++extern channelControlBlock *iapi_CCBHead;
++
++/* configs_data structure filled with default data*/
++extern configs_data iapi_ConfigDefaults;
++
++#ifdef SDMA_V2
++extern sdmaState iapi_SdmaState;
++#endif
++
++#endif /* iapiDefaults_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapi.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapi.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapi.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapi.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,49 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapi.h
++ *
++ * $Id iapi.h $
++ *
++ * Description:
++ * Unique include for the whole IAPI library.
++ *
++ *
++ * http//compass.mot.com/go/115342679
++ *
++ * $Log iapi.h $
++ *
++ * ***************************************************************************/
++
++#ifndef _iapi_h
++#define _iapi_h
++
++/* ****************************************************************************
++ * Include File Section
++ * ***************************************************************************/
++#include <linux/types.h>
++#include <mach/hardware.h>
++
++#include <iapiOS.h>
++#include <iapiLow.h>
++#include <iapiMiddle.h>
++#include <iapiHigh.h>
++
++#ifdef MCU
++#include <iapiMiddleMcu.h>
++#endif /* MCU */
++
++
++
++#endif /* _iapi_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,142 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiHigh.h
++ *
++ * $Id iapiHigh.h $
++ *
++ * Description:
++ * prototypes for high level function of I.API
++ *
++ *
++ * http://venerque.sps.mot.com/pjt/sfs/www/iapi/softsim_api.pdf
++ *
++ * $Log iapiHigh.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiHigh_h
++#define _iapiHigh_h
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include "sdmaStruct.h"
++
++/* ****************************************************************************
++ * Macro-command Section
++ *****************************************************************************/
++enum {
++ IAPI_CHANGE_CHANDESC, /* 0x00 */
++ IAPI_CHANGE_BDNUM, /* 0x01 */
++ IAPI_CHANGE_BUFFSIZE, /* 0x02 */
++ IAPI_CHANGE_CHANBLOCK, /* 0x03 */
++ IAPI_CHANGE_INSTANCE, /* 0x04 */
++ IAPI_CHANGE_OWNERSHIP, /* 0x05 */
++ IAPI_CHANGE_SYNCH, /* 0x06 */
++ IAPI_CHANGE_TRUST, /* 0x07 */
++ IAPI_CHANGE_CALLBACKFUNC, /* 0x08 */
++ IAPI_CHANGE_CHANCCB, /* 0x09 */
++ IAPI_CHANGE_PRIORITY, /* 0x0a */
++ IAPI_CHANGE_BDWRAP, /* 0x0b */
++ IAPI_CHANGE_WATERMARK, /* 0x0c */
++ IAPI_CHANGE_SET_BDCONT, /* 0x0d */
++ IAPI_CHANGE_UNSET_BDCONT, /* 0x0e */
++ IAPI_CHANGE_SET_BDEXTD, /* 0x0f */
++ IAPI_CHANGE_UNSET_BDEXTD, /* 0x10 */
++ IAPI_CHANGE_EVTMASK1, /* 0x11 */
++ IAPI_CHANGE_EVTMASK2, /* 0x12 */
++ IAPI_CHANGE_PERIPHADDR, /* 0x13 */
++ IAPI_CHANGE_SET_BDINTR, /* 0x14 */
++ IAPI_CHANGE_UNSET_BDINTR, /* 0x15 */
++ IAPI_CHANGE_SET_TRANSFER_CD, /* 0x16 */
++ IAPI_CHANGE_FORCE_CLOSE, /* 0x17 */
++ IAPI_CHANGE_SET_TRANSFER, /* 0x18 */
++ IAPI_CHANGE_USER_ARG, /* 0x19 */
++ IAPI_CHANGE_SET_BUFFERADDR, /* 0x1a */
++ IAPI_CHANGE_SET_EXTDBUFFERADDR, /* 0x1b */
++ IAPI_CHANGE_SET_COMMAND, /* 0x1c */
++ IAPI_CHANGE_SET_COUNT, /* 0x1d */
++ IAPI_CHANGE_SET_STATUS, /* 0x1e */
++ IAPI_CHANGE_GET_BUFFERADDR, /* 0x1f */
++ IAPI_CHANGE_GET_EXTDBUFFERADDR, /* 0x20 */
++ IAPI_CHANGE_GET_COMMAND, /* 0x21 */
++ IAPI_CHANGE_GET_COUNT, /* 0x22 */
++ IAPI_CHANGE_GET_STATUS, /* 0x23 */
++ IAPI_CHANGE_BUFFER_LOCATION, /* 0x24 */
++ IAPI_CHANGE_SET_ENDIANNESS, /* 0x25 */
++#ifdef SDMA_V2
++ IAPI_ENTER_LOCK_MODE, /* 0x26 */
++#endif
++ IAPI_CHANGE_SET_INTR_MASK, /* 0x27 */
++ IAPI_CHANGE_UNSET_INTR_MASK, /* 0x28 */
++};
++
++
++/*
++ * Public Function Prototype Section
++ */
++int iapi_Open(channelDescriptor *cd_p, unsigned char channelNumber);
++int iapi_Close(channelDescriptor *cd_p);
++int iapi_Read(channelDescriptor *cd_p, void *buf, unsigned short nbyte);
++int iapi_Write(channelDescriptor *cd_p, void *buf, unsigned short nbyte);
++int iapi_MemCopy(channelDescriptor *cd_p, void* dest, void* src,
++ unsigned long size);
++int iapi_IoCtl(channelDescriptor *cd_p, unsigned long ctlRequest,
++ unsigned long param);
++
++
++int iapi_Read_ipcv2(channelDescriptor *cd_p, void *data_control_struct_ipcv2);
++
++int iapi_Write_ipcv2(channelDescriptor *cd_p, void *data_control_struct_ipcv2);
++
++#ifdef MCU
++int iapi_Init(channelDescriptor *cd_p, configs_data *config_p,
++ unsigned short *ram_image, unsigned short code_size,
++ dma_addr_t start_addr, unsigned short channel0_addr);
++#endif /* MCU */
++#ifdef DSP
++int iapi_Init(channelDescriptor *cd_p);
++#endif /* DSP */
++
++int iapi_StartChannel(unsigned char channel);
++int iapi_StopChannel(unsigned char channel);
++int iapi_SynchChannel(unsigned char channel);
++
++int iapi_GetChannelNumber(channelDescriptor *cd_p);
++unsigned long iapi_GetError(channelDescriptor *cd_p);
++int iapi_GetCount(channelDescriptor *cd_p);
++int iapi_GetCountAll(channelDescriptor *cd_p);
++
++#ifndef IRQ_KEYWORD
++#define IRQ_KEYWORD
++#endif /* IRQ_KEYWORD */
++
++IRQ_KEYWORD void IRQ_Handler(void);
++
++#ifdef MCU
++int iapi_GetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
++ dma_addr_t address);
++int iapi_GetContext(channelDescriptor *cd_p, void *buf,
++ unsigned char channel);
++int iapi_SetScript(channelDescriptor *cd_p, void *buf, unsigned short nbyte,
++ dma_addr_t destAddr);
++int iapi_SetContext(channelDescriptor *cd_p, void *buf,
++ unsigned char channel);
++int iapi_AssignScript(channelDescriptor *cd_p, script_data *data_p);
++
++int iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map);
++#endif /* MCU */
++
++#endif /* _iapiHigh_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,50 @@
++/*
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/* ****************************************************************************
++ *
++ * File: iapiLowDsp.h
++ *
++ * $Id iapiLowDsp.h $
++ *
++ * Description:
++ * prototypes for low level function of I.API for DSP side only
++ *
++ *
++ *
++ *
++ * $Log iapiLowDsp.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiLowDsp_h
++#define _iapiLowDsp_h
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ *****************************************************************************/
++/* WARNING !!!!!
++ * This file is empty and it is normal, because there is no low level functions
++ * dedicated to the DSP but the file (iapi_LowDsp.h) must still exist because
++ * some project directly links the file. Previously, there were function
++ * iapi_EnableInterrupts,iapi_DisableInterrupts,iapi_WaitCore,iapi_StartChannel
++ * iapi_StopChannel but they are common to both MCU and DSP, so they have been
++ * moved to iapi_Low.h file.
++ */
++
++#endif /* _iapiLowDsp_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,70 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiLow.h
++ *
++ * $Id iapiLow.h $
++ *
++ * Description:
++ * prototypes for low level function of I.API
++ *
++ *
++ *
++ *
++ * $Log iapiLow.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiLow_h
++#define _iapiLow_h
++
++/* ****************************************************************************
++ * Boolean identifiers
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include "iapiOS.h"
++#include <linux/types.h>
++#include <mach/dma.h>
++
++/* ****************************************************************************
++ * Macro-command Section
++ *****************************************************************************/
++enum
++{
++ OR_OP,
++ AND_OP
++};
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ *****************************************************************************/
++typedef void (*CallbackISR)(channelDescriptor *cd_p, void *arg);
++
++void iapi_lowStartChannel(unsigned char channel);
++void iapi_lowStopChannel(unsigned char channel);
++int iapi_lowChangeIntrMask(unsigned int param, unsigned char op);
++void iapi_AttachCallbackISR(channelDescriptor *cd_p,
++ CallbackISR func_p);
++void iapi_DetachCallbackISR(channelDescriptor *cd_p);
++void iapi_ChangeCallbackISR(channelDescriptor *cd_p,
++ CallbackISR func_p);
++void iapi_lowSynchChannel(unsigned char channel);
++void iapi_SetBufferDescriptor(bufferDescriptor *bd_p, unsigned char command,
++ unsigned char status, unsigned short count,
++ void *buffAddr, dma_addr_t extBufferAddr);
++
++#endif /* _iapiLow_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h 2010-12-03 09:51:55.388349760 +0100
+@@ -0,0 +1,58 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiLowMcu.h
++ *
++ * $Id iapiLowMcu.h $
++ *
++ * Description:
++ * prototypes for low level function of I.API of MCU side only
++ *
++ *
++ *
++ *
++ * $Log iapiLowMcu.h $
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiLowMcu_h
++#define _iapiLowMcu_h
++
++/******************************************************************************
++ * Include File Section
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ * ***************************************************************************/
++
++
++void iapi_InitChannelTables(void);
++int iapi_ChannelConfig(unsigned char channel, unsigned eventOverride,
++ unsigned mcuOverride, unsigned dspOverride);
++int iapi_Channel0Command(channelDescriptor *cd_p, void *buf,
++ unsigned short nbyte, unsigned char command);
++void iapi_lowGetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
++ dma_addr_t address);
++void iapi_lowGetContext(channelDescriptor *cd_p, void *buf,
++ unsigned char channel);
++void iapi_lowSetScript(channelDescriptor *cd_p, void *buf, unsigned short nbyte,
++ dma_addr_t destAddr);
++void iapi_lowSetContext(channelDescriptor *cd_p, void *buf,
++ unsigned char channel);
++int iapi_lowAssignScript(channelDescriptor *cd_p, script_data *data_p);
++
++int iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map);
++
++#endif /* _iapiLowMcu_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h 2010-12-03 09:51:55.392354434 +0100
+@@ -0,0 +1,52 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiMiddle.h
++ *
++ * $Id iapiMiddle.h $
++ *
++ * Description:
++ * prototypes for middle level function of I.API
++ *
++ *
++ *
++ *
++ * $Log iapiMiddle.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiMiddle_h
++#define _iapiMiddle_h
++
++/* ****************************************************************************
++ * Include File Section
++ ******************************************************************************/
++#include "sdmaStruct.h"
++#ifdef MCU
++#include "iapiMiddleMcu.h"
++#endif /* MCU */
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ ******************************************************************************/
++bufferDescriptor *iapi_AllocBD(channelControlBlock *ccb_p);
++int iapi_AllocContext(contextData **ctxd_p, unsigned char channel);
++int iapi_AllocChannelDesc(channelDescriptor **cd_p, unsigned char channel);
++int iapi_ChangeChannelDesc (channelDescriptor *cd_p,
++ unsigned char whatToChange, unsigned long newval);
++void iapi_InitializeCallbackISR(void (*func_p)(channelDescriptor *cd_p,
++ void *arg));
++int iapi_InitializeMemory (channelControlBlock *ccb_p);
++
++#endif /* iapiMiddle_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h 2010-12-03 09:51:55.392354434 +0100
+@@ -0,0 +1,41 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiMiddleMcu.h
++ *
++ * $Id iapiMiddleMcu.h $
++ *
++ * Description:
++ * prototypes for middle level function of I.API
++ *
++ *
++ *
++ *
++ * $Log iapiMiddleMcu.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiMiddleMcu_h
++#define _iapiMiddleMcu_h
++
++/* ****************************************************************************
++ * Include File Section
++ ******************************************************************************/
++#include "sdmaStruct.h"
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ ******************************************************************************/
++
++#endif /* iapiMiddleMcu_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h 2010-12-03 09:51:55.392354434 +0100
+@@ -0,0 +1,95 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiOS.h
++ *
++ * $Id iapiOS.h $
++ *
++ * Description:
++ * prototypes for OS level function of I.API
++ *
++ *
++ *
++ *
++ * $Log iapiOS.h
++ *
++ * ***************************************************************************/
++
++#ifndef _iapiOS_h
++#define _iapiOS_h
++
++/* ****************************************************************************
++ * Boolean identifiers
++ *****************************************************************************/
++#define NO_OS 0
++#define LINUX 1
++#define SYMBIAN 2
++#define WINCE 3
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#if OS == NO_OS
++#include <stdlib.h>
++#elif OS == LINUX
++#include <linux/types.h>
++#endif
++
++#include "sdmaStruct.h"
++#include "iapiDefaults.h"
++#ifdef MCU
++#include "iapiLowMcu.h"
++#endif /* MCU */
++
++/* ****************************************************************************
++ * Macro-command Section
++ *****************************************************************************/
++#ifdef CONFIG_SDMA_IRAM
++#define IRAM_MALLOC(x) (*iapi_iram_Malloc)(x)
++#else
++#define IRAM_MALLOC(x) (*iapi_Malloc)(x)
++#endif
++#define MALLOC(x) (*iapi_Malloc)(x)
++#define FREE(x) if ((x) != NULL) (*iapi_Free)(x)
++
++#define GOTO_SLEEP(x) (iapi_GotoSleep)(x)
++#define INIT_SLEEP(x) (iapi_InitSleep)(x)
++
++/* ****************************************************************************
++ * Public Function Prototype Section
++ *****************************************************************************/
++
++#ifdef CONFIG_SDMA_IRAM
++extern void *(*iapi_iram_Malloc)(size_t size);
++#endif
++extern void *(*iapi_Malloc)(size_t size);
++extern void (*iapi_Free)(void *ptr);
++
++extern dma_addr_t (*iapi_Virt2Phys)(void *ptr);
++extern void *(*iapi_Phys2Virt)(dma_addr_t);
++
++extern void (*iapi_WakeUp)(int);
++extern void (*iapi_GotoSleep)(int);
++extern void (*iapi_InitSleep)(int);
++
++extern void *(*iapi_memcpy)(void *dest, const void *src, size_t count);
++extern void *(*iapi_memset)(void *dest, int c, size_t count);
++
++extern void (*iapi_EnableInterrupts)(void);
++extern void (*iapi_DisableInterrupts)(void);
++
++extern int (*iapi_GetChannel)(int);
++extern int (*iapi_ReleaseChannel)(int);
++
++#endif /* _iapiOS_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h 2010-12-03 09:51:55.392354434 +0100
+@@ -0,0 +1,465 @@
++/******************************************************************************
++ *
++ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: sdmaStruct.h
++ *
++ * $Id sdmaStruct.h $
++ *
++ * Description: provides necessary definitions and inclusion for ipcmStruct.c
++ *
++ * $Log $
++ *
++ *****************************************************************************/
++#ifndef _sdmaStruct_h
++#define _sdmaStruct_h
++
++/* ****************************************************************************
++ * Include File Section
++ ******************************************************************************/
++
++/* ****************************************************************************
++ * Macro-command Section
++ ******************************************************************************/
++
++/**
++ * Identifier NULL
++ */
++#ifndef NULL
++#define NULL 0
++#endif
++
++/**
++ * Boolean identifiers
++ */
++#ifndef FALSE
++#define FALSE 0
++#endif
++
++#ifndef TRUE
++#define TRUE 1
++#endif
++
++/**
++ * Number of channels
++ */
++#define CH_NUM 32
++/**
++ * Number of events
++ */
++#ifdef SDMA_V2
++#define EVENTS_NUM 48
++#else
++#define EVENTS_NUM 32
++#endif
++/**
++ * Channel configuration
++ */
++#define DONT_OWN_CHANNEL 0
++#define OWN_CHANNEL 1
++
++/**
++ * Ownership (value defined to computed decimal value)
++ */
++#define CH_OWNSHP_OFFSET_EVT 0
++#define CH_OWNSHP_OFFSET_MCU 1
++#define CH_OWNSHP_OFFSET_DSP 2
++/**
++ * Indexof the greg which holds address to start a script from when channel
++ * becomes current.
++ */
++#define SDMA_NUMBER_GREGS 8
++
++/**
++ * Channel contexts management
++ */
++
++#define CHANNEL_CONTEXT_BASE_ADDRESS 0x800
++/**
++ * Buffer descriptor status values.
++ */
++#define BD_DONE 0x01
++#define BD_WRAP 0x02
++#define BD_CONT 0x04
++#define BD_INTR 0x08
++#define BD_RROR 0x10
++#define BD_LAST 0x20
++#define BD_EXTD 0x80
++
++
++/**
++ * Data Node descriptor status values.
++ */
++#define DND_END_OF_FRAME 0x80
++#define DND_END_OF_XFER 0x40
++#define DND_DONE 0x20
++#define DND_UNUSED 0x01
++
++/**
++ * IPCV2 descriptor status values.
++ */
++#define BD_IPCV2_END_OF_FRAME 0x40
++
++
++#define IPCV2_MAX_NODES 50
++/**
++ * Error bit set in the CCB status field by the SDMA,
++ * in setbd routine, in case of a transfer error
++ */
++#define DATA_ERROR 0x10000000
++
++/**
++ * Buffer descriptor commands.
++ */
++#define C0_ADDR 0x01
++#define C0_LOAD 0x02
++#define C0_DUMP 0x03
++#define C0_SETCTX 0x07
++#define C0_GETCTX 0x03
++#define C0_SETDM 0x01
++#define C0_SETPM 0x04
++#define C0_GETDM 0x02
++#ifdef SDMA_V2
++#define C0_GETPM 0x06
++#else
++#define C0_GETPM 0x08
++#endif
++/**
++ * Transfer types, encoded in the BD command field
++ */
++#define TRANSFER_32BIT 0x00
++#define TRANSFER_8BIT 0x01
++#define TRANSFER_16BIT 0x02
++#define TRANSFER_24BIT 0x03
++
++#define TRANSFER_TYPE_MASK 0x03 /* MASK FOR BIT0 and BIT1 of BD Command Field*/
++/**
++ * Memory types, encoded in the BD command field
++ */
++#define EXTERNAL_MEM 0x04
++#define INTERNAL_MEM ~0x04
++
++#define BUFFER_LOC_MASK 0x04 /* MASK FOR BIT2 of BD Command Field*/
++/**
++ * Change endianness indicator in the BD command field
++ */
++#define CHANGE_ENDIANNESS 0x80
++
++#define ENDIANNESS_MASK 0x80 /* MASK FOR BIT7 of BD Command Field*/
++/**
++ * Size in bytes
++ */
++#define SDMA_BD_SIZE 8
++#define SDMA_EXTENDED_BD_SIZE 12
++#define BD_NUMBER 4
++/**
++ * Channel interrupt policy
++ */
++#define DEFAULT_POLL 0
++#define CALLBACK_ISR 1
++/**
++ * Channel status
++ */
++#define UNINITIALIZED 0
++#define INITIALIZED 1
++
++/**
++ * IoCtl particular values
++ */
++#define SET_BIT_ALL 0xFFFFFFFF
++#define BD_NUM_OFFSET 16
++#define BD_NUM_MASK 0xFFFF0000
++
++/**
++ * Maximum values for IoCtl calls, used in high or middle level calls
++ */
++#define MAX_BD_NUM 1024
++#define MAX_BD_SIZE 65536
++#define MAX_BLOCKING 2
++#define MAX_SYNCH 2
++#define MAX_OWNERSHIP 8
++#define MAX_CH_PRIORITY 8
++#define MAX_TRUST 2
++#define MAX_WML 256
++
++
++/**
++ * Access to channelDescriptor fields
++ */
++enum {
++ IAPI_CHANNELNUMBER, /* 0x00 */
++ IAPI_BUFFERDESCNUMBER, /* 0x01 */
++ IAPI_BUFFERSIZE, /* 0x02 */
++ IAPI_BLOCKING, /* 0x03 */
++ IAPI_CALLBACKSYNCH, /* 0x04 */
++ IAPI_OWNERSHIP, /* 0x05 */
++ IAPI_PRIORITY, /* 0x06 */
++ IAPI_TRUST, /* 0x07 */
++ IAPI_UNUSED, /* 0x08 */
++ IAPI_CALLBACKISR_PTR, /* 0x09 */
++ IAPI_CCB_PTR, /* 0x0a */
++ IAPI_BDWRAP, /* 0x0b */
++ IAPI_WML, /* 0x0c */
++};
++
++#ifdef SDMA_V2
++
++/**
++ * Enum for SDMA states
++ */
++typedef enum {
++ UNDEF,
++ OPEN,
++ LOCK,
++ CLOSED,
++ CLOSE_LOCK
++} sdmaState;
++
++/**
++ * LOCK Register Value
++ */
++ #define RESET_CLEAR_LOCK 0x03
++ #define RESET_NOCLEAR_LOCK 0x01
++
++#define RESET_CLR_BIT_OFFSET 1
++#define LOCK_BIT_OFFSET 0
++
++#endif
++
++/**
++ * Default values for channel descriptor - nobody ownes the channel
++ */
++#define CD_DEFAULT_OWNERSHIP 7
++
++
++/**
++ * User Type Section
++ */
++
++/**
++ * Command/Mode/Count of buffer descriptors
++ */
++
++#if (ENDIANNESS==B_I_G_ENDIAN)
++typedef struct iapi_modeCount_ipcv2 {
++ unsigned long status : 8; /* L, E , D bits stored here */
++ unsigned long reserved : 8;
++ unsigned long count : 16; /* <size of the buffer pointed by this BD */
++} modeCount_ipcv2;
++#else
++typedef struct iapi_modeCount_ipcv2 {
++ unsigned long count : 16; /* size of the buffer pointed by this BD */
++ unsigned long reserved : 8; /* Reserved*/
++ unsigned long status : 8; /* L, E , D bits stored here */
++} modeCount_ipcv2;
++#endif
++/**
++ * Data Node descriptor - IPCv2
++ * (differentiated between evolutions of SDMA)
++ */
++typedef struct iapi_dataNodeDescriptor {
++ modeCount_ipcv2 mode; /* command, status and count */
++ dma_addr_t bufferAddr; /* address of the buffer described */
++} dataNodeDescriptor;
++
++#if (ENDIANNESS==B_I_G_ENDIAN)
++typedef struct iapi_modeCount_ipcv1_v2 {
++ unsigned long endianness: 1;
++ unsigned long reserved: 7;
++ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here */
++ unsigned long count : 16; /* size of the buffer pointed by this BD */
++} modeCount_ipcv1_v2;
++#else
++typedef struct iapi_modeCount_ipcv1_v2 {
++ unsigned long count : 16; /* size of the buffer pointed by this BD */
++ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here */
++ unsigned long reserved: 7;
++ unsigned long endianness: 1;
++} modeCount_ipcv1_v2;
++#endif
++/**
++ * Buffer descriptor
++ * (differentiated between evolutions of SDMA)
++ */
++typedef struct iapi_bufferDescriptor_ipcv1_v2 {
++ modeCount_ipcv1_v2 mode; /* command, status and count */
++ dma_addr_t bufferAddr; /* address of the buffer described */
++ dma_addr_t extBufferAddr; /* extended buffer address */
++} bufferDescriptor_ipcv1_v2;
++
++
++/**
++ * Mode/Count of data node descriptors - IPCv2
++ */
++
++#if (ENDIANNESS==B_I_G_ENDIAN)
++typedef struct iapi_modeCount {
++ unsigned long command : 8; /* command mostly used for channel 0 */
++ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here */
++ unsigned long count : 16; /* size of the buffer pointed by this BD */
++} modeCount;
++#else
++typedef struct iapi_modeCount {
++ unsigned long count : 16; /* size of the buffer pointed by this BD */
++ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here */
++ unsigned long command : 8; /* command mostly used for channel 0 */
++} modeCount;
++#endif
++
++
++/**
++ * Buffer descriptor
++ * (differentiated between evolutions of SDMA)
++ */
++typedef struct iapi_bufferDescriptor {
++ modeCount mode; /* command, status and count */
++ dma_addr_t bufferAddr; /* address of the buffer described */
++ dma_addr_t extBufferAddr; /* extended buffer address */
++} bufferDescriptor;
++
++
++
++struct iapi_channelControlBlock;
++struct iapi_channelDescriptor;
++/**
++ * Channel Descriptor
++ */
++typedef struct iapi_channelDescriptor {
++ unsigned char channelNumber ;/* stores the channel number */
++ unsigned short bufferSize ;/* size (in bytes) of buffer descriptors */
++ unsigned short bufferDescNumber;/* number of BD's automatically allocated for this channel */
++ unsigned long blocking :3;/* blocking / non blocking feature selection */
++ unsigned long callbackSynch :1;/* polling/ callback method selection */
++ unsigned long ownership :3;/* ownership of the channel (host+dedicated+event)*/
++ unsigned long priority :3;/* reflects the SDMA channel priority register */
++ unsigned long trust :1;/* trusted buffers or kernel allocated */
++ unsigned long useDataSize :1;/* indicates if the dataSize field is meaningfull */
++ unsigned long dataSize :2;/* data transfer size - 8,16,24 or 32 bits*/
++ unsigned long forceClose :1;/* if TRUE, close channel even with BD owned by SDMA*/
++ unsigned long scriptId :7;/* number of the script */
++ unsigned long watermarkLevel:10;/* Watermark level for the peripheral access*/
++ unsigned long eventMask1; /* First Event mask */
++ unsigned long eventMask2; /* Second Event mask */
++ unsigned long peripheralAddr; /* Address of the peripheral or its fifo when needed */
++ void (*callbackISR_ptr)(struct iapi_channelDescriptor*, void*); /* pointer to the callback function (or NULL) */
++ struct iapi_channelControlBlock *ccb_ptr; /* pointer to the channel control block associated to this channel */
++} channelDescriptor;
++
++/**
++ * Channel Status
++ */
++typedef struct iapi_channelStatus {
++ unsigned long unused :27,
++ data_error : 1,
++ even_more_unused: 1,
++ openedInit : 1, /* channel is initialized */
++ stateDirection: 1, /* sdma is reading/writing (as seen from channel owner core) */
++ execute : 1; /* channel is being processed (started) */
++} channelStatus;
++
++/**
++ * Channel control Block
++ */
++typedef struct iapi_channelControlBlock {
++ dma_addr_t currentBDptr; /* current buffer descriptor processed */
++ dma_addr_t baseBDptr; /* first element of buffer descriptor array */
++ channelDescriptor *channelDescriptor; /* pointer to the channel descriptor */
++ channelStatus status; /* open/close ; started/stopped ; read/write */
++} channelControlBlock;
++
++/**
++ * Context structure.
++ */
++#if (ENDIANNESS==B_I_G_ENDIAN)
++typedef struct iapi_stateRegisters {
++ unsigned long sf : 1;/* source falut while loading data */
++ unsigned long unused0: 1;/* */
++ unsigned long rpc :14;/* return program counter */
++ unsigned long t : 1;/* test bit:status of arithmetic & test instruction*/
++ unsigned long unused1: 1;/* */
++ unsigned long pc :14;/* program counter */
++ unsigned long lm : 2;/* loop mode */
++ unsigned long epc :14;/* loop end program counter */
++ unsigned long df : 1;/* destiantion falut while storing data */
++ unsigned long unused2: 1;/* */
++ unsigned long spc :14;/* loop start program counter */
++} stateRegiters;
++#else
++typedef struct iapi_stateRegisters {
++ unsigned long pc :14;/* program counter */
++ unsigned long unused1: 1;/* */
++ unsigned long t : 1;/* test bit: status of arithmetic & test instruction*/
++ unsigned long rpc :14;/* return program counter */
++ unsigned long unused0: 1;/* */
++ unsigned long sf : 1;/* source falut while loading data */
++ unsigned long spc :14;/* loop start program counter */
++ unsigned long unused2: 1;/* */
++ unsigned long df : 1;/* destiantion falut while storing data */
++ unsigned long epc :14;/* loop end program counter */
++ unsigned long lm : 2;/* loop mode */
++} stateRegiters;
++#endif
++
++/**
++ * This is SDMA version of SDMA
++ */
++typedef struct iapi_contextData {
++ stateRegiters channelState; /* channel state bits */
++ unsigned long gReg[SDMA_NUMBER_GREGS]; /* general registers */
++ unsigned long mda; /* burst dma destination address register */
++ unsigned long msa; /* burst dma source address register */
++ unsigned long ms; /* burst dma status register */
++ unsigned long md; /* burst dma data register */
++ unsigned long pda; /* peripheral dma destination address register */
++ unsigned long psa; /* peripheral dma source address register */
++ unsigned long ps; /* peripheral dma status register */
++ unsigned long pd; /* peripheral dma data register */
++ unsigned long ca; /* CRC polynomial register */
++ unsigned long cs; /* CRC accumulator register */
++ unsigned long dda; /* dedicated core destination address register */
++ unsigned long dsa; /* dedicated core source address register */
++ unsigned long ds; /* dedicated core status register */
++ unsigned long dd; /* dedicated core data register */
++ unsigned long scratch0; /* scratch */
++ unsigned long scratch1; /* scratch */
++ unsigned long scratch2; /* scratch */
++ unsigned long scratch3; /* scratch */
++ unsigned long scratch4; /* scratch */
++ unsigned long scratch5; /* scratch */
++ unsigned long scratch6; /* scratch */
++ unsigned long scratch7; /* scratch */
++} contextData;
++
++/**
++ *This structure holds the necessary data for the assignment in the
++ * dynamic channel-script association
++ */
++typedef struct iapi_script_data {
++ unsigned short load_address;/* start address of the script */
++ unsigned long wml; /* parameters for the channel descriptor */
++ unsigned long shp_addr; /* shared peripheral base address */
++ unsigned long event_mask1; /* First Event mask */
++ unsigned long event_mask2; /* Second Event mask */
++} script_data;
++
++/**
++ *This structure holds the the useful bits of the CONFIG register
++ */
++typedef struct iapi_configs_data {
++ unsigned long dspdma :1; /* indicates if the DSPDMA is used */
++ unsigned long rtdobs :1; /* indicates if Real-Time Debug pins are enabled */
++ unsigned long acr :1; /* indicates if AHB freq /core freq = 2 or 1 */
++ unsigned long csm :2; /* indicates which context switch mode is selected */
++} configs_data;
++
++#endif /* _sdmaStruct_h */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/Makefile linux.35.new/arch/arm/plat-mxc/sdma/iapi/Makefile
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/Makefile 2010-12-03 09:51:55.392354434 +0100
+@@ -0,0 +1,5 @@
++#
++# Makefile for I.API sources.
++#
++
++obj-y := src/
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c 2010-12-03 09:51:55.396349340 +0100
+@@ -0,0 +1,128 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiDefaults.c
++ *
++ * $Id iapiDefaults.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ *
++ * Usage:
++ *
++ * Files:
++ *
++ *
++* /
++ *
++ * $Log iapiDefaults.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ ******************************************************************************/
++#include <iapi.h>
++
++/* ****************************************************************************
++ * Global Variable Section
++ ******************************************************************************/
++
++/**
++ * @brief System Call-back ISRs Table
++ */
++void (*callbackIsrTable[CH_NUM])(channelDescriptor *cd_p, void *arg);
++
++/**
++ * @brief User registered pointers table
++ */
++void *userArgTable[CH_NUM];
++
++/**
++ * @brief Pointer to the first CCB in the CCB array
++ */
++channelControlBlock *iapi_CCBHead = NULL;
++
++
++/**Default channel description.
++ *
++ * Initialization values are:\n
++ * - channelNumber = 0
++ * - bufferDescNumber = 1
++ * - bufferSize = 8
++ * - blocking = 0
++ * - callbackSynch = DEFAULT_POLL
++ * - ownership = CD_DEFAULT_OWNERSHIP
++ * - priority = 1
++ * - trust = TRUE
++ * - useDataSize = 0
++ * - dataSize = 0
++ * - forceClose = 0
++ * - scriptId = 0
++ * - watermarkLevel = 0
++ * - eventMask1 = 0
++ * - eventMask2 = 0
++ * - peripheralAddr = NULL
++ * - callbackISR_ptr = NULL
++ * - iapi_channelControlBlock = NULL
++ */
++channelDescriptor iapi_ChannelDefaults = {
++ 0, 1, 8, 0, DEFAULT_POLL,
++ CD_DEFAULT_OWNERSHIP, 1, TRUE, 0, 0, 0, 0,
++ 0, 0x00, 0x00, 0x00, NULL, NULL,
++};
++
++/**
++ * Integrated error management
++ */
++int iapi_errno = 0;
++volatile unsigned long iapi_SDMAIntr = 0;
++
++/* Default config register.
++ * Initialization values are:
++ * dspdma used
++ * Real-Time Debug pins disabled
++ * AHB freq / core freq = 2
++ * dynamic context switch
++*/
++
++/* DSPDMA (12th) bit of CONFIG Register should be zero when DSP DMA is not connected.
++ * Otherwise it can even lead to hang while doing the context switch.
++ * Hence for all MAD targets, iapi_ConfigDefaults should be updated to:
++ * { 0, 0, 0, 3 OR 0 } depending on whether context switching
++ * needs to be static or dynamic */
++configs_data iapi_ConfigDefaults = {
++ /* according to the i.MX25 reference manual this should be configured as 0 */
++#ifndef CONFIG_ARCH_MX25
++ 1,
++#else
++ 0,
++#endif
++ 0,
++ 0,
++ 3,
++};
++
++#ifdef SDMA_V2
++/* Default sdma State : UNDEF
++ *possible value are UNDEF, OPEN, LOCK, CLOSED, CLOSE_LOCK
++ */
++
++sdmaState iapi_SdmaState = UNDEF;
++#endif
++
++/* ***************************************************************************/
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c 2010-12-03 09:51:55.404347330 +0100
+@@ -0,0 +1,2462 @@
++/******************************************************************************
++ *
++ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiHigh.c
++ *
++ * $Id iapiHigh.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the HIGH level functions of the I.API.
++ *
++ *
++ * /
++ *
++ * $Log iapiHigh.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <stdarg.h>
++#include <string.h>
++#include <linux/err.h>
++#include <linux/io.h>
++
++#include <epm.h>
++#include <iapi.h>
++
++#ifdef DEBUG
++#include <mach/sdma.h>
++#if CH_NUM != MAX_DMA_CHANNELS
++#error BAD number of DMA channels!
++#endif
++#endif
++
++/* ****************************************************************************
++ * External Reference Section (for compatibility with already developed code)
++ *****************************************************************************/
++static void iapi_read_ipcv2_callback(struct iapi_channelDescriptor *cd_p, void *data);
++
++/* ****************************************************************************
++ * Global Variable Section
++ *****************************************************************************/
++#define MAX_CHANNEL 32
++
++static dataNodeDescriptor *dnd_read_control_struct[MAX_CHANNEL];
++
++/* MASK to nullify all the bits of Status in Data Node descriptor apart from L, E and D */
++#define GET_LED_MASK 0xE0
++
++/* Table defines mapping of Data Node Descriptor to Buffer Descriptor status */
++static unsigned char dnd_2_bd_status[] = {
++ [0x00] = 0x85, /* L = 0, E = 0, D = 0 */
++ [0x20] = 0x84, /* L = 0, E = 0, D = 1 */
++ [0x40] = 0xAB, /* L = 0, E = 1, D = 0 */
++ [0x60] = 0xAA, /* L = 0, E = 1, D = 1 */
++ [0x80] = 0xC5, /* L = 1, E = 0, D = 0 */
++ [0xA0] = 0xC4, /* L = 1, E = 0, D = 1 */
++ [0xC0] = 0xEB, /* L = 1, E = 1, D = 0 */
++ [0xE0] = 0xEA, /* L = 1, E = 1, D = 1 */
++};
++/* ****************************************************************************
++ * Function Section
++ *****************************************************************************/
++
++/* ***************************************************************************/
++/* Opens an SDMA channel to be used by the library.
++ *
++ * <b>Algorithm:</b>\n
++ *
++ * - Check if initialization is necessary.
++ * - Check that user initialized OS dependant functions.
++ * - Test validity of input parameters
++ * - Check whole channel control block data structure
++ * - Finish initializations (tables with default values)
++ * - Initialize channel 0 is dedicated to communications with SDMA
++ * - Check channel control block definition
++ * - if the channel descriptor is not initialized, initialize it with
++ * the default value
++ * - If buffer descriptor already allocated, exit with iapi_errno filled
++ * complete the lowest bits with the number of 'D' bits set
++ * - Buffer Descriptors allocation
++ * - Channel's configuration properties (mcu side only)
++ * - read/write direction => enable/disable channel setting
++ *
++ * @param *cd_p If channelNumber is 0, it is pointer to channel descriptor
++ * for the channnel 0 to be opened and
++ * has default values.
++ * For other channels, this function should be called after
++ * channel 0 has been opened, and it's channel descriptor
++ * has been allocated.
++ * @param channelNumber channel to be opened
++ *
++ * @return
++ * - IAPI_SUCCESS : OK
++ * - -iapi_errno : close failed, return negated value of iapi_errno
++ */
++int
++iapi_Open(channelDescriptor *cd_p, unsigned char channelNumber)
++{
++ channelControlBlock *ccb_p;
++ channelControlBlock *local_ccb_p;
++ channelDescriptor *local_cd_p;
++ bufferDescriptor *bd_p;
++ int index;
++
++ DBG(0, "%s: cd_p=%p channel=%d\n", __FUNCTION__, cd_p, channelNumber);
++
++ /*
++ * 1. Check if initialization is necessary
++ */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED |
++ IAPI_ERR_CH_AVAILABLE | channelNumber;
++ return -iapi_errno;
++ }
++
++ /* Verify these functions every time */
++ if ((iapi_GetChannel == NULL) || (iapi_ReleaseChannel == NULL)) {
++ iapi_errno = IAPI_ERR_NO_OS_FN | channelNumber;
++ return -iapi_errno;
++ }
++
++ /* Try to aquire channel */
++ if (iapi_GetChannel(channelNumber) != 0) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | channelNumber;
++ return -iapi_errno;
++ }
++
++ DBG(0, "%s@%d: cd_p=%p ccb_ptr=%p\n", __FUNCTION__, __LINE__, cd_p,
++ cd_p->ccb_ptr);
++ if (channelNumber == 0 && cd_p->ccb_ptr == NULL) {
++ int i;
++
++ /* Verify that the user initialized all OS dependant functions required
++ * by the library.
++ */
++ if ((iapi_Malloc == NULL) ||
++ (iapi_Free == NULL) ||
++ (iapi_Virt2Phys == NULL) ||
++ (iapi_Phys2Virt == NULL) ||
++ (iapi_GotoSleep == NULL) ||
++ (iapi_WakeUp == NULL) ||
++ (iapi_InitSleep == NULL) ||
++ (iapi_memset == NULL) ||
++ (iapi_memcpy == NULL)) {
++ iapi_errno = IAPI_ERR_NO_OS_FN | channelNumber;
++ iapi_ReleaseChannel(channelNumber);
++ return -iapi_errno;
++ }
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /* Whole channel control block data structure */
++ ccb_p = MALLOC(CH_NUM * sizeof(channelControlBlock));
++ if (ccb_p == NULL) {
++ iapi_errno = IAPI_ERR_CCB_ALLOC_FAILED |
++ IAPI_ERR_CH_AVAILABLE | channelNumber;
++ iapi_ReleaseChannel(channelNumber);
++ return -iapi_errno;
++ }
++ DBG(0, "%s: ccb allocated at %p..%p\n", __FUNCTION__, ccb_p,
++ (unsigned char *)(ccb_p + CH_NUM) - 1);
++
++ /* Zero-out the CCB structures array just allocated */
++ iapi_memset(ccb_p, 0x00, CH_NUM * sizeof(channelControlBlock));
++ for (i = 0; i < CH_NUM; i++) {
++ ccb_p[i].baseBDptr = DMA_ADDR_INVALID;
++ ccb_p[i].currentBDptr = DMA_ADDR_INVALID;
++ }
++ /* Save the address of the CCB structures array */
++ iapi_CCBHead = ccb_p;
++
++ cd_p->ccb_ptr = ccb_p;
++ ccb_p->channelDescriptor = cd_p;
++ DBG(0, "%s: channelDescriptor %p=%p\n", __FUNCTION__,
++ &ccb_p->channelDescriptor, cd_p);
++#ifdef MCU
++ /* finish initializations */
++ iapi_InitChannelTables();
++#endif /* MCU */
++ /* Channel 0 is dedicated to communications with SDMA */
++ cd_p->ownership = ((DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ cd_p->bufferDescNumber = 1;
++ }
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /*
++ * 2. Check channel control block
++ */
++ ccb_p = cd_p->ccb_ptr;
++ if (ccb_p == NULL) {
++ iapi_errno = IAPI_ERR_NO_CCB_DEFINED |
++ IAPI_ERR_CH_AVAILABLE |
++ channelNumber;
++ iapi_ReleaseChannel(channelNumber);
++ return -iapi_errno;
++ }
++
++ DBG(0, "%s@%d: ccb_p=%p\n", __FUNCTION__, __LINE__, ccb_p);
++ /* Control block & Descriptor associated with the channel being worked on */
++ local_ccb_p = &ccb_p[channelNumber];
++ local_cd_p = ccb_p[channelNumber].channelDescriptor;
++
++ DBG(0, "%s@%d: local_ccb_p[%d]=%p local_cd_p[%p]=%p\n", __FUNCTION__, __LINE__,
++ channelNumber, local_ccb_p,
++ &ccb_p[channelNumber].channelDescriptor, local_cd_p);
++ /* If the channel is not initialized, initialize it with the default value */
++ if (local_cd_p == NULL) {
++ int result = iapi_AllocChannelDesc(&local_cd_p, channelNumber);
++ if (result!= IAPI_SUCCESS) {
++ iapi_ReleaseChannel(channelNumber);
++ return result; //is already negated from iapi_AllocChannelDesc
++ }
++
++ local_cd_p->ccb_ptr = (struct iapi_channelControlBlock *)local_ccb_p;
++ local_ccb_p->channelDescriptor = local_cd_p;
++ }
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /*
++ * 3. If buffer descriptor already allocated, exit with iapi_errno filled
++ */
++ if (local_ccb_p->baseBDptr != DMA_ADDR_INVALID) {
++ int result = IAPI_ERR_BD_ALLOCATED;
++
++ bd_p = iapi_Phys2Virt(local_ccb_p->baseBDptr);
++ if (bd_p == NULL) {
++ iapi_errno = IAPI_ERR_BD_ALLOCATION;
++ return -iapi_errno;
++ }
++ DBG(0, "%s: bd_p=%p phys=%08x\n", __FUNCTION__, bd_p, local_ccb_p->baseBDptr);
++ for (index = 1; index < local_cd_p->bufferDescNumber; index++) {
++ if ((bd_p->mode.status & BD_DONE) == BD_DONE) {
++ /* complete the lowest bits with the number of 'D' bits set */
++ result++;
++ }
++ bd_p++;
++ }
++ iapi_errno = result;
++ iapi_ReleaseChannel(channelNumber);
++ return -iapi_errno;
++ }
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /*
++ * 4. Buffer Descriptors allocation
++ */
++ iapi_InitializeMemory(local_ccb_p);
++
++#ifdef MCU
++ /*
++ * 5. Channel's configuration properties (mcu side only)
++ */
++ iapi_ChannelConfig(channelNumber,
++ (local_cd_p->ownership >> CH_OWNSHP_OFFSET_EVT) & 1,
++ (local_cd_p->ownership >> CH_OWNSHP_OFFSET_MCU) & 1,
++ (local_cd_p->ownership >> CH_OWNSHP_OFFSET_DSP) & 1);
++#endif /* MCU */
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /* Setting interrupt handling */
++ iapi_ChangeCallbackISR(local_cd_p, local_cd_p->callbackISR_ptr);
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /* Call initialization fn for polling synch on this channel */
++ INIT_SLEEP(channelNumber);
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /* No user arg pointer yet */
++ userArgTable[cd_p->channelNumber] = NULL;
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ /*
++ * 6. read/write direction => enable/disable channel
++ */
++#ifdef MCU
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++#if 1
++ __raw_writel(1, SDMA_CHNPRI(channelNumber));
++#else
++ channelPriorityMatx = &SDMA_CHNPRI_0;
++ channelPriorityMatx[channelNumber] = 1;
++#endif
++#endif /* MCU */
++
++ DBG(0, "%s@%d: \n", __FUNCTION__, __LINE__);
++ local_ccb_p->status.openedInit = TRUE;
++ iapi_ReleaseChannel(channelNumber);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/** Attempts to read nbyte from the data buffer descriptor associated with the
++ * channel channelNumber, into the user's data buffer pointed to by buf.
++ *
++ * <b>Algorithm:</b>\n
++ * - Check data structures are properly initialized:
++ * - Channel descriptor validity
++ * - Control block & Descriptor associated with the channel being worked on
++ * - Check initialization has been done for trusted channels
++ * - If transfer data size is used, check validity of combination transfer
++ * size/requested bytes
++ * - Set the 'D' done bits on all buffer descriptors
++ * - Starting of the channel
++ * - Synchronization mechanism handling:
++ * - for callback: just exit function
++ * - for polling: call the synchronization function then read data from
++ * buffer until either nbyte parameter is reached or all buffer descriptors
++ * have been processed.
++ *
++ * <b>Notes:</b>\n
++ * 1) Virtual DMA SDMA channels are unidirectional, an iapi_Read authorized
++ * on a channel means that we are expecting to receive from the SDMA. The
++ * meaning of an interrupt received from the SDMA is therefore that the
++ * data has been copied from the SDMA to the host's data buffers and is
++ * already passed on upper layers of the application.\n
++ *
++ * @param *cd_p chanenl descriptor for the channel to read from
++ * @param *buf buffer to receive the data
++ * @param nbyte number of bytes to read from channel
++ *
++ * @return
++ * - number of bytes read
++ * - -iapi_errno : in case of failure return negated value of iapi_errno
++ */
++int
++iapi_Read(channelDescriptor *cd_p, void *buf, unsigned short nbyte)
++{
++ int index;
++ int readBytes;
++ int toRead;
++ unsigned int copyFinished;
++ unsigned int bufsize;
++ bufferDescriptor *bd_p;
++ channelControlBlock *ccb_p;
++ unsigned char *local_buf;
++ unsigned char chNum;
++ unsigned char div;
++
++ iapi_errno = IAPI_ERR_NO_ERROR;
++
++ /*
++ * 1. Check data structures are properly initialized
++ */
++ /* Channel descriptor validity */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Channel control block validity */
++ if (cd_p->ccb_ptr == NULL) {
++ iapi_errno = IAPI_ERR_CCB_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Control block & Descriptor associated with the channel being worked on */
++ chNum = cd_p->channelNumber;
++ ccb_p = cd_p->ccb_ptr;
++
++ /* Try to aquire channel */
++ if (iapi_GetChannel(chNum) != 0) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | chNum;
++ return -iapi_errno;
++ }
++
++ /* Check if channel is already opened/initialized */
++ if (ccb_p->status.openedInit == FALSE) {
++ iapi_errno = IAPI_ERR_CHANNEL_UNINITIALIZED |
++ IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++
++ /* Buffer descriptor validity */
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ if (bd_p == NULL) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED |
++ IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++
++
++ /* Check initialization has been done for trusted channels */
++ if (cd_p->trust == TRUE) {
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if ((bd_p->bufferAddr == DMA_ADDR_INVALID) ||
++ (bd_p->mode.count == 0)) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED |
++ IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ }
++
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ /* If transfer data size is used, check that the required read length is
++ * divisible by transfer data size expressed in bytes
++ */
++ if (cd_p->useDataSize) {
++ /* Check for divisibility only if data size different then 8bit */
++ if (cd_p->dataSize != TRANSFER_8BIT) {
++ switch(cd_p->dataSize) {
++ case TRANSFER_32BIT:
++ div = 4;
++ break;
++ case TRANSFER_16BIT:
++ div = 2;
++ break;
++ case TRANSFER_24BIT:
++ div = 3;
++ break;
++ /* we should not get to default */
++ default:
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ /* check the total number of bytes requested */
++ if ((nbyte % div) != 0) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ /* now check the length of every BD */
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if ((bd_p->mode.count % div) != 0) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ }
++ }
++
++ /*
++ * 2. Set the 'D' done bits on all buffer descriptors
++ */
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ bd_p->mode.status |= BD_DONE;
++ bd_p++;
++ }
++
++ /*
++ * 3. Starting of the channel
++ */
++ iapi_lowStartChannel(chNum);
++ ccb_p->status.execute = TRUE;
++ readBytes = 0;
++
++ /*
++ * 4. Synchronization mechanism handling
++ */
++ if (cd_p->callbackSynch == DEFAULT_POLL) {
++ iapi_SynchChannel(chNum);
++
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ toRead = nbyte;
++ copyFinished = FALSE;
++ local_buf = buf;
++
++ /*
++ * Check the 'RROR' bit on all buffer descriptors, set error number
++ * and return IAPI_FAILURE if set.
++ */
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if (bd_p->mode.status & BD_RROR) {
++ iapi_errno = IAPI_ERR_RROR_BIT_READ | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++
++
++ /*
++ * 5. Read loop
++ */
++
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ while (!copyFinished) {
++ if (!(bd_p->mode.status & BD_DONE)) {
++ if (cd_p->trust == FALSE) {
++ bufsize = cd_p->bufferSize;
++ } else {
++ bufsize = bd_p->mode.count;
++ }
++ /* if L bit is set, read only "count" bytes and exit the loop */
++ if (bd_p->mode.status & BD_LAST) {
++ bufsize = bd_p->mode.count;
++ copyFinished = TRUE;
++ }
++ if (toRead > bufsize) {
++ if (cd_p->trust == FALSE) {
++ iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), bufsize);
++ local_buf += bufsize;
++ }
++ readBytes += bufsize;
++ toRead -= bufsize;
++ /* advance bd_p only if bit L is not set. The loop will exit anyway. */
++ if (!(bd_p->mode.status & BD_LAST)) {
++ if (bd_p->mode.status & BD_WRAP) {
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ } else if ((iapi_Phys2Virt(ccb_p->baseBDptr +
++ (cd_p->bufferDescNumber - 1) *
++ sizeof(bufferDescriptor))) != bd_p) {
++ bd_p++;
++ } else {
++ /* finished here : end of buffer descriptors */
++ copyFinished = TRUE;
++ }
++ }
++ } else {
++ if (cd_p->trust == FALSE) {
++ iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), toRead);
++ local_buf += toRead;
++ }
++ readBytes += toRead;
++ toRead = 0;
++ /* finished successfully : readBytes = nbytes */
++ copyFinished = TRUE;
++ }
++ } else {
++ /* finished here : buffer not already done */
++ copyFinished = TRUE;
++ }
++ }
++ iapi_ReleaseChannel(chNum);
++ }
++
++ /*
++ *If synchronization type is callback, the user of I.API must
++ *release the channel
++ */
++ return readBytes;
++}
++
++/****************************************************************************
++ * Attempts to write nbyte from the buffer pointed to by buf to the channel
++ * data buffers associated with the opened channel number channelNumber
++ *
++ * <b>Algorithm:</b>\n
++ *
++ * - Check data structures are properly initialized:
++ * - Channel descriptor validity
++ * - Channel control block validity
++ * - Buffer descriptor validity
++ * - If transfer data size is used, check validity of combination transfer
++ * size/requested bytes
++ * - Write loop\n
++ * Write occurs in the buffer acceded form buffer descriptor and continues
++ * to the "next" buffer which can be:\n
++ * -# the last BD of the ring so re-start from beginning\n
++ * -# the last BD of the BD array but no ring so finish\n
++ * -# (general case) the next BD in the BD array\n
++ * And copy continues until data fit in the current buffer or the nbyte
++ * parameter is reached.
++ * - Starting of the channel
++ *
++ * <b>Notes:</b>\n
++ * 1) Virtual DMA SDMA channels are unidirectionnal, an iapi_Write authorized
++ * on a channel means that we are expecting to send to the SDMA. The
++ * meaning of an interrupt received from the SDMA is therfore that the
++ * data has been delivered to the SDMA.
++ *
++ * @param *cd_p chanenl descriptor for the channel to write to
++ * @param *buf buffer with data to be written
++ * @param nbyte number of bytes to write to channel
++ *
++ * @return
++ * - number of bytes written
++ * - -iapi_errno if failure
++ */
++int
++iapi_Write(channelDescriptor *cd_p, void *buf, unsigned short nbyte)
++{
++ int writtenBytes = 0;
++ unsigned int toWrite;
++ unsigned int copyFinished;
++ unsigned int buffsize;
++ unsigned int index = 0;
++ bufferDescriptor *bd_p;
++ channelControlBlock *ccb_p;
++ unsigned char *local_buf;
++ unsigned char chNum;
++ unsigned char div;
++
++ iapi_errno = IAPI_ERR_NO_ERROR;
++
++ /*
++ * 1. Check data structures are properly initialized
++ */
++ /* Channel descriptor validity */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Channel control block validity */
++ if (cd_p->ccb_ptr == NULL) {
++ iapi_errno = IAPI_ERR_CCB_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Control block & Descriptpor associated with the channel being worked on */
++ chNum = cd_p->channelNumber;
++ ccb_p = cd_p->ccb_ptr;
++
++ /* Try to aquire channel */
++ if (iapi_GetChannel(chNum) != 0) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | chNum;
++ return -iapi_errno;
++ }
++
++ /* Buffer descriptor validity */
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ if (bd_p == NULL) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++
++ /* Check initialization has been done for trusted channels */
++ if (cd_p->trust == TRUE) {
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if ((bd_p->bufferAddr == DMA_ADDR_INVALID) || (bd_p->mode.count == 0)) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ }
++
++
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ /* If transfer data size is used, check that the required write length is
++ * divisible by transfer data size expressed in bytes
++ */
++ if (cd_p->useDataSize) {
++ /* Check for divisibility only if data size different then 8bit */
++ if (cd_p->dataSize != TRANSFER_8BIT) {
++ switch(cd_p->dataSize) {
++ case TRANSFER_32BIT:
++ div = 4;
++ break;
++ case TRANSFER_16BIT:
++ div = 2;
++ break;
++ case TRANSFER_24BIT:
++ div = 3;
++ break;
++ default:
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ /* check the total number of bytes requested */
++ if ((nbyte % div) != 0) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ /* now check the length of every BD */
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if ((bd_p->mode.count % div) != 0) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ }
++ }
++
++ /*
++ * 2. Write loop
++ */
++ local_buf = buf;
++ toWrite = nbyte;
++ copyFinished = FALSE;
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++
++ while (!copyFinished) {
++ /* variable buffsize contains the number of bytes that the SDMA
++ * will transfer at each pass of the while loop */
++ /* in NON trusted mode, buffsize is copied from Channel
++ * descriptor bufferSize (same size for all transfers) */
++
++ if (cd_p->trust == FALSE) {
++ buffsize = cd_p->bufferSize;
++ } else {
++ /* in TRUSTED mode, it's up to the user to specify the size of each buffer thru an IoCtl call */
++ /* This IoCtl has directly modified the bd_p->mode.count */
++ /* therefore, buffersize is copied from the bd_p->mode.count */
++ buffsize = bd_p->mode.count;
++ }
++ DBG(-1, "%s: nbyte=%u towrite=%u buffsize=%u\n", __FUNCTION__,
++ nbyte, toWrite, buffsize);
++
++ /* in any mode (trusted or non trusted), the transfer size must be overridden by */
++ /* "toWrite" when there is less remaining bytes to transfer than the current buffer size */
++ if (toWrite < buffsize) {
++ buffsize = toWrite;
++ }
++
++ if (!(bd_p->mode.status & BD_DONE)) {
++ /* More data to write than a single buffer can contain */
++ if (cd_p->trust == FALSE) {
++ iapi_memcpy(iapi_Phys2Virt(bd_p->bufferAddr),
++ local_buf, buffsize);
++ local_buf += buffsize;
++ }
++
++ /* update the BD count that will be used by the SDMA to transfer the proper nb of bytes */
++ bd_p->mode.count = buffsize;
++
++ bd_p->mode.status |= BD_DONE;
++ writtenBytes += buffsize;
++ toWrite -= buffsize;
++ /* Prepares access to the "next" buffer */
++ if (toWrite == 0) {
++ /* - case 1 - finished successfully : writtenBytes = nbytes */
++ copyFinished = TRUE;
++ } else if ((bd_p->mode.status & BD_WRAP)) {
++ /* - case 2 - Last BD and WRAP bit set so re-start from beginning */
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ } else if ((iapi_Phys2Virt(
++ ccb_p->baseBDptr +
++ (cd_p->bufferDescNumber - 1) *
++ sizeof(bufferDescriptor))) ==
++ bd_p) {
++ /* - case 3 - Last BD of the BD but not ring */
++ copyFinished = TRUE;
++ } else {
++ /* - case 4 - general : next BD in the BD array */
++ bd_p++;
++ }
++ } else {
++ /* finished here : buffer not already done */
++ copyFinished = TRUE;
++ }
++ }
++
++ ccb_p->currentBDptr = ccb_p->baseBDptr;
++
++ /*
++ * 3. Starting of the channel
++ */
++ iapi_lowStartChannel(chNum);
++ ccb_p->status.execute = TRUE;
++
++ if (cd_p->callbackSynch == DEFAULT_POLL) {
++ iapi_SynchChannel(chNum);
++ /*
++ * Check the 'RROR' bit on all buffer descriptors, set error number
++ * and return IAPI_FAILURE if set.
++ */
++ bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if (bd_p->mode.status & BD_RROR) {
++ iapi_errno = IAPI_ERR_RROR_BIT_WRITE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ iapi_ReleaseChannel(chNum);
++ }
++
++ /*
++ * If synchronization type is callback, the user of I.API must
++ * release the channel
++ */
++ return writtenBytes;
++}
++
++/* ***************************************************************************/
++/* This function is used to receive data from the SDMA.
++ *
++ * <b>Algorithm:</b>\n
++ *
++ * The data control structure would be copied to IPCv1 complied Buffer
++ * Descriptor Array. This array shall be allocated from non cacheable memory.
++ * It would then provide this buffer descriptor array as an input to SDMA using
++ * channel control block and then configure the Host Enable (HE) or
++ * DSP enable (DE) bit of SDMA for the channel used for this transfer depending
++ * on the source.
++ *
++ * <b>Notes:</b>\n
++ * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized
++ * on a channel means that source processor is expecting to send to the destination
++ * processor. The meaning of an interrupt received from the SDMA notifies that the
++ * data has been delivered to the destination processor.
++ *
++ * @param *cd_p chanenl descriptor for the channel to receive from
++ * @param *data_control_struct_ipcv2
++
++ * Data Control structure:
++ * -------------------------
++ * | Data Node Descriptor 1|
++ * -------------------------
++ * | Data Node Descriptor 2|
++ * -------------------------
++ * | : |
++ * | : |
++ * -------------------------
++ * |Data Node Descriptor n |
++ * -------------------------
++ *
++ * Data Node Descriptor (Buffer Descriptor):
++ *------------------------------------------------------------------------------
++ *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 Â… 0|
++ *------------------------------------------------------------------------------
++ *| L E D R R R R R |<---- Reserved ----> |<- Length-> |
++ *------------------------------------------------------------------------------
++ *| <---------------------------- Data Ptr ----------------------------------->|
++ *------------------------------------------------------------------------------
++ *
++ * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame
++ * E bit (END): If set, we reached the end of the buffers passed to the function
++ * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been
++ * filled by the SDMA.
++ * Length: Length of data pointed by this node in bytes
++ * Data Ptr: Pointer to the data pointed to by this node.
++ * The Function Shall not be called for the same channel unless the Read callback has been
++ * received for channel for which it has been called already.
++ *
++ * @return
++ * - IAPI_SUCCESS on success, IAPI_ERROR otherwise
++ *
++ *- -iapi_errno if failure
++ */
++
++int iapi_Read_ipcv2(channelDescriptor *cd_p, void *data_control_struct_ipcv2)
++{
++ channelControlBlock *ccb_p;
++/* The Parameters passed are considered to be validated by the upper layers */
++ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p;
++ dataNodeDescriptor *dnd_p = data_control_struct_ipcv2;
++
++ ccb_p = cd_p->ccb_ptr;
++ iapi_errno = IAPI_ERR_NO_ERROR;
++
++ if (ccb_p->baseBDptr == DMA_ADDR_INVALID) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ ccb_p->currentBDptr = ccb_p->baseBDptr;
++
++ /* Copy the data Node descriptor information to new BDs */
++ bd_ipcv2_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++
++ while (1) {
++ bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr;
++ bd_ipcv2_p->mode.count = dnd_p->mode.count;
++#ifdef MCU
++ bd_ipcv2_p->mode.endianness = 1;
++#endif
++#ifdef DSP
++ bd_ipcv2_p->mode.endianness = 0;
++#endif
++
++ bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK];
++
++ if ((dnd_p->mode.status & DND_END_OF_XFER) != 0) {
++ /* Break the loop at End of Transfer */
++ break;
++ }
++ bd_ipcv2_p++;
++ dnd_p++;
++ }
++ /*
++ * Store the buffer address
++ */
++ dnd_read_control_struct[cd_p->channelNumber] = data_control_struct_ipcv2;
++ /*
++ * Register the Call Back
++ */
++
++ iapi_AttachCallbackISR(cd_p, iapi_read_ipcv2_callback);
++
++ /*
++ * Starting of the channel
++ */
++ iapi_lowStartChannel(cd_p->channelNumber);
++ ccb_p->status.execute = TRUE;
++
++ return IAPI_SUCCESS;
++}
++
++
++/* ***************************************************************************/
++/*
++ * The function is used send a group of buffers to SDMA.
++ * <b>Algorithm:</b>\n
++ *
++ * The data control structure would be copied to IPCv1 complied Buffer
++ * Descriptor Array. This array shall be allocated from non cacheable memory.
++ * It would then provide this buffer descriptor array as an input to SDMA using
++ * channel control block and then configure the Host Enable (HE) or
++ * DSP enable (DE) bit of SDMA for the channel used for this transfer depending
++ * on the source.
++ * The Function Shall not be called for the same channel unless the Read callback has been
++ * received for channel for which it has been called already.
++ *
++ * <b>Notes:</b>\n
++ * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized
++ * on a channel means that source processor is expecting to send to the destination
++ * processor. The meaning of an interrupt received from the SDMA notifies that the
++ * data has been delivered to the destination processor.
++ *
++ * @param *cd_p chanenl descriptor for the channel to write to
++ * @param *data_control_struct_ipcv2
++
++ * Data Control structure:
++ * -------------------------
++ * | Data Node Descriptor 1|
++ * -------------------------
++ * | Data Node Descriptor 2|
++ * -------------------------
++ * | : |
++ * | : |
++ * -------------------------
++ * |Data Node Descriptor n |
++ * -------------------------
++ *
++ * Data Node Descriptor (Buffer Descriptor):
++ *------------------------------------------------------------------------------
++ *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 Â… 0|
++ *------------------------------------------------------------------------------
++ *| L E D R R R R R |<---- Reserved ----> |<- Length-> |
++ *------------------------------------------------------------------------------
++ *| <---------------------------- Data Ptr ----------------------------------->|
++ *------------------------------------------------------------------------------
++ *
++ * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame
++ * E bit (END): If set, we reached the end of the buffers passed to the function
++ * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been
++ * filled by the SDMA.
++ * Length: Length of data pointed by this node in bytes
++ * Data Ptr: Pointer to the data pointed to by this node.
++ *
++ *
++ * @return
++ * - iapi sucess on success.
++ * - -iapi_errno if failure
++ */
++
++int iapi_Write_ipcv2(channelDescriptor *cd_p, void *data_control_struct_ipcv2)
++{
++ channelControlBlock *ccb_p;
++/* The Parameters passed are considered to be validated by the upper layers */
++ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p;
++ dataNodeDescriptor *dnd_p = data_control_struct_ipcv2;
++ ccb_p = cd_p->ccb_ptr;
++ iapi_errno = IAPI_ERR_NO_ERROR;
++
++ if (ccb_p->baseBDptr == DMA_ADDR_INVALID) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ ccb_p->currentBDptr = ccb_p->baseBDptr;
++
++ bd_ipcv2_p = iapi_Phys2Virt(ccb_p->currentBDptr);
++ /* Copy the data Node descriptor information to new BDs */
++ while (1) {
++ bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr;
++ bd_ipcv2_p->mode.count = dnd_p->mode.count;
++
++#ifdef MCU
++ bd_ipcv2_p->mode.endianness = 1;
++#endif
++#ifdef DSP
++ bd_ipcv2_p->mode.endianness = 0;
++#endif
++
++ bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK];
++
++ if ((dnd_p->mode.status & DND_END_OF_XFER) != 0) {
++ /* Break the loop at End of Transfer */
++ break;
++ }
++ bd_ipcv2_p++;
++ dnd_p++;
++ }
++
++ /*
++ * Starting of the channel
++ */
++ iapi_lowStartChannel(cd_p->channelNumber);
++ ccb_p->status.execute = TRUE;
++
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/** Call back ISR for the IPCv2 Receive.
++ *
++ * <b>Algorithm:</b>\n
++ * - This would copy back the informationfrom IPCv1 BD to IPCv2 BD on
++ * the receiving processor
++ *
++ * @return
++ * - void
++ */
++
++static void iapi_read_ipcv2_callback(struct iapi_channelDescriptor *cd_p, void *data)
++{
++ dataNodeDescriptor *dnd_p = dnd_read_control_struct[cd_p->channelNumber];//cd_p->ccb_ptr->channelDNDBuffer;
++ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ int index;
++
++ for (index = MAX_BD_NUM - 1; index >= 0; index--) {
++ dnd_p->mode.status = 0;
++ dnd_p->mode.count = bd_ipcv2_p->mode.count;
++
++ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_DONE ? 0x00 : DND_DONE;
++ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_IPCV2_END_OF_FRAME ? DND_END_OF_FRAME : 0x00;
++ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_LAST ? DND_END_OF_XFER : 0x00;
++ cd_p->ccb_ptr->currentBDptr = iapi_Virt2Phys(bd_ipcv2_p);
++
++ if ((bd_ipcv2_p->mode.status & BD_LAST) ||
++ !(bd_ipcv2_p->mode.status & BD_CONT))
++ break;
++ dnd_p++;
++ bd_ipcv2_p++;
++ }
++
++ /* Call back the Original ISR */
++ cd_p->callbackISR_ptr(cd_p, data);
++}
++
++/* ***************************************************************************/
++/**Terminates a channel.
++ *
++ * <b>Algorithm:</b>\n
++ * - Check input parameters ans data structures
++ * - Check that all buffes have been processed (test all 'D' bits)
++ * - Stop the channel execution
++ * - Free alocated memory structures
++ * - Re-instantiate default interrupt handling
++ *
++ * @param *cd_p chanenl descriptor for the channel to close
++ *
++ * @return
++ * - IAPI_SUCCESS : OK
++ * - -iapi_errno : close failed
++ */
++int
++iapi_Close(channelDescriptor *cd_p)
++{
++ int index = 0;
++ unsigned char chNum;
++ channelControlBlock *ccb_p;
++
++ /*
++ * 1. Check input parameters ans data structures
++ */
++ if (cd_p != NULL) {
++ if (cd_p->ccb_ptr != NULL) {
++ chNum = cd_p->channelNumber;
++ ccb_p = cd_p->ccb_ptr;
++ } else {
++ iapi_errno = IAPI_ERR_NO_CCB_DEFINED | IAPI_ERR_CH_AVAILABLE;
++ return -iapi_errno;
++ }
++ } else {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE;
++ return -iapi_errno;
++ }
++ /* Try to aquire channel */
++ if (iapi_GetChannel(chNum) != 0) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | chNum;
++ return -iapi_errno;
++ }
++
++ /*
++ * 2. Check that all buffes have been processed (test all 'D' bits),
++ * only if the forceClose bit in channel descriptor is set to FALSE
++ */
++ if (ccb_p->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++
++ if (bd_p == NULL) {
++ iapi_errno = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
++ return -iapi_errno;
++ }
++ if (cd_p->forceClose == FALSE) {
++ for (index = cd_p->bufferDescNumber; index > 0; index--) {
++ if (bd_p->mode.status & BD_DONE) {
++ iapi_errno = IAPI_ERR_CLOSE | IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_ReleaseChannel(chNum);
++ return -iapi_errno;
++ }
++ bd_p++;
++ }
++ } else {
++ /* if the closing is forced, mark channel unused and
++ * set BD ownership to processor
++ */
++ ccb_p->status.execute = FALSE;
++ for (index = cd_p->bufferDescNumber; index > 0; index--) {
++ bd_p->mode.status &= ~BD_DONE;
++ bd_p++;
++ }
++ }
++ }
++
++ /*
++ * 3. Stop the channel execution
++ */
++ iapi_lowStopChannel(chNum);
++
++ /*
++ * 4. Free alocated memory structures
++ */
++ if (cd_p->trust == FALSE && ccb_p->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bd_p = iapi_Phys2Virt(ccb_p->baseBDptr);
++
++ for (index = cd_p->bufferDescNumber; index > 0; index--) {
++ FREE(iapi_Phys2Virt(bd_p->bufferAddr));
++ bd_p++;
++ }
++ }
++
++ /*
++ * 5. Re-instantiate default interrupt handling
++ */
++ iapi_DetachCallbackISR(cd_p);
++ if (ccb_p->baseBDptr != DMA_ADDR_INVALID) {
++ FREE(iapi_Phys2Virt(ccb_p->baseBDptr));
++ ccb_p->baseBDptr = DMA_ADDR_INVALID;
++ ccb_p->currentBDptr = DMA_ADDR_INVALID;
++ }
++ FREE(cd_p);
++ ccb_p->channelDescriptor = NULL;
++ ccb_p->status.openedInit = FALSE;
++
++ iapi_ReleaseChannel(chNum);
++
++ return IAPI_SUCCESS;
++}
++
++static inline int iapi_clr_status(channelDescriptor *cd_p, unsigned long param,
++ unsigned long mask)
++{
++ int retvalue = IAPI_SUCCESS;
++ bufferDescriptor *bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ if (param == SET_BIT_ALL) {
++ int j;
++
++ for (j = 0; j < cd_p->bufferDescNumber; j++) {
++ bde_p->mode.status &= ~mask;
++ bde_p++;
++ }
++ } else if (param < cd_p->bufferDescNumber) {
++ bde_p[param].mode.status &= ~mask;
++ } else {
++ retvalue = IAPI_FAILURE;
++ }
++ return retvalue;
++}
++
++static inline int iapi_set_status(channelDescriptor *cd_p, unsigned long param,
++ unsigned long mask)
++{
++ int retvalue = IAPI_SUCCESS;
++ bufferDescriptor *bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ if (param == SET_BIT_ALL) {
++ int j;
++
++ for (j = 0; j < cd_p->bufferDescNumber; j++) {
++ bde_p->mode.status |= mask;
++ bde_p++;
++ }
++ } else if (param < cd_p->bufferDescNumber) {
++ bde_p[param].mode.status |= mask;
++ } else {
++ retvalue = IAPI_FAILURE;
++ }
++ return retvalue;
++}
++
++static inline int iapi_set_command(channelDescriptor *cd_p, unsigned long param,
++ unsigned long cmd)
++{
++ int retvalue = IAPI_SUCCESS;
++ bufferDescriptor *bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ if (param == SET_BIT_ALL) {
++ int j;
++
++ for (j = 0; j < cd_p->bufferDescNumber; j++) {
++ bde_p->mode.command = cmd;
++ bde_p++;
++ }
++ } else if (param < cd_p->bufferDescNumber) {
++ bde_p[param].mode.command = cmd;
++ } else {
++ retvalue = IAPI_FAILURE;
++ }
++ return retvalue;
++}
++
++/* ***************************************************************************/
++/**The request argument selects the control function to be performed.
++ *
++ * <b>Algorithm:</b>\n
++ *
++ * - Check data structures are properly initialized:
++ * - Channel descriptor validity
++ * - Channel control block validity
++ * - The ctlRequest parameter contains in the lower 16 bits the control code of
++ * the change to be performed, and in the upper 16 bits, the BD to be
++ * modified if the change affects a BD od the channel.
++ * - Selection of the parameter to change and appropriate sanity checks:
++ * - Channel Descriptor: changes the pointer to the channel descriptor
++ * structure, the pointer to the new channel descriptor is given in the third
++ * argument call
++ * - Buffer Descriptor Number: changes the number of buffer descriptor for the
++ * channel
++ * - Buffer size: changes the size of the data buffers pointed to by the
++ * buffer descriptor; note that all buffer descriptors are assumed to have the
++ * same size for a given buffer descripotr chain
++ * - Blocking policy: changes the blocking policy for the read and write calls
++ * - Ownership: changes direction: turnaround
++ * - Synchronization method: changes the callback type, default or user. The *
++ * callback function table is set accordingly
++ * - Trust property: trust can only be changed through ChangeChannelDesc first
++ * request, this guarantees the close/open sequence for the channel
++ * - Callback Interrupt service routine pointer: changes the callback function
++ * pointer, when this method is used, to replace it with a new one
++ * - Channel control block pointer: not available
++ * - Priority: changes the channel priority directly in SDMA register
++ * - Watermark level: changes the value of the peripheral watermark level that
++ * passed to the script. The new value is passed in the third parameter call.
++ * - Wrap bit: changes to set to 1 the Wrap bit of the last buffer descriptor
++ *
++ * @param *cd_p channel descriptor for the channel to modify
++ * @param ctlRequest request control code and, if tha case, number of BD to be
++ * changed
++ * @param param parameter for the modification
++ *
++ * @return
++ * - IAPI_SUCCESS : OK
++ * - -iapi_errno : operation failed
++ */
++int
++iapi_IoCtl(channelDescriptor *cd_p, unsigned long ctlRequest,
++ unsigned long param)
++{
++ int result = IAPI_SUCCESS;
++ unsigned char chNum;
++ unsigned long clean_ctlRequest; /* lower 16 bits of the ctlRequest */
++ unsigned long bd_num; /* upper 16 bits of the ctlRequest */
++
++ DBG(0, "%s: cd=%p req=%08lx param=%08lx\n", __FUNCTION__,
++ cd_p, ctlRequest, param);
++ /*
++ * 1. Check data structures are properly initialized
++ */
++ /* Channel descriptor validity */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Channel control block validity */
++ if (cd_p->ccb_ptr == NULL) {
++ iapi_errno = IAPI_ERR_CCB_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Control block & Descriptor associated with the channel being worked on */
++ chNum = cd_p->channelNumber;
++
++ /* Remove, if exists, BD number specified in upper bits of ctlRequest */
++ clean_ctlRequest = ctlRequest & ~BD_NUM_MASK;
++
++ /* Extract, if exists, BD number specified in upper bits of ctlRequest */
++ bd_num = (ctlRequest & BD_NUM_MASK) >> BD_NUM_OFFSET;
++
++ /* Check that the bd_num is valid */
++ if (bd_num >= cd_p->bufferDescNumber) {
++ DBG(0, "%s: BD number %lu out of range: %u\n", __FUNCTION__,
++ bd_num, cd_p->bufferDescNumber);
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | chNum;
++ return -iapi_errno;
++ }
++
++ /* All checks OK, try to aquire channel */
++ if (iapi_GetChannel(chNum) != 0) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | chNum;
++ return -iapi_errno;
++ }
++
++ /*
++ * 2. Selection of the parameter to change and appropriate sanity checks
++ */
++ switch (clean_ctlRequest) {
++ case IAPI_CHANGE_CHANDESC:
++ /*
++ * Channel Descriptor
++ * --- Changes the pointer to the channel descriptor structure: the pointer
++ * to the new channel descriptor is given in the third argument call.
++ */
++ if ((void *)param == NULL) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER;
++ result = -iapi_errno;
++ } else {
++ channelDescriptor *chParam = (channelDescriptor *)param;
++
++ if (chParam->channelNumber != chNum) {
++ /* Release ch so it can be aquired by the Close fn */
++ iapi_ReleaseChannel(chNum);
++ result = iapi_Close(cd_p);
++ if (result == IAPI_SUCCESS) {
++ FREE(cd_p);
++ iapi_AllocChannelDesc(&cd_p,
++ chParam->channelNumber);
++ iapi_memcpy(cd_p, chParam,
++ sizeof(channelDescriptor));
++ /* Channel is released allready, so Open can get the channel */
++ result = iapi_Open(cd_p,
++ chParam->channelNumber);
++ if (result != IAPI_SUCCESS) {
++ return result; /* error code already set in iapi_Open */
++ }
++ } else {
++ return result; /* error code already set in iapi_Close */
++ }
++ } else {
++ iapi_errno = IAPI_ERR_CD_CHANGE |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ result = -iapi_errno;
++ break;
++ }
++ }
++ break;
++
++ case IAPI_CHANGE_BDNUM:
++ /*
++ * Buffer Descriptor Number
++ * --- Changes the number of buffer descriptor for the channel.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, param);
++ break;
++
++ case IAPI_CHANGE_BUFFSIZE:
++ /*
++ * Buffer size
++ * --- Changes the size of the data buffers pointed to by the buffer
++ * descriptor; note that all buffer descriptors are assumed to have the
++ * same size for a given buffer descripotr chain.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, param);
++ break;
++
++ case IAPI_CHANGE_CHANBLOCK:
++ /*
++ * Blocking policy
++ * --- Changes the blocking policy for the read and write calls.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BLOCKING, param);
++ break;
++
++ case IAPI_CHANGE_OWNERSHIP:
++ /*
++ * Ownership
++ * --- Changes direction: turnaround
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_OWNERSHIP, param);
++ break;
++
++ case IAPI_CHANGE_SYNCH:
++ /*
++ * Synchronization method
++ * --- Changes the callback type, default or user. The callback function
++ * table is set accordingly.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKSYNCH, param);
++ break;
++
++ case IAPI_CHANGE_TRUST:
++ /*
++ * Trust property
++ * --- trust can only be changed through ChangeChannelDesc first request,
++ * this guarantees the close/open sequence for the channel.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, param);
++ break;
++
++ case IAPI_CHANGE_CALLBACKFUNC:
++ /*
++ * Callback Interrupt service routine pointer
++ * --- Cahnges the callback function pointer, when this method is used, to
++ * replace it with a new one.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKISR_PTR, param);
++ break;
++
++ case IAPI_CHANGE_CHANCCB:
++ /*
++ * Channel control block pointer
++ * --- NA
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_CCB_PTR, param);
++ break;
++#ifdef MCU
++ case IAPI_CHANGE_PRIORITY:
++ /*
++ * Priority
++ * --- Changes the channel priority directly in SDMA register
++ */
++ if (param < MAX_CH_PRIORITY) {
++ __raw_writel(param, SDMA_CHNPRI(cd_p->channelNumber));
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++#endif /* MCU */
++ case IAPI_CHANGE_BDWRAP:
++ /*
++ * Wrap
++ * --- Set to 1 the wrap bit of the last buffer descriptor of the array.
++ * it provides the possibility to have a circular buffer structure.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BDWRAP, param);
++ break;
++
++ case IAPI_CHANGE_WATERMARK:
++ /*
++ * Watermark
++ * --- Changes the value of the peripheral watermark level that triggers
++ * a DMA request. It impacts context of the channel, therefore channel 0
++ * must be started to update the context with this new value.
++ */
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_WML, param);
++ break;
++
++ case IAPI_CHANGE_SET_BDINTR:
++ /*
++ * INTR
++ * --- Set the INTR bit on specified BD or on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_set_status(cd_p, param, BD_INTR);
++ break;
++
++ case IAPI_CHANGE_UNSET_BDINTR:
++ /*
++ * INTR
++ * --- Unset the INTR bit on specified BD or on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_clr_status(cd_p, param, BD_INTR);
++ break;
++
++ case IAPI_CHANGE_EVTMASK1:
++ /*
++ * EventMask1
++ * --- Changes the value of the eventMask1
++ */
++ cd_p->eventMask1 = param;
++ break;
++
++ case IAPI_CHANGE_EVTMASK2:
++ /*
++ * EventMask2
++ * --- Changes the value of the eventMask2
++ */
++ cd_p->eventMask2 = param;
++ break;
++
++ case IAPI_CHANGE_PERIPHADDR:
++ /*
++ * Peripheral Address
++ * --- Changes the value of the peripheralAddr
++ */
++ cd_p->peripheralAddr = param;
++ break;
++
++ case IAPI_CHANGE_SET_BDCONT:
++ /*
++ * Cont
++ * --- Set the CONT bit on specified BD on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_set_status(cd_p, param, BD_CONT);
++ break;
++
++ case IAPI_CHANGE_UNSET_BDCONT:
++ /*
++ * Cont
++ * --- Unset the CONT bit on specified BD or on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_clr_status(cd_p, param, BD_CONT);
++ break;
++
++ case IAPI_CHANGE_SET_BDEXTD:
++ /*
++ * EXTD
++ * --- Set the EXTD bit on specified BD or on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_set_status(cd_p, param, BD_EXTD);
++ break;
++
++ case IAPI_CHANGE_UNSET_BDEXTD:
++ /*
++ * EXTD
++ * --- Unset the EXTD bit on specified BD or on all BD's if SET_BIT_ALL
++ * is passed as parameter.
++ */
++ result = iapi_clr_status(cd_p, param, BD_EXTD);
++ break;
++
++ case IAPI_CHANGE_SET_TRANSFER_CD:
++ /*
++ * TRANSFER SIZE to be used for this channel
++ * --- Set the transfer size used indicator and code for transfer size in
++ * the CD
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++ int j;
++
++ if ((param == TRANSFER_8BIT) || (param == TRANSFER_16BIT) ||
++ (param == TRANSFER_24BIT) || (param == TRANSFER_32BIT)) {
++ cd_p->useDataSize = TRUE;
++ cd_p->dataSize = param;
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ for (j = 0; j < cd_p->bufferDescNumber; j++) {
++ bde_p->mode.command = param;
++ bde_p++;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_USER_ARG:
++ /*
++ * USER_ARG
++ * --- Set the user selectable pointer to be received by the callback
++ * function, if IRQ synch is used
++ */
++ userArgTable[cd_p->channelNumber]= (void *)param;
++ break;
++
++ case IAPI_CHANGE_FORCE_CLOSE:
++ /*
++ * FORCE_CLOSE
++ * --- Set the forceClose bit in channelDescriptor to value passed in param.
++ * If this bit is TRUE, the channel in closed even if some BD are still
++ * owned by the SDMA.
++ */
++ if ((param == TRUE) || (param == FALSE)) {
++ cd_p->forceClose = param;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | cd_p->channelNumber;
++ result = -iapi_errno;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_TRANSFER:
++ /*
++ * TRANSFER type
++ * --- Set the last 2 bits in the command field of the BD to specify the
++ * transfer type 8, 16, 24, or 32 bits on all BD's, allready set in the CD
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ if ((param == TRANSFER_8BIT) || (param == TRANSFER_16BIT) ||
++ (param == TRANSFER_24BIT) || (param == TRANSFER_32BIT)) {
++ int j;
++
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ for (j = 0; j < cd_p->bufferDescNumber; j++) {
++ bde_p->mode.command = param;
++ bde_p++;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_BUFFERADDR:
++ /*
++ * BUFFER address
++ * --- Change buffer address in BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++
++ /* DO NOT translate address to physical */
++ bde_p->bufferAddr = (dma_addr_t)param;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_GET_BUFFERADDR:
++ /*
++ * BUFFER address
++ * --- Get the buffer address from the BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++ dma_addr_t *retval = (dma_addr_t *)param;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* DO NOT Translate to virtual */
++ *retval = bde_p->bufferAddr;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_EXTDBUFFERADDR:
++ /*
++ * EXTENDED BUFFER address
++ * --- Change extended buffer address in BD specified in the upper 16 bits
++ * of the ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++
++ /* DO NOT translate address to physical. The user might want something else
++ * here
++ */
++ bde_p->extBufferAddr = (dma_addr_t)param;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_GET_EXTDBUFFERADDR:
++ /*
++ * EXTENDED BUFFER address
++ * --- Get extended buffer address from the BD specified in the upper 16 bits
++ * of the ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++ dma_addr_t *retval = (dma_addr_t *)param;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++
++ /* DO NOT translate address to vitual - user knows what is here.
++ */
++ *retval = bde_p->extBufferAddr;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_COMMAND:
++ /*
++ * COMMAND field
++ * --- Change command field in BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Update command field */
++ bde_p->mode.command = param;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_GET_COMMAND:
++ /*
++ * COMMAND field
++ * --- Get the command field from the BD specified in the upper 16 bits
++ * of the ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Get the command field */
++ *((unsigned long *)param) = bde_p->mode.command;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_COUNT:
++ /*
++ * COUNT field
++ * --- Change count field in BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Update count field */
++ bde_p->mode.count = param;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_GET_COUNT:
++ /*
++ * COUNT field
++ * --- Get the count field of the BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Update count field */
++ *((unsigned long *)param) = bde_p->mode.count;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_SET_STATUS:
++ /*
++ * STATUS field
++ * --- Change status field in BD specified in the upper 16 bits of the
++ * ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Update status field */
++ DBG(1, "%s: BD[%ld] %08x->%08lx\n", __FUNCTION__,
++ bd_num, bde_p->mode.status, param);
++ bde_p->mode.status = param;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ case IAPI_CHANGE_GET_STATUS:
++ /*
++ * STATUS field
++ * --- Get the status field of the BD specified in the upper 16 bits
++ * of the ctlRequest.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ /* Get pointer to the BD structure to change */
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ /* Update status field */
++ *((unsigned long *)param) = bde_p->mode.status;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++#ifdef MCU
++ case IAPI_CHANGE_SET_ENDIANNESS:
++ /*
++ * Endianness
++ * --- Set the ENDIANNESS indicator in the command filed of the specified BD
++ * or on all BD's if SET_BIT_ALL is passed as parameter.
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ if (param == SET_BIT_ALL) {
++ int j;
++
++ for (j = 0; j < cd_p->bufferDescNumber; j++, bde_p++) {
++ /* Clear the respective bits in the command field
++ * and set the new parameter value
++ */
++ bde_p->mode.command &= ~ENDIANNESS_MASK;
++ bde_p->mode.command |= CHANGE_ENDIANNESS &
++ ENDIANNESS_MASK;
++ }
++ } else if (param < cd_p->bufferDescNumber) {
++ bde_p[param].mode.command &= ~ENDIANNESS_MASK;
++ bde_p[param].mode.command |= CHANGE_ENDIANNESS &
++ ENDIANNESS_MASK;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++#ifdef SDMA_V2
++ case IAPI_ENTER_LOCK_MODE:
++ /*
++ * SDMA State
++ * --- Enter the SDMA into LOCK Mode. No RAM update allowed except same Context
++ * update with same PC Value.
++ */
++ if (param == RESET_CLEAR_LOCK) {
++ __raw_writel(1 << RESET_CLR_BIT_OFFSET, SDMA_SDMA_LOCK);
++ __raw_writel(1 << LOCK_BIT_OFFSET, SDMA_SDMA_LOCK);
++ iapi_SdmaState = LOCK;
++ } else if (param == RESET_NOCLEAR_LOCK) {
++ __raw_writel(1 << LOCK_BIT_OFFSET, SDMA_SDMA_LOCK);
++ iapi_SdmaState = LOCK;
++ }
++ break;
++#endif
++#endif
++ case IAPI_CHANGE_SET_INTR_MASK:
++ /*
++ * Interrupt Mask
++ * --- Sets the Interrupt Mask directly in SDMA register. Can be used to set
++ * mask per channel or for all channels(SET_BIT_ALL)
++ * In case of error, the error reflects the channel number the error is received for.
++ */
++ if (param == SET_BIT_ALL) {
++ result = iapi_lowChangeIntrMask(SET_BIT_ALL, OR_OP);
++ } else {
++ /* chnum is Extracted earlier in iapi_Ioctl() and checked for validity */
++ result = iapi_lowChangeIntrMask(1 << chNum, OR_OP);
++ }
++ /* iapi_errno has been set by iapi_lowChangeIntrMask() */
++ if (result != IAPI_SUCCESS)
++ result |= IAPI_ERR_CH_AVAILABLE | chNum;
++ break;
++
++ case IAPI_CHANGE_UNSET_INTR_MASK:
++ /*
++ * Interrupt Mask
++ * --- Clears the Interrupt Mask directly in SDMA register. Can be used to clear
++ * mask per channel or for all channels(SET_BIT_ALL)
++ * In case of error, the error reflects the channel number the error is received for.
++ */
++ if (param == SET_BIT_ALL) {
++ result = iapi_lowChangeIntrMask(~SET_BIT_ALL, AND_OP);
++ } else {
++ result = iapi_lowChangeIntrMask(~(1 << chNum), AND_OP);
++ }
++ /* iapi_errno has been set by iapi_lowChangeIntrMask() */
++ if (result != IAPI_SUCCESS)
++ result |= IAPI_ERR_CH_AVAILABLE | chNum;
++ break;
++
++ case IAPI_CHANGE_BUFFER_LOCATION:
++ /* Buffer Location
++ * Set whether Buffer is located in External Memory or Internal Memory
++ */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ bufferDescriptor *bde_p;
++
++ bde_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bde_p += bd_num;
++ if ((param == EXTERNAL_MEM) || (param == INTERNAL_MEM)) {
++ /* Clear the respective bits in the command field
++ * and set the new parameter value
++ */
++ bde_p->mode.command &= ~BUFFER_LOC_MASK;
++ bde_p->mode.command |= param & BUFFER_LOC_MASK;
++ } else {
++ result = IAPI_FAILURE;
++ }
++ } else {
++ result = IAPI_FAILURE;
++ }
++ break;
++
++ default:
++ iapi_errno = IAPI_ERR_CD_CHANGE_UNKNOWN |
++ IAPI_ERR_CH_AVAILABLE | chNum;
++ result = -iapi_errno;
++ }
++
++ iapi_ReleaseChannel(chNum);
++ return result;
++}
++
++/* ***************************************************************************/
++/**Initialization of the SDMA - opening of channel 0, download RAM image.
++ *
++ * <b>Algorithm:</b>\n
++ * - open channel 0
++ * - if ram_image pointer passed is not NULL, download RAM image to SDMA
++ *
++ * @param
++ * - cd_p channel descriptor pointer for channel 0
++ * - ram_image pointer to RAM image to download, or NULL if this operation
++ * is not required
++ * - code_size size of the RAM image, in bytes
++ * - start_addr start address for the RAM image
++ *
++ * @return
++ * - IAPI_SUCCESS if all operations were successful
++ * - negated I.API error code if any operation failed
++ */
++#ifdef MCU
++int
++iapi_Init(channelDescriptor *cd_p, configs_data *config_p, unsigned short *ram_image,
++ unsigned short code_size, dma_addr_t start_addr, unsigned short channel0_addr)
++{
++#endif
++#ifdef DSP
++int
++iapi_Init(channelDescriptor *cd_p)
++{
++#endif
++ int retvalue; /* Variable to store the results from I.API calls */
++
++ /* Check initialization not allredy done */
++ if (iapi_CCBHead != NULL) {
++ iapi_errno = IAPI_ERR_NOT_ALLOWED;
++ return -iapi_errno;
++ }
++ /* Be sure SDMA has not started yet */
++#ifdef MCU
++ __raw_writel(0, SDMA_H_C0PTR);
++#endif
++#ifdef DSP
++ __raw_writel(0, SDMA_D_C0PTR);
++#endif
++
++ /* Try to open channel 0 */
++ retvalue = iapi_Open(cd_p, 0);
++ if (retvalue != IAPI_SUCCESS) {
++ return retvalue;
++ }
++#if 0
++ print_hex_dump(KERN_DEBUG, "sdma: ", DUMP_PREFIX_ADDRESS, 4, 4,
++ cd_p->ccb_ptr, CH_NUM * sizeof(channelControlBlock), 0);
++#endif
++#ifdef MCU
++ /* Set Command Channel (Channel Zero) */
++ __raw_writel(0x4000 | (channel0_addr & 0x3FFF), SDMA_CHN0ADDR);
++
++ /* Set bits of CONFIG register but with static context switching */
++ __raw_writel((config_p->dspdma << 12) | (config_p->rtdobs << 11) |
++ (config_p->acr << 4), SDMA_H_CONFIG);
++
++ /* Send the address for the host channel table to the SDMA */
++ __raw_writel(iapi_Virt2Phys(iapi_CCBHead), SDMA_H_C0PTR);
++ /* If required, download the RAM image for SDMA */
++ if (ram_image != NULL) {
++ retvalue = iapi_SetScript(cd_p, ram_image, code_size,
++ start_addr);
++ }
++
++ /* Set bits of CONFIG register with given context switching mode */
++ __raw_writel((config_p->dspdma << 12) | (config_p->rtdobs << 11) |
++ (config_p->acr << 4) | config_p->csm, SDMA_H_CONFIG);
++
++#endif
++#ifdef DSP
++ /* Send the address for the host channel table to the SDMA */
++ __raw_writel(iapi_Virt2Phys(iapi_CCBHead), SDMA_D_C0PTR);
++#endif
++
++#ifdef SDMA_V2
++ iapi_SdmaState = OPEN;
++#endif
++ return retvalue;
++}
++
++
++/* ***************************************************************************/
++/**High layer interface for starting a channel
++ *
++ * <b>Algorithm:</b>\n
++ * - call low layer function for starting a channel
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_StartChannel(unsigned char channel)
++{
++ iapi_lowStartChannel(channel);
++ return IAPI_SUCCESS;
++}
++/* ***************************************************************************/
++/**High layer interface for stopping a channel
++ *
++ * <b>Algorithm:</b>\n
++ * - call low layer function for stopping a channel
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_StopChannel(unsigned char channel)
++{
++ iapi_lowStopChannel(channel);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**High layer interface for synchronising a channel
++ *
++ * <b>Algorithm:</b>\n
++ * - call low layer function for stopping a channel
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int iapi_SynchChannel(unsigned char channel)
++{
++ iapi_lowSynchChannel(channel);
++ return IAPI_SUCCESS;
++}
++
++#ifdef MCU
++/* ***************************************************************************/
++/**High layer interface for getting program memory data from SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_GetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
++ dma_addr_t address)
++{
++ iapi_lowGetScript(cd_p, buf, size, address);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**High layer interface for getting data memory from SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_GetContext(channelDescriptor *cd_p, void *buf, unsigned char channel)
++{
++ iapi_lowGetContext(cd_p, buf, channel);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**High layer interface for set program memory data to SDMA - e.g. scripts
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_SetScript(channelDescriptor *cd_p, void *buf, unsigned short nbyte,
++ dma_addr_t destAddr)
++{
++ iapi_lowSetScript(cd_p, buf, nbyte, destAddr);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**High layer interface for set data memory to SDMA - e.g. contexts.
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_SetContext(channelDescriptor *cd_p, void *buf, unsigned char channel)
++{
++ iapi_lowSetContext(cd_p, buf, channel);
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**High layer interface used to associate specified channel with a script.
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_AssignScript(channelDescriptor *cd_p, script_data *data_p)
++{
++ /* VERIFY THAT THE CHANNEL IT IS OPENED !!!! */
++ return iapi_lowAssignScript(cd_p, data_p);
++}
++
++/* ***************************************************************************/
++/**High layer interface used to associate specified channel with a script.
++ *
++ * <b>Algorithm:</b>\n
++ * - call coresponding low layer function
++ *
++ * @return
++ * - IAPI_SUCCESS
++ */
++int
++iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map)
++{
++ return iapi_lowSetChannelEventMapping(event, channel_map);
++}
++#endif
++
++
++
++#ifdef DSP
++#define SDMA_DI SDMA_D_INTR
++void IRQ_Handler();
++#pragma interrupt IRQ_Handler
++#endif
++
++#ifdef MCU
++#define SDMA_DI SDMA_H_INTR
++#endif
++
++#ifndef IRQ_KEYWORD
++#define IRQ_KEYWORD
++#endif /* IRQ_KEYWORD */
++
++/* ***************************************************************************/
++/**
++ *@brief Find the first set bit in data parameter.
++ *
++ * Find the first set bit in unsigned integer parameter data. Data is scanned
++ * from MSB to LSB, searching for the set bit. The value returned is the
++ * offset from the most significant bit of data. If bit 31 is set, the value
++ * returned is zero. If no bits are set, a value of 32 is returned. This is compliant
++ * with the MCore FF1 instruction.
++ *
++ *
++ *
++ * @param
++ * - data: variable to check
++ *
++ * @return
++ * - the offset of the most significant bit set from the MSB
++ */
++static unsigned int
++quartz_FF1(unsigned int data)
++{
++ register unsigned int result = 0;
++ while ((result <= 31) && !(data & 0x80000000U)) {
++ data <<= 1U;
++ result++;
++ }
++
++ return result;
++}
++#ifdef DEBUG
++static void dump_chan(channelControlBlock *ccb, int chan)
++{
++ dma_addr_t bd_phys = ccb[chan].baseBDptr;
++ int i;
++
++ if (bd_phys == DMA_ADDR_INVALID)
++ return;
++
++ while (1) {
++ bufferDescriptor *bd = iapi_Phys2Virt(bd_phys);
++
++ DBG(1, "BD[%2d]@%08x count=%d CONT=%d DONE=%d WRAP=%d LAST=%d INTR=%d ERR=%d EXTD=%d\n",
++ i, iapi_Virt2Phys(bd), bd->mode.count,
++ !!(bd->mode.status & BD_CONT),
++ !!(bd->mode.status & BD_DONE),
++ !!(bd->mode.status & BD_WRAP),
++ !!(bd->mode.status & BD_LAST),
++ !!(bd->mode.status & BD_INTR),
++ !!(bd->mode.status & BD_RROR),
++ !!(bd->mode.status & BD_EXTD));
++ if (bd->mode.status & (BD_LAST | BD_WRAP)) {
++ break;
++ }
++ bd_phys += ((bd->mode.status & BD_EXTD) ?
++ SDMA_EXTENDED_BD_SIZE : SDMA_BD_SIZE);
++ i++;
++ }
++}
++
++static void dump_dma(void)
++{
++ dma_addr_t reg;
++
++ reg = __raw_readl(SDMA_H_C0PTR);
++ if (reg != DMA_ADDR_INVALID) {
++ channelControlBlock *ccb = iapi_Phys2Virt(reg);
++ int chan;
++
++ for (chan = 0; chan < CH_NUM; chan++) {
++ dump_chan(ccb, chan);
++ }
++ }
++}
++#endif // DEBUG
++
++IRQ_KEYWORD
++void
++IRQ_Handler(void)
++{
++ unsigned int intrReg;/* interrupt register mask for clearing the interrupt bit */
++ unsigned char chNum; /* SDMA channel number generating the IRQ */
++
++ /* Disable interrupts */
++ iapi_DisableInterrupts();
++ /*
++ * Clear interrupt in SDMA DI register => ACK to the SDMA the IT request.
++ * Get each interrupt number, clear them one after the other.
++ */
++ if (__raw_readl(SDMA_DI) != 0) {
++ chNum = CH_NUM - 1 - quartz_FF1(__raw_readl(SDMA_DI));
++ intrReg = 1 << chNum;
++ } else {
++ chNum = 32;
++ intrReg = 0;
++ }
++ DBG(0, "%s: SDMA_DI=%08x\n", __FUNCTION__, __raw_readl(SDMA_DI));
++#ifdef DEBUG
++ dump_dma();
++#endif
++ while (intrReg != 0) {
++ DBG(0, "%s: ACK %08x\n", __FUNCTION__, intrReg);
++ __raw_writel(intrReg, SDMA_DI);
++ iapi_SDMAIntr |= intrReg;
++ iapi_WakeUp(chNum);
++ if (callbackIsrTable[chNum] != NULL) {
++ /* release channel before callback, so IoCtl's are available */
++ iapi_ReleaseChannel(chNum);
++ callbackIsrTable[chNum](iapi_CCBHead[chNum].channelDescriptor,
++ userArgTable[chNum]);
++ }
++
++ chNum = CH_NUM - 1 - quartz_FF1(__raw_readl(SDMA_DI));
++ intrReg = 1 << chNum;
++ }
++
++ /* Enable interrupts */
++ iapi_EnableInterrupts();
++ DBG(0, "%s: Done\n", __FUNCTION__);
++}
++
++/* ***************************************************************************/
++/**
++ *@brief Perform a memory copy operation, in the memory of the same processor
++ *
++ * Size bytes are copied from the src address to dest address. It is used
++ * the channel pointed by cd_p, which must be configured prior to this call:
++ * opened, associated with the script to perform the operation - DSP_2_DSP,
++ * or MCU_2_MCU - and have the synchronization option set.
++ *
++ *
++ *
++ * @param
++ * - cd_p: channel configured to perform DSP_2_DSP or MCU_2_MCU transfers
++ * - dest: destination memory address
++ * - src : source memory address
++ * - size: number of bytes to copy from src to dest
++ *
++ * @return
++ * - the offset of the most significant bit set from the MSB
++ */
++
++int iapi_MemCopy(channelDescriptor *cd_p, void *dest, void *src, unsigned long size)
++{
++ int result = IAPI_SUCCESS;
++ bufferDescriptor *bd_p;
++
++ /* Channel descriptor validity */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* Check and set correct parameter */
++ if (cd_p->trust != TRUE) {
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, TRUE);
++ }
++
++ if (cd_p->bufferDescNumber != 1) {
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, 1);
++ if (result != IAPI_SUCCESS) {
++ return result;
++ }
++ }
++
++ if (cd_p->bufferSize != size) {
++ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, size);
++ if (result != IAPI_SUCCESS) {
++ return result;
++ }
++ }
++ /* Set addresses */
++ bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ bd_p->bufferAddr = iapi_Virt2Phys(src);
++ bd_p->extBufferAddr = iapi_Virt2Phys(dest);
++
++ /* Set mode */
++ bd_p->mode.count = size;
++ bd_p->mode.command = 0x00;
++ bd_p->mode.status = BD_INTR | BD_EXTD | BD_DONE | BD_WRAP;
++
++ /* Decide if we sleep or not */
++ if (cd_p->callbackSynch == DEFAULT_POLL) {
++ iapi_StartChannel(cd_p->channelNumber);
++ /* Call synchronization routine */
++ iapi_SynchChannel(cd_p->channelNumber);
++ } else {
++ /* Just start the channel */
++ iapi_StartChannel(cd_p->channelNumber);
++ }
++
++ return result;
++}
++
++/* ***************************************************************************/
++/**Return the channel number from the channel descriptor
++ *
++ * @param cd_p pointer to channel descriptor to obtain the channel number
++ *
++ * @return
++ * - the channel number
++ *
++ */
++int iapi_GetChannelNumber(channelDescriptor *cd_p)
++{
++ return cd_p->channelNumber;
++}
++
++/* ***************************************************************************/
++/**Return the error bit from the current BD of the channel
++ *
++ *
++ * @param cd_p pointer to channel descriptor
++ *
++ * @return
++ * - 0 if no error detected
++ * - BD_RROR | DATA_ERROR if error detected
++ *
++ */
++unsigned long iapi_GetError(channelDescriptor *cd_p)
++{
++ bufferDescriptor *bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->currentBDptr);
++
++ if (bd_p == NULL)
++ return -EINVAL;
++
++ return (bd_p->mode.status & BD_RROR) |
++ cd_p->ccb_ptr->status.data_error;
++}
++
++/* ***************************************************************************/
++/**Return the count from the current BD of the channel
++ *
++ *
++ * @param cd_p pointer to channel descriptor
++ *
++ * @return
++ * - count field of the current BD for the channel
++ *
++ */
++int iapi_GetCount(channelDescriptor *cd_p)
++{
++ bufferDescriptor *bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->currentBDptr);
++
++ if (bd_p == NULL)
++ return -EINVAL;
++
++ return bd_p->mode.count;
++}
++
++/* ***************************************************************************/
++/**Return the sum of counts for all the BD's owned by the processor for
++ * the channel specified by the received parameter.
++ *
++ *
++ * @param cd_p pointer to channel descriptor
++ *
++ * @return
++ * - sum of count fields
++ *
++ */
++int iapi_GetCountAll(channelDescriptor *cd_p)
++{
++ int retval = 0;
++ int i;
++ bufferDescriptor *bd_p;
++
++ bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ for (i = 0; i < cd_p->bufferDescNumber &&
++ !(bd_p->mode.status & BD_DONE); i++, bd_p++) {
++ retval += bd_p->mode.count;
++ }
++ return retval;
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c 2010-12-03 09:51:55.404347330 +0100
+@@ -0,0 +1,153 @@
++/******************************************************************************
++ *
++ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiLow.c
++ *
++ * $Id iapiLow.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the LOW level functions of the I.API.
++ *
++ *
++ * /
++ *
++ * $Log iapiLow.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <linux/kernel.h>
++
++#include <epm.h>
++#include <iapiLow.h>
++
++/**
++ * Function Section
++ */
++
++
++/* ***************************************************************************/
++/**Records an ISR callback function pointer into the ISR callback
++ * function table
++ *
++ * @param cd_p channel descriptor to attach callback to
++ * @param func_p pointer to the callback function to be registered
++ *
++ * @return none
++ */
++void
++iapi_AttachCallbackISR(channelDescriptor *cd_p, CallbackISR func_p)
++{
++ if (cd_p->callbackSynch == CALLBACK_ISR) {
++ iapi_DisableInterrupts();
++ callbackIsrTable[cd_p->channelNumber] = func_p;
++ iapi_EnableInterrupts();
++ } else if (cd_p->callbackSynch == DEFAULT_POLL) {
++ callbackIsrTable[cd_p->channelNumber] = NULL;
++ } else {
++ iapi_errno = IAPI_ERR_CALLBACKSYNCH_UNKNOWN |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ WARN_ON(1);
++ }
++}
++
++
++/* ***************************************************************************/
++/**Detaches (removes) an ISR callback function pointer from the ISR callback
++ * function table
++ *
++ * <b>Algorithm:</b>\n
++ * - Attach a null function to replace the original one.
++ *
++ * @param cd_p channel descriptor to detach callback from
++ *
++ * @return none
++ */
++void
++iapi_DetachCallbackISR(channelDescriptor *cd_p)
++{
++ iapi_AttachCallbackISR(cd_p, NULL);
++}
++
++/* ***************************************************************************/
++/**Updates an ISR callback function pointer into the ISR callback function
++ * table
++ *
++ * <b>Algorithm:</b>\n
++ * - Detach the old function pointer (if any) and attach the new one
++ *
++ * @param cd_p channel descriptor to attach callback to
++ * @param func_p pointer to the callback function to be registered
++ *
++ * @return none
++ */
++void
++iapi_ChangeCallbackISR(channelDescriptor *cd_p, CallbackISR func_p)
++{
++ iapi_DetachCallbackISR(cd_p);
++ iapi_AttachCallbackISR(cd_p, func_p);
++}
++
++/* ***************************************************************************/
++/**Loop while the channel is not done on the SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - Loop doing nothing but checking the I.API global variable to indicate
++ * that the channel has been completed (interrupt from SDMA)
++ *
++ * <b>Notes:</b>\n
++ * - The ISR must update the I.API global variable iapi_SDMAIntr.
++ *
++ * @param channel channel number to poll on
++ *
++ * @return none
++ */
++void
++iapi_lowSynchChannel(unsigned char channel)
++{
++ //while (!((1UL << channel) & iapi_SDMAIntr));
++ GOTO_SLEEP(channel);
++ DBG(0, "%s: Done: %08lx->%08lx\n", __FUNCTION__, iapi_SDMAIntr,
++ iapi_SDMAIntr & ~(1 << channel));
++ iapi_SDMAIntr &= ~(1 << channel);
++}
++
++/* ***************************************************************************/
++/**Fill the buffer descriptor with the values given in parameter.
++ *
++ * @return none
++ */
++void
++iapi_SetBufferDescriptor(bufferDescriptor *bd_p, unsigned char command,
++ unsigned char status, unsigned short count,
++ void *buffAddr, dma_addr_t extBufferAddr)
++{
++ bd_p->mode.command = command;
++ bd_p->mode.status = status;
++ bd_p->mode.count = count;
++ if (buffAddr != NULL) {
++ bd_p->bufferAddr = iapi_Virt2Phys(buffAddr);
++ } else {
++ bd_p->bufferAddr = DMA_ADDR_INVALID;
++ }
++ bd_p->extBufferAddr = extBufferAddr;
++}
++
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c 2010-12-03 09:51:55.404347330 +0100
+@@ -0,0 +1,79 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiLowDsp.c
++ *
++ * $Id iapiLowDsp.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the LOW level functions of the I.API specific to MCU.
++ *
++ *
++ *
++ *
++ * $Log iapiLowDsp.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include "epm.h"
++#include "iapiLow.h"
++
++/* ****************************************************************************
++ * Function Section
++ *****************************************************************************/
++#ifdef DSP
++
++/* ***************************************************************************/
++/**Starts the channel (core specific register)
++ *
++ * <b>Algorithm:</b>\n
++ * - Bit numbered "channel" of DspEnStartReg register is set
++ *
++ * @param channel channel to start
++ *
++ * @return none
++ */
++void
++iapi_lowStartChannel (unsigned char channel)
++{
++ SDMA_D_START |= (1 << channel);
++}
++
++/* ***************************************************************************/
++/**Stops the channel (core specific register)
++ *
++ * <b>Algorithm:</b>
++ * - Bit numbered "channel" of DspEnStopReg register is cleared
++ *
++ * <b>Notes:</b>\n
++ * - This is a write one to clear register
++ *
++ * @param channel channel to stop
++ *
++ * @return none
++ */
++void
++iapi_lowStopChannel (unsigned char channel)
++{
++ SDMA_D_STATSTOP &= (1 << channel);
++}
++
++#endif /* DSP */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c 2010-12-03 09:51:55.408346904 +0100
+@@ -0,0 +1,545 @@
++/******************************************************************************
++ *
++ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiLowMcu.c
++ *
++ * $Id iapiLowMcu.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the LOW level functions of the I.API specific to MCU.
++ *
++ *
++ * http://compass/mot.com/go/115342679
++ *
++ * $Log iapiLowMcu.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <string.h>
++#include <linux/io.h>
++
++#include <epm.h>
++#include <iapiLow.h>
++
++/* ****************************************************************************
++ * Function Section
++ *****************************************************************************/
++#ifdef MCU
++
++/* ***************************************************************************/
++/**Send a command on SDMA's channel zero.
++ * Check if buffer descriptor is already used by the sdma, if yes return
++ * an error as c0BDNum is wrong.
++ *
++ * <b>Notes</b>\n
++ * There is an upgrade in the script on the Context load command and
++ * the fact that the context structure has a fixed length of 20 or 24
++ * depending on SDMA versions.
++ *
++ * @return
++ * - IAPI_SUCCESS
++ * - -iapi_errno if failure
++ */
++int
++iapi_Channel0Command(channelDescriptor *cd_p, void *buf,
++ unsigned short nbyte, unsigned char command)
++{
++ channelControlBlock *ccb_p;
++ bufferDescriptor *bd_p;
++ int result = IAPI_SUCCESS;
++ unsigned char chNum;
++
++ /*
++ * Check data structures are properly initialized
++ */
++ /* Channel descriptor validity */
++ if (cd_p == NULL) {
++ result = IAPI_ERR_CD_UNINITIALIZED;
++ iapi_errno = result;
++ return -result;
++ }
++
++ /* Channel control block validity */
++ if (cd_p->ccb_ptr == NULL) {
++ result = IAPI_ERR_CCB_UNINITIALIZED;
++ iapi_errno = result;
++ return -result;
++ }
++
++ /* Control block & Descriptpor associated with the channel being worked on */
++ chNum = cd_p->channelNumber;
++ ccb_p = cd_p->ccb_ptr;
++
++ /* Is channel already in use ? */
++ if (ccb_p->baseBDptr != DMA_ADDR_INVALID) {
++ result = IAPI_ERR_BD_ALLOCATED | IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_errno = result;
++ return -result;
++ }
++
++ /* Allocation of buffer descriptors */
++ bd_p = MALLOC(sizeof(bufferDescriptor));
++ if (bd_p != NULL) {
++ ccb_p->baseBDptr = iapi_Virt2Phys(bd_p);
++ } else {
++ result = IAPI_ERR_BD_ALLOCATION | IAPI_ERR_CH_AVAILABLE | chNum;
++ iapi_errno = result;
++ return -result;
++ }
++
++ /* Buffer descriptor setting */
++ iapi_SetBufferDescriptor(bd_p, command, BD_WRAP | BD_DONE | BD_INTR,
++ nbyte, buf, DMA_ADDR_INVALID);
++
++ /* Actually the transfer */
++ iapi_lowStartChannel(cd_p->channelNumber);
++ iapi_lowSynchChannel(cd_p->channelNumber);
++
++ /* Cleaning of allocation */
++ FREE(bd_p);
++ ccb_p->baseBDptr = DMA_ADDR_INVALID;
++
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**Changes the interrupt Mask (core specific register)
++ *
++ * Algorithm:
++ * - Program value as per the passed in arguments to the core-specific Interrupt Mask Reg.
++ *
++ * @param
++ * Value to be AND-ed or Or-ed with the interrupt Mask reg
++ * @op
++ * Operation(AND or OR) to be performed on the Interrupt Mask Reg.
++ * @return
++ * - IAPI_SUCCESS
++ * - iapi_errno if failure
++ */
++int
++iapi_lowChangeIntrMask(unsigned int param, unsigned char op)
++{
++ switch (op) {
++ case OR_OP:
++ __raw_writel(__raw_readl(SDMA_H_INTRMSK) | param, SDMA_H_INTRMSK);
++ break;
++ case AND_OP:
++ __raw_writel(__raw_readl(SDMA_H_INTRMSK) & ~param, SDMA_H_INTRMSK);
++ break;
++ default:
++ iapi_errno = IAPI_ERR_NOT_ALLOWED;
++ return iapi_errno;
++ }
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**Starts the channel (core specific register)
++ *
++ * <b>Algorithm:</b>\n
++ * - Bit numbered "channel" of HostEnStartReg register is set
++ *
++ * @param channel channel to start
++ *
++ * @return none
++ */
++void
++iapi_lowStartChannel(unsigned char channel)
++{
++ DBG(0, "%s: %p: %08x->%08x\n", __FUNCTION__, SDMA_H_START,
++ __raw_readl(SDMA_H_START), __raw_readl(SDMA_H_START) | (1 << channel));
++ __raw_writel(__raw_readl(SDMA_H_START) | (1 << channel), SDMA_H_START);
++}
++
++/* ***************************************************************************/
++/**Stops the channel (core specific register)
++ *
++ * <b>Algorithm:</b>
++ * - Bit numbered "channel" of HostEnStopReg register is cleared
++ *
++ * <b>Notes:</b>\n
++ * - This is a write one to clear register
++ *
++ * @param channel channel to stop
++ *
++ * @return none
++ */
++void
++iapi_lowStopChannel(unsigned char channel)
++{
++ DBG(0, "%s: %p: %08x->%08x\n", __FUNCTION__, SDMA_H_STATSTOP,
++ __raw_readl(SDMA_H_STATSTOP), __raw_readl(SDMA_H_STATSTOP) & ~(1 << channel));
++ __raw_writel(1 << channel, SDMA_H_STATSTOP);
++}
++
++/* ***************************************************************************/
++/**Initialize the initial priority of registers and channel enable
++ * RAM from the MCU side. No channels are enabled, all priorities are set to 0.
++ *
++ * @return none
++ */
++void
++iapi_InitChannelTables(void)
++{
++ int i;
++
++ /* No channel is enabled */
++ for (i = 0; i < EVENTS_NUM; i++) {
++ __raw_writel(0, SDMA_CHNENBL_0 + (i << 2));
++ }
++ //iapi_memset((void *)&SDMA_CHNENBL_0, 0x00, sizeof(unsigned long) * EVENTS_NUM);
++
++ /* All channels have priority 0 */
++ for (i = 0; i < EVENTS_NUM; i++) {
++ __raw_writel(0, SDMA_CHNPRI_0 + (i << 2));
++ }
++ //iapi_memset((void *)&SDMA_CHNPRI_0, 0x00, sizeof(unsigned long) * CH_NUM);
++}
++
++/* ***************************************************************************/
++/** The host enable (HE), hosts override (HO), dsp enable (DE), dsp override
++ * (DO) registers are involved here.
++ * Host and Dsp enable registers are here to signify that the MCU or DSP side
++ * have prepared the appropriate buffers and are now ready. If the channel is
++ * owned by the MCU the override bit for that channel needs to be cleared :
++ * the host allows the channel to be used.\n
++ *
++ * Then the override bits can define (mcuOverride dspOverride):\n
++ * - 0 0 channel is public: transfer to/from MCU to DSP
++ * - 0 1 channel if owned by DSP
++ * - 1 0 channel if owned by MCU
++ * - 1 1 channel zero config
++ *
++ * See also :\n
++ * IAPI Table 1.1 "Channel configuration properties"
++ *
++ * @param channel channel to configure
++ * @param eventOverride event ownership
++ * @param mcuOverride ARM ownership
++ * @param dspOverride DSP ownership
++ *
++ * @return
++ * - -iapi_errno if the 3 override parameters are all set
++ * - IAPI_SUCCESS in other cases (valid cases)
++ */
++int
++iapi_ChannelConfig(unsigned char channel, unsigned eventOverride,
++ unsigned mcuOverride, unsigned dspOverride)
++{
++ int result = IAPI_SUCCESS;
++
++ if (eventOverride &&
++ mcuOverride &&
++ dspOverride) {
++ result = IAPI_ERR_CONFIG_OVERRIDE;
++ iapi_errno = result;
++ return -result;
++ } else {
++ /*
++ * DSP side
++ */
++ if (dspOverride) {
++ __raw_writel(__raw_readl(SDMA_H_DSPOVR) &
++ ~(1 << channel), SDMA_H_DSPOVR);
++ } else {
++ __raw_writel(__raw_readl(SDMA_H_DSPOVR) |
++ (1 << channel), SDMA_H_DSPOVR);
++ }
++ /*
++ * Event
++ */
++ if (eventOverride) {
++ __raw_writel(__raw_readl(SDMA_H_EVTOVR) &
++ ~(1 << channel), SDMA_H_EVTOVR);
++ } else {
++ __raw_writel(__raw_readl(SDMA_H_EVTOVR) |
++ (1 << channel), SDMA_H_EVTOVR);
++ }
++ /*
++ * MCU side
++ */
++ if (mcuOverride) {
++ __raw_writel(__raw_readl(SDMA_H_HOSTOVR) &
++ ~(1 << channel), SDMA_H_HOSTOVR);
++ } else {
++ __raw_writel(__raw_readl(SDMA_H_HOSTOVR) |
++ (1 << channel), SDMA_H_HOSTOVR);
++ }
++ }
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**Load the context data of a channel from SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - Setup BD with appropiate parameters
++ * - Start channel
++ * - Poll for answer
++ *
++ * @param *cd_p channel descriptor for channel 0
++ * @param *buf pointer to receive context data
++ * @param channel channel for which the context data is requested
++ *
++ * @return none
++ */
++void
++iapi_lowGetContext(channelDescriptor *cd_p, void *buf, unsigned char channel)
++{
++ bufferDescriptor *bd_p;
++
++ bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ /* Setup buffer descriptor with channel 0 command */
++ iapi_SetBufferDescriptor(&bd_p[0],
++ C0_GETDM,
++ BD_DONE | BD_INTR | BD_WRAP | BD_EXTD,
++ sizeof(contextData) / 4,
++ buf,
++ CHANNEL_CONTEXT_BASE_ADDRESS + sizeof(contextData) * channel / 4);
++ /* Receive, polling method */
++ iapi_lowStartChannel(cd_p->channelNumber);
++ iapi_lowSynchChannel(cd_p->channelNumber);
++}
++
++/* ***************************************************************************/
++/**Read "size" byte /2 at SDMA address (address) and write them in buf
++ *
++ * <b>Algorithm:</b>\n
++ * - Setup BD with appropiate parameters (C0_GETPM)
++ * - Start channel
++ * - Poll for answer
++ *
++ * <b>Notes</b>\n
++ * - Parameter "size" is in bytes, it represents the size of "buf", e.g.
++ * the size in bytes of the script to be loaded.
++ * - Parameter "address" denotes the RAM address for the script in SDMA
++ *
++ * @param *cd_p channel descriptor for channel 0
++ * @param *buf pointer to receive the data
++ * @param size number of bytes to read
++ * @param address address in SDMA RAM to start reading from
++ *
++ * @return none
++ */
++void
++iapi_lowGetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
++ dma_addr_t address)
++{
++ bufferDescriptor *bd_p;
++
++ bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ /* Setup buffer descriptor with channel 0 command */
++ iapi_SetBufferDescriptor(&bd_p[0],
++ C0_GETPM,
++ BD_DONE | BD_INTR | BD_WRAP | BD_EXTD,
++ size / 2, /* count in shorts */
++ buf,
++ address);
++ /* Receive, polling method*/
++ iapi_lowStartChannel(cd_p->channelNumber);
++ iapi_lowSynchChannel(cd_p->channelNumber);
++}
++
++/* ***************************************************************************/
++/**Load a SDMA script to SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - Setup BD with appropiate parameters (C0_SETPM)
++ * - Start channel
++ * - Poll for answer
++ *
++ * <b>Notes</b>\b
++ * - Parameter "size" is in bytes, it represents the size of "buf", e.g.
++ * the size in bytes of the script to be uploaded.
++ * - Parameter "address" denotes the RAM address for the script in SDMA
++ *
++ * @param *cd_p channel descriptor for channel 0
++ * @param *buf pointer to the script
++ * @param size size of the script, in bytes
++ * @param address address in SDMA RAM to place the script
++ *
++ * @return none
++ */
++void
++iapi_lowSetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
++ dma_addr_t address)
++{
++ bufferDescriptor *bd_p;
++
++ bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ /* Setup buffer descriptor with channel 0 command */
++ iapi_SetBufferDescriptor(&bd_p[0],
++ C0_SETPM,
++ BD_DONE | BD_INTR | BD_WRAP | BD_EXTD,
++ size / 2, /* count in shorts */
++ buf,
++ address);
++ /* Receive, polling method*/
++ iapi_lowStartChannel(cd_p->channelNumber);
++ iapi_lowSynchChannel(cd_p->channelNumber);
++}
++
++/* ***************************************************************************/
++/**Load the context for a channel to SDMA
++ *
++ * <b>Algorithm:</b>\n
++ * - Send context and poll for answer.
++ *
++ * @param *cd_p channel descriptor for channel 0
++ * @param *buf pointer to context data
++ * @param channel channel to place the context for
++ *
++ * @return none
++ */
++void
++iapi_lowSetContext(channelDescriptor *cd_p, void *buf, unsigned char channel)
++{
++
++ bufferDescriptor *local_bd_p;
++#ifdef SDMA_V2
++ local_bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ iapi_SetBufferDescriptor(&local_bd_p[0],
++ (channel << 3) | C0_SETCTX,
++ BD_DONE | BD_INTR | BD_WRAP,
++ sizeof(contextData) / 4,
++ buf,
++ DMA_ADDR_INVALID);
++#else
++
++ local_bd_p = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++
++ iapi_SetBufferDescriptor(&local_bd_p[0],
++ C0_SETDM,
++ BD_DONE | BD_INTR | BD_WRAP | BD_EXTD,
++ sizeof(contextData) / 4,
++ buf,
++ (2048 + (sizeof(contextData) / 4) * channel));
++#endif
++ /* Send */
++ iapi_lowStartChannel(cd_p->channelNumber);
++ iapi_lowSynchChannel(cd_p->channelNumber);
++}
++
++/* ***************************************************************************/
++/**Associate specified channel with the script starting at the
++ * specified address. Channel 0 command is used to load the set-up context
++ * for the channel. The address used must be generated by the GUI tool
++ * used to create RAM images for SDMA.
++ *
++ * <b>Algorithm:</b>\n
++ * - Set-up and load the context.
++ *
++ * @param *cd_p pointer to the channel descriptor of the channel
++ * @param *data_p: pointer to the data identifying the script to be associated
++ * with the channel
++ *
++ * @return
++ * - IAPI_SUCCESS : OK
++ * - -iapi_errno : operation failed, return negated value of iapi_errno
++ */
++
++int
++iapi_lowAssignScript(channelDescriptor *cd_p, script_data *data_p)
++{
++ contextData *chContext; /* context to be loaded for the channel */
++ channelDescriptor *cd0_p; /* pointer to channel descriptor of channel 0 */
++ int result = IAPI_SUCCESS;
++
++ /* Verify passed data */
++ if (cd_p == NULL || data_p == NULL) {
++ result = IAPI_ERR_INVALID_PARAMETER;
++ iapi_errno = result;
++ return -result;
++ }
++
++ /* Allocate context and initialize PC to required script start adress*/
++ chContext = MALLOC(sizeof(contextData));
++ if (chContext == NULL) {
++ result = IAPI_ERR_B_ALLOC_FAILED | cd_p->channelNumber;
++ iapi_errno = result;
++ return -result;
++ }
++
++ iapi_memset(chContext, 0x00, sizeof(contextData));
++ chContext->channelState.pc = data_p->load_address;
++
++ /* Send by context the event mask,base address for peripheral
++ * and watermark level
++ */
++ chContext->gReg[0] = data_p->event_mask2;
++ chContext->gReg[1] = data_p->event_mask1;
++ chContext->gReg[6] = data_p->shp_addr;
++ chContext->gReg[7] = data_p->wml;
++
++ /* Set transmited data to the CD */
++ cd_p->watermarkLevel = data_p->wml;
++ cd_p->eventMask1 = data_p->event_mask1;
++ cd_p->eventMask2 = data_p->event_mask2;
++
++ /* Get the cd0_p */
++ cd0_p = (cd_p->ccb_ptr - cd_p->channelNumber)->channelDescriptor;
++
++ /*load the context*/
++ iapi_lowSetContext(cd0_p, chContext, cd_p->channelNumber);
++
++ /* release allocated memory */
++ FREE(chContext);
++
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/** Set the channels to be triggered by an event. The for every channel that
++ *must be triggered by the event, the corresponding bit from channel_map
++ *parameter must be set to 1. (e.g. for the event to trigger channels 31 and
++ *0 one must pass 0x80000001)
++ *
++ *
++ * <b>Algorithm:</b>\n
++ * - Update the register from Channel Enable RAM with the channel_map
++ *
++ * @param event event for which to set the channel association
++ * @param channel_map channels to be triggered by event. Put the corresponding
++ * bit from this 32-bit value to 1 for every channel that should be
++ * triggered by the event.
++ *
++ * @return
++ * - IAPI_SUCCESS : OK
++ * - -iapi_errno : operation failed, return negated value of iapi_errno
++ */
++int
++iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map)
++{
++ /* Check validity of event*/
++ if (event < EVENTS_NUM) {
++ __raw_writel(channel_map, SDMA_CHNENBL(event));
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | event;
++ return -iapi_errno;
++ }
++ return IAPI_SUCCESS;
++}
++
++#endif /* MCU */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c 2010-12-03 09:51:55.408346904 +0100
+@@ -0,0 +1,577 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiMiddle.c
++ *
++ * $Id iapiMiddle.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the MIDDLE level functions of the I.API.
++ *
++ *
++ *
++ *
++ * $Log iapiMiddle.c $
++ *
++ *****************************************************************************/
++
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <string.h>
++#include <linux/io.h>
++
++#include <epm.h>
++#include <iapiLow.h>
++#include <iapiMiddle.h>
++
++/* ****************************************************************************
++ * Global Variable Section
++ *****************************************************************************/
++
++
++/* ****************************************************************************
++ * Function Section
++ *****************************************************************************/
++
++/* ***************************************************************************/
++/**Allocates one Buffer Descriptor structure using information present in the
++ * channel descriptor.
++ *
++ * @param *ccb_p channel control block used to get the channel descriptor
++ *
++ * @return
++ * - pointer on the new Buffer Descriptor
++ * - NULL if allocation failed
++ *
++ */
++bufferDescriptor *
++iapi_AllocBD(channelControlBlock *ccb_p)
++{
++ bufferDescriptor *ptrBD = NULL;
++ int num_desc = ccb_p->channelDescriptor->bufferDescNumber;
++
++ if (num_desc == 0)
++ return NULL;
++
++ ptrBD = MALLOC(num_desc * sizeof(bufferDescriptor));
++ if (ptrBD == NULL) {
++ DBG(0, "%s: Failed to allocate %u byte for %u BDs\n",
++ __FUNCTION__,
++ num_desc * sizeof(bufferDescriptor),
++ num_desc);
++ return NULL;
++ }
++ ptrBD->mode.command = 0;
++ ptrBD->mode.status = 0;
++ ptrBD->mode.count = 0;
++ ptrBD->bufferAddr = DMA_ADDR_INVALID;
++
++ return ptrBD;
++}
++
++/* ***************************************************************************/
++/**Allocate one channel context data structure.
++ *
++ * @param **ctxd_p pointer to context data to be allocated
++ * @param channel channel number of context data structure
++ *
++ * @return
++ * - IAPI_SUCCESS
++ * - -iapi_errno if allocation failed
++ */
++int
++iapi_AllocContext(contextData **ctxd_p, unsigned char channel)
++{
++ if (*ctxd_p != NULL) {
++ iapi_errno = IAPI_ERR_CC_ALREADY_DEFINED |
++ IAPI_ERR_CH_AVAILABLE | channel;
++ return -iapi_errno;
++ }
++
++ *ctxd_p = MALLOC(sizeof(contextData));
++ if (*ctxd_p == NULL) {
++ iapi_errno = IAPI_ERR_CC_ALLOC_FAILED |
++ IAPI_ERR_CH_AVAILABLE | channel;
++ return -iapi_errno;
++ }
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**Allocates channel description and fill in with default values.
++ *
++ * <b>Algorithm:</b>\n
++ * - Check channel properties.
++ * - Then modifies the properties of the channel description with default
++ *
++ * @param **cd_p pointer to channel descriptor to be allocated
++ * @param channel channel number of channel descriptor
++ *
++ * @return
++ * - IAPI_SUCCESS
++ * - -iapi_errno if allocation failed
++ *
++ */
++int
++iapi_AllocChannelDesc(channelDescriptor **cd_p, unsigned char channel)
++{
++ unsigned int pri;
++
++ if (*cd_p != NULL) {
++ iapi_errno = IAPI_ERR_CD_ALREADY_DEFINED |
++ IAPI_ERR_CH_AVAILABLE | channel;
++ return -iapi_errno;
++ }
++
++ *cd_p = MALLOC(sizeof(channelDescriptor));
++ if (*cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_ALLOC_FAILED |
++ IAPI_ERR_CH_AVAILABLE | channel;
++ return -iapi_errno;
++ }
++
++ iapi_memcpy(*cd_p, &iapi_ChannelDefaults, sizeof(channelDescriptor));
++ (*cd_p)->channelNumber = channel;
++#ifdef MCU
++ pri = __raw_readl(SDMA_CHNPRI(channel));
++ if (pri != 0) {
++ (*cd_p)->priority = pri;
++ } else {
++ __raw_writel((*cd_p)->priority, SDMA_CHNPRI(channel));
++ }
++#endif
++ return IAPI_SUCCESS;
++}
++
++/* ***************************************************************************/
++/**Changes channel description information after performing sanity checks.
++ *
++ * <b>Algorithm:</b>\n
++ * - Check channel properties.
++ * - Then modifies the properties of the channel description.
++ *
++ * @param *cd_p channel descriptor of the channel to change
++ * @param whatToChange control code indicating the desired change
++ * @param newval new value
++ *
++ * @return
++ * - IAPI_SUCCESS
++ * - IAPI_FAILURE if change failed
++ *
++ */
++int
++iapi_ChangeChannelDesc(channelDescriptor *cd_p, unsigned char whatToChange,
++ unsigned long newval)
++{
++ bufferDescriptor *tmpBDptr;
++ unsigned int index;
++
++ DBG(0, "%s: channel %d what=%08x newval=%08lx\n", __FUNCTION__,
++ cd_p->channelNumber, whatToChange, newval);
++ /* verify parameter validity */
++ if (cd_p == NULL) {
++ iapi_errno = IAPI_ERR_CD_UNINITIALIZED;
++ return -iapi_errno;
++ }
++
++ /* verify channel descriptor initialization */
++ if (cd_p->ccb_ptr == NULL) {
++ iapi_errno = IAPI_ERR_CCB_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++
++ /* verify channel is not in use */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ tmpBDptr = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ for (index = cd_p->bufferDescNumber; index > 0; index--) {
++ if (tmpBDptr->mode.status & BD_DONE) {
++ iapi_errno = IAPI_ERR_CH_IN_USE | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ tmpBDptr++;
++ }
++ }
++
++ /* Select the change accorded to the selector given in parameter */
++ switch (whatToChange) {
++ case IAPI_CHANNELNUMBER:
++ /*
++ * Channel Number
++ */
++ /* Channel number can not be changed (description remains attached) */
++ iapi_errno = IAPI_ERR_CD_CHANGE_CH_NUMBER |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++
++ case IAPI_BUFFERDESCNUMBER:
++ /*
++ * Buffer Descriptor Number
++ */
++ if (newval >= MAX_BD_NUM) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ if (newval == cd_p->bufferDescNumber) {
++ break;
++ }
++ /* Free memory used for previous data */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ tmpBDptr = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if (tmpBDptr->bufferAddr != DMA_ADDR_INVALID) {
++ if (cd_p->trust == FALSE) {
++ FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr));
++ }
++ }
++ tmpBDptr++;
++ }
++ FREE(iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr));
++ cd_p->ccb_ptr->baseBDptr = DMA_ADDR_INVALID;
++ cd_p->ccb_ptr->currentBDptr = DMA_ADDR_INVALID;
++ }
++ /* Allocate and initialize structures */
++ cd_p->bufferDescNumber = newval;
++ cd_p->ccb_ptr->status.openedInit = FALSE;
++ if (IAPI_SUCCESS != iapi_InitializeMemory(cd_p->ccb_ptr)) {
++ iapi_errno = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ cd_p->ccb_ptr->status.openedInit = TRUE;
++ break;
++
++ case IAPI_BUFFERSIZE:
++ /*
++ * Buffer size
++ */
++ if (newval < MAX_BD_SIZE) {
++ if (newval != cd_p->bufferSize) {
++ /* Free memory used for previous old data */
++ if (cd_p->ccb_ptr->baseBDptr != DMA_ADDR_INVALID) {
++ tmpBDptr = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber; index++) {
++ if (cd_p->trust == FALSE) {
++ FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr));
++ }
++ tmpBDptr++;
++ }
++ FREE(iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr));
++ }
++ cd_p->ccb_ptr->baseBDptr = DMA_ADDR_INVALID;
++ cd_p->ccb_ptr->currentBDptr = DMA_ADDR_INVALID;
++ /* Allocate and initialize structures */
++ cd_p->bufferSize = newval;
++ cd_p->ccb_ptr->status.openedInit = FALSE;
++ if (IAPI_SUCCESS != iapi_InitializeMemory(cd_p->ccb_ptr)) {
++ iapi_errno = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ cd_p->ccb_ptr->status.openedInit = TRUE;
++ }
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++
++ case IAPI_BLOCKING:
++ /*
++ * Blocking / non blocking feature
++ */
++ if (newval < MAX_BLOCKING) {
++ cd_p->blocking = newval;
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++
++ case IAPI_CALLBACKSYNCH:
++ /*
++ * Synchronization method
++ */
++ if (newval < MAX_SYNCH) {
++ cd_p->callbackSynch = newval;
++ iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr);
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++
++ case IAPI_OWNERSHIP:
++ /*
++ * Ownership of the channel
++ */
++#ifdef DSP
++ iapi_errno = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
++ return -iapi_errno;
++#endif /* DSP */
++#ifdef MCU
++ if (newval < MAX_OWNERSHIP) {
++ cd_p->ownership = newval;
++ iapi_ChannelConfig(cd_p->channelNumber,
++ (newval >> CH_OWNSHP_OFFSET_EVT) & 1,
++ (newval >> CH_OWNSHP_OFFSET_MCU) & 1,
++ (newval >> CH_OWNSHP_OFFSET_DSP) & 1);
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++#endif /* MCU */
++ case IAPI_PRIORITY:
++ /*
++ * Priority
++ */
++#ifdef DSP
++ iapi_errno = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
++ return -iapi_errno;
++#endif /* DSP */
++
++#ifdef MCU
++ if (newval < MAX_CH_PRIORITY) {
++#if 1
++ __raw_writel(newval, SDMA_CHNPRI(cd_p->channelNumber));
++#else
++ volatile unsigned long *ChannelPriorities = &SDMA_CHNPRI_0;
++ ChannelPriorities[cd_p->channelNumber] = newval;
++#endif
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++#endif /* MCU */
++ case IAPI_TRUST:
++ /*
++ * "Trust" property
++ */
++ if (newval < MAX_TRUST) {
++ if (cd_p->trust != newval) {
++ cd_p->trust = newval;
++ if (newval == FALSE) {
++ if (IAPI_SUCCESS !=iapi_InitializeMemory(cd_p->ccb_ptr)) {
++ iapi_errno = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ }
++ }
++ break;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++
++ case IAPI_CALLBACKISR_PTR:
++ /*
++ * Callback function pointer
++ */
++ if ((void *)newval != NULL) {
++ cd_p->callbackISR_ptr = (void *)newval;
++ iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr);
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ break;
++
++ case IAPI_CCB_PTR:
++ /*
++ * Channel Control Block pointer
++ */
++ cd_p->ccb_ptr = (channelControlBlock *)newval;
++ cd_p->ccb_ptr->channelDescriptor = cd_p;
++ break;
++
++ case IAPI_BDWRAP:
++ /*
++ * WRAP/UNWRAP
++ */
++ /* pointer to first BD */
++ tmpBDptr = iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
++ /* pointer to last BD */
++ tmpBDptr += cd_p->bufferDescNumber - 1;
++ DBG(0, "%s: newval=%08lx\n", __FUNCTION__, newval);
++ if (newval == TRUE) {
++ /* wrap last BD */
++ DBG(0, "%s: Setting BD_WRAP for channel %d BD[%d/%d]\n",
++ __FUNCTION__, cd_p->channelNumber,
++ cd_p->bufferDescNumber - 1,
++ cd_p->bufferDescNumber);
++ tmpBDptr->mode.status |= BD_WRAP;
++ } else if (newval == FALSE) {
++ /* unwrap last BD */
++ DBG(0, "%s: Clearing BD_WRAP for channel %d BD[%d/%d]\n",
++ __FUNCTION__, cd_p->channelNumber,
++ cd_p->bufferDescNumber - 1,
++ cd_p->bufferDescNumber);
++ tmpBDptr->mode.status &= ~BD_WRAP;
++ } else {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ break;
++
++ case IAPI_WML:
++ /*
++ * Watermark level
++ */
++#ifdef DSP
++ iapi_errno = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
++ return -iapi_errno;
++#endif /* DSP */
++#ifdef MCU
++ if (newval >= MAX_WML) {
++ iapi_errno = IAPI_ERR_INVALID_PARAMETER |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ if (cd_p->watermarkLevel != newval) {
++ cd_p->watermarkLevel = newval;
++ }
++ break;
++#endif /* MCU */
++ default:
++ /*
++ * Detect errors
++ */
++ iapi_errno = IAPI_ERR_CD_CHANGE_UNKNOWN |
++ IAPI_ERR_CH_AVAILABLE |
++ cd_p->channelNumber;
++ return -iapi_errno;
++ }
++ return IAPI_SUCCESS;
++}
++
++
++/* ***************************************************************************/
++/**Initialize a table of function pointers that contain the interrupt Service
++ * Routine callback pointers for the SDMA channels with a default value
++ *
++ * <b>Algorithm:</b>\n
++ * - Loop on each element of the global IAPI variable callbackIsrTable
++ *
++ * @param *func_p default callback functon for all SDMA channels
++ *
++ * @return none
++ */
++void
++iapi_InitializeCallbackISR(void(* func_p)(channelDescriptor *cd_p, void *arg))
++{
++ unsigned long chCnt;
++
++ for (chCnt = 0; chCnt < CH_NUM; chCnt++) {
++ callbackIsrTable[chCnt] = func_p;
++ }
++}
++
++/* ***************************************************************************/
++/**For the specified channel control block, attach the array of buffer
++ * descriptors, the channel description structure and initialize channel's
++ * status using information in the channel descriptor.
++ *
++ * @param *ccb_p pointer to channel control block
++ *
++ * @return none
++ *
++ */
++int
++iapi_InitializeMemory(channelControlBlock *ccb_p)
++{
++ bufferDescriptor *bd_p;
++ unsigned int index;
++ channelDescriptor *cd_p = ccb_p->channelDescriptor;
++
++ /* Attach the array of Buffer descriptors */
++ bd_p = iapi_AllocBD(ccb_p);
++ if (bd_p == NULL)
++ return -IAPI_ERR_BD_ALLOCATION;
++
++ ccb_p->baseBDptr = iapi_Virt2Phys(bd_p);
++ ccb_p->currentBDptr = ccb_p->baseBDptr;
++ DBG(0, "%s: BDptr[%p] of ccb %p set to %08x\n", __FUNCTION__,
++ &ccb_p->baseBDptr, ccb_p, ccb_p->baseBDptr);
++ for (index = 0; index < cd_p->bufferDescNumber - 1; index++) {
++ if (cd_p->trust == TRUE) {
++ iapi_SetBufferDescriptor(bd_p,
++ cd_p->dataSize,
++ BD_CONT | BD_EXTD, cd_p->bufferSize,
++ NULL, DMA_ADDR_INVALID);
++ } else {
++ if (cd_p->bufferSize != 0) {
++ void *buf = MALLOC(cd_p->bufferSize);
++
++ if (buf == NULL)
++ goto cleanup;
++
++ iapi_SetBufferDescriptor(bd_p,
++ cd_p->dataSize,
++ BD_CONT | BD_EXTD,
++ cd_p->bufferSize,
++ buf, DMA_ADDR_INVALID);
++ }
++ }
++ bd_p++;
++ }
++
++ if (cd_p->trust == TRUE) {
++ iapi_SetBufferDescriptor(bd_p,
++ cd_p->dataSize,
++ BD_EXTD | BD_WRAP | BD_INTR,
++ cd_p->bufferSize,
++ NULL, DMA_ADDR_INVALID);
++ } else {
++ if (cd_p->bufferSize != 0) {
++ void *buf = MALLOC(cd_p->bufferSize);
++
++ if (buf == NULL)
++ goto cleanup;
++
++ iapi_SetBufferDescriptor(bd_p,
++ cd_p->dataSize,
++ BD_EXTD | BD_WRAP | BD_INTR,
++ cd_p->bufferSize,
++ buf,
++ DMA_ADDR_INVALID);
++ }
++ }
++ return IAPI_SUCCESS;
++cleanup:
++ WARN_ON(1);
++ while (--index >= 0) {
++
++ }
++}
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c 2010-12-03 09:51:55.408346904 +0100
+@@ -0,0 +1,52 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiMiddleMcu.c
++ *
++ * $Id iapiMiddleMcu.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the MIDDLE level functions of the I.API specific to MCU.
++ *
++ *
++ *
++ *
++ * $Log iapiMiddleMcu.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <epm.h>
++#include <string.h>
++
++#include <iapiLow.h>
++#include <iapiMiddle.h>
++
++/* ****************************************************************************
++ * Global Variable Section
++ *****************************************************************************/
++
++/*extern void * __HEAP_START;
++extern void * __HEAP_END;
++*/
++
++/* ****************************************************************************
++ * Function Section
++ *****************************************************************************/
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c 2010-12-03 09:51:55.408346904 +0100
+@@ -0,0 +1,64 @@
++/******************************************************************************
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ *
++ ******************************************************************************
++ *
++ * File: iapiOS.c
++ *
++ * $Id iapiOS.c $
++ *
++ * Description:
++ * This library is written in C to guarantee functionality and integrity in
++ * the usage of SDMA virtual DMA channels. This API (Application Programming
++ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
++ * fashion.
++ * These are the OS level functions of the I.API - are OS dependant and must
++ * be provided by the user of I.API.
++ *
++ *
++ * /
++ *
++ * $Log iapiOS.c $
++ *
++ *****************************************************************************/
++
++/* ****************************************************************************
++ * Include File Section
++ *****************************************************************************/
++#include <epm.h>
++#include <iapi.h>
++
++/**
++ * Function Section
++ */
++#ifdef CONFIG_SDMA_IRAM
++void* (*iapi_iram_Malloc)(size_t size);
++#endif /*CONFIG_SDMA_IRAM*/
++
++void* (*iapi_Malloc)(size_t size);
++void (*iapi_Free)(void *ptr);
++
++dma_addr_t (*iapi_Virt2Phys) (void *ptr);
++void* (*iapi_Phys2Virt) (dma_addr_t ptr);
++
++void (*iapi_WakeUp)(int);
++void (*iapi_GotoSleep)(int);
++void (*iapi_InitSleep)(int);
++
++void* (*iapi_memcpy)(void *dest, const void *src, size_t count);
++void* (*iapi_memset)(void *dest, int c, size_t count);
++
++void (*iapi_EnableInterrupts)(void);
++void (*iapi_DisableInterrupts)(void);
++
++int (*iapi_GetChannel)(int);
++int (*iapi_ReleaseChannel)(int);
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/Makefile linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/Makefile
+--- linux.35.old/arch/arm/plat-mxc/sdma/iapi/src/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/iapi/src/Makefile 2010-12-03 09:51:55.412348386 +0100
+@@ -0,0 +1,20 @@
++#
++# Makefile for I.API sources.
++#
++
++ifneq ($(KBUILD_SRC),)
++ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \
++ -I$(KBUILD_SRC)/include/linux \
++ -DMCU -DOS=LINUX \
++ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
++ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
++else
++ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \
++ -Iinclude/linux \
++ -DMCU -DOS=LINUX \
++ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
++ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
++endif
++
++#obj-y += iapiLow.o iapiLowMcu.o iapiMiddle.o iapiMiddleMcu.o iapiHigh.o iapiDefaults.o iapiOS.o
++obj-y += iapiLow.o iapiLowMcu.o iapiMiddle.o iapiHigh.o iapiDefaults.o iapiOS.o
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/Makefile linux.35.new/arch/arm/plat-mxc/sdma/Makefile
+--- linux.35.old/arch/arm/plat-mxc/sdma/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/Makefile 2010-12-03 09:51:55.412348386 +0100
+@@ -0,0 +1,18 @@
++ifneq ($(KBUILD_SRC),)
++ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \
++ -I$(KBUILD_SRC)/include/linux \
++ -DMCU -DOS=LINUX \
++ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
++ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
++else
++ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \
++ -Iinclude/linux \
++ -DMCU -DOS=LINUX \
++ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
++ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
++endif
++
++obj-y += dma_sdma.o
++obj-$(CONFIG_MXC_SDMA_API) += sdma.o
++obj-$(CONFIG_MXC_SDMA_API) += iapi/
++obj-$(CONFIG_MXC_SDMA_API) += sdma_malloc.o
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/sdma.c linux.35.new/arch/arm/plat-mxc/sdma/sdma.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/sdma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/sdma.c 2010-12-03 09:51:55.416347546 +0100
+@@ -0,0 +1,1653 @@
++/*
++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/*
++ * file plat-mxc/sdma/sdma.c
++ * This file contains functions for Smart DMA API
++ *
++ * SDMA (Smart DMA) is used for transferring data between MCU and peripherals
++ *
++ */
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/semaphore.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/proc_fs.h>
++
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++#include <mach/dma.h>
++#include <mach/hardware.h>
++
++#include <iapi.h>
++#include <epm.h>
++#include "sdma.h"
++
++#define M3_BASE_ADDRESS CSD0_BASE_ADDR
++#define CHAD(ch) sdma_data[0].cd->ccb_ptr[ch].channelDescriptor
++
++void __iomem *sdma_base_addr = NULL;
++
++/*
++ * SDMA status mutex
++ */
++static struct semaphore sdma_status_mutex;
++
++/*
++ * SDMA channel sleep queues
++ */
++//static struct semaphore sdma_sleep_mutex[MAX_DMA_CHANNELS];
++static wait_queue_head_t sdma_sleep_queue[MAX_DMA_CHANNELS];
++
++/*
++ * SDMA channel synchronization
++ */
++static struct semaphore sdma_synch_mutex[MAX_DMA_CHANNELS];
++
++struct clk *mxc_sdma_clk;
++
++/*
++ * Structure containing sdma channels information.
++ */
++typedef struct {
++ /* Channel number */
++ int channel;
++ /* Channel usage name */
++ int in_use;
++ /* Name of device using the channel */
++ char devicename[MAX_DEVNAME_LENGTH];
++ /* Transfer type. Needed for setting SDMA script */
++ sdma_transferT transfer_type;
++ /* Peripheral type. Needed for setting SDMA script */
++ sdma_periphT peripheral_type;
++ /* Watermark level of device's fifo */
++ __u32 watermark_level;
++ /* Peripheral event id */
++ int event_id;
++ /* Peripheral event id2 (for channels that use 2 events) */
++ int event_id2;
++ /* Running status (boolean) */
++ int running;
++ /* buffer descriptors number */
++ int bd_number;
++ /* callback function */
++ dma_callback_t callback;
++ /* callback argument */
++ void *arg;
++ /* SDMA data access word size */
++ unsigned long word_size:8;
++ /* channel descriptor pointer */
++ channelDescriptor *cd;
++} sdma_struct;
++
++/*
++ * Used to save the status of channels.
++ */
++static sdma_struct sdma_data[MAX_DMA_CHANNELS];
++
++/*
++ * Stores the start address of the SDMA scripts
++ */
++static sdma_script_start_addrs sdma_script_addrs;
++
++extern void mxc_sdma_get_script_info(sdma_script_start_addrs *sdma_script_add);
++
++/*
++ * Init sleep mutex of the channel
++ *
++ * @param channel channel number
++ */
++static void sdma_init_sleep(int channel)
++{
++ init_waitqueue_head(&sdma_sleep_queue[channel]);
++}
++
++#ifdef DEBUG
++#define SHOW_REG(b, p, r) __show_reg(b, p, r, #r)
++
++static inline void __show_reg(void __iomem *base, unsigned long phys,
++ unsigned int reg, const char *name)
++{
++ DBG(0, "%-12s[%08lx]=%08x\n", name, phys + reg, __raw_readl(base + reg));
++}
++
++void dump_sdma_regs(void)
++{
++ unsigned int reg;
++
++ for (reg = 0; reg < 0x180; reg += 4) {
++ SHOW_REG(sdma_base_addr, SDMA_BASE_ADDR, reg);
++ }
++}
++#endif
++
++/*
++ * Puts channel to sleep
++ *
++ * @param channel channel number
++ */
++#include <linux/delay.h>
++
++static void sdma_sleep_channel(int channel)
++{
++ int ret;
++
++ DBG(1, "%s: Waiting for channel %d to drain\n",
++ __FUNCTION__, channel);
++ BUG_ON(irqs_disabled());
++
++ ret = wait_event_interruptible_timeout(sdma_sleep_queue[channel],
++ iapi_SDMAIntr & (1 << channel), HZ);
++ if (ret == 0 && !(iapi_SDMAIntr & (1 << channel))) {
++ DBG(-1, "%s: Wait for channel %d done timed out: %08lx\n",
++ __FUNCTION__, channel, iapi_SDMAIntr);
++ } else if (ret < 0) {
++ DBG(-1, "%s: Wait for channel %d aborted: %08lx, %d\n",
++ __FUNCTION__, channel, iapi_SDMAIntr, ret);
++ } else {
++ DBG(1, "%s: Wait for channel %d done finished after %u ticks: %08lx\n",
++ __FUNCTION__, channel, HZ - ret, iapi_SDMAIntr);
++ }
++}
++
++/*
++ * Wake up channel from sleep
++ *
++ * @param channel channel number
++ */
++static void sdma_wakeup_channel(int channel)
++{
++ DBG(1, "%s: Waking up channel %d\n", __FUNCTION__, channel);
++ wake_up_interruptible(&sdma_sleep_queue[channel]);
++}
++
++/*
++ * Sdma interrupt handler routine.
++ * Calls channels callback function
++ *
++ * @param irq the interrupt number
++ * @param dev_id driver private data
++ * @return the function returns \b IRQ_RETVAL(1) - interrupt was handled
++ */
++static irqreturn_t sdma_int_handler(int irq, void *dev_id)
++{
++ DBG(2, "%s: IRQ %d\n", __FUNCTION__, irq);
++ IRQ_Handler();
++ DBG(2, "%s: Done\n", __FUNCTION__);
++ return IRQ_HANDLED;
++}
++
++/*
++ * I.API channel callback function
++ *
++ * @param cd channel descriptor structure
++ * @param channel_data SDMA struct of the current channel
++ */
++static void iapi_interrupt_callback(channelDescriptor *cd,
++ sdma_struct *channel_data)
++{
++ int channel;
++ dma_callback_t callback;
++ void *arg;
++
++ DBG(2, "%s: cd=%p\n", __FUNCTION__, cd);
++ channel = channel_data->channel;
++
++ channel_data->running = 0;
++
++ arg = channel_data->arg;
++
++ if (arg == NULL) {
++ arg = &channel;
++ }
++
++ callback = channel_data->callback;
++
++ if (callback != NULL) {
++ DBG(2, "%s: Calling %p\n", __FUNCTION__, callback);
++ callback(arg);
++ }
++}
++
++/*
++ * Returns pc of SDMA script according to peripheral and transfer type
++ *
++ * @param peripheral_type peripheral type
++ * @param transfer_type transfer type
++ *
++ * @return PC of SDMA script
++*/
++static unsigned short sdma_get_pc(sdma_periphT peripheral_type,
++ sdma_transferT transfer_type)
++{
++ int res = 0;
++
++ if (peripheral_type == MEMORY) {
++ switch (transfer_type) {
++ case emi_2_int:
++ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
++ break;
++ case emi_2_emi:
++ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
++ break;
++ case int_2_emi:
++ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == DSP) {
++ switch (transfer_type) {
++ case emi_2_dsp:
++ res = sdma_script_addrs.mxc_sdma_ap_2_bp_addr;
++ break;
++ case dsp_2_emi:
++ res = sdma_script_addrs.mxc_sdma_bp_2_ap_addr;
++ break;
++ case dsp_2_emi_loop:
++ res =
++ sdma_script_addrs.
++ mxc_sdma_loopback_on_dsp_side_addr;
++ break;
++ case emi_2_dsp_loop:
++ res =
++ sdma_script_addrs.mxc_sdma_mcu_interrupt_only_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == FIRI) {
++ switch (transfer_type) {
++ case per_2_int:
++ res = sdma_script_addrs.mxc_sdma_firi_2_per_addr;
++ break;
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_firi_2_mcu_addr;
++ break;
++ case int_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_firi_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_firi_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == UART) {
++ switch (transfer_type) {
++ case per_2_int:
++ res = sdma_script_addrs.mxc_sdma_uart_2_per_addr;
++ break;
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_uart_2_mcu_addr;
++ break;
++ case int_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_app_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == UART_SP) {
++ switch (transfer_type) {
++ case per_2_int:
++ res = sdma_script_addrs.mxc_sdma_uartsh_2_per_addr;
++ break;
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_uartsh_2_mcu_addr;
++ break;
++ case int_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_shp_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == ATA) {
++ switch (transfer_type) {
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_ata_2_mcu_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_ata_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == CSPI || peripheral_type == EXT ||
++ peripheral_type == SSI) {
++ switch (transfer_type) {
++ case per_2_int:
++ res = sdma_script_addrs.mxc_sdma_app_2_per_addr;
++ break;
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_app_2_mcu_addr;
++ break;
++ case int_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_app_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == SSI_SP || peripheral_type == MMC ||
++ peripheral_type == SDHC || peripheral_type == CSPI_SP ||
++ peripheral_type == ESAI || peripheral_type == MSHC_SP) {
++ switch (transfer_type) {
++ case per_2_int:
++ res = sdma_script_addrs.mxc_sdma_shp_2_per_addr;
++ break;
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_shp_2_mcu_addr;
++ break;
++ case int_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_shp_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == ASRC) {
++ switch (transfer_type) {
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_asrc_2_mcu_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_asrc_2_mcu_addr;
++ break;
++ case per_2_per:
++ res = sdma_script_addrs.mxc_sdma_per_2_per_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == MSHC) {
++ switch (transfer_type) {
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_mshc_2_mcu_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_mshc_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == CCM) {
++ switch (transfer_type) {
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_dptc_dvfs_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == FIFO_MEMORY) {
++ res = sdma_script_addrs.mxc_sdma_ap_2_ap_fixed_addr;
++ } else if (peripheral_type == SPDIF) {
++ switch (transfer_type) {
++ case per_2_emi:
++ res = sdma_script_addrs.mxc_sdma_spdif_2_mcu_addr;
++ break;
++ case emi_2_per:
++ res = sdma_script_addrs.mxc_sdma_mcu_2_spdif_addr;
++ break;
++ default:
++ res = -EINVAL;
++ }
++ } else if (peripheral_type == IPU_MEMORY) {
++ if (transfer_type == emi_2_per) {
++ res = sdma_script_addrs.mxc_sdma_ext_mem_2_ipu_addr;
++ } else {
++ res = -EINVAL;
++ }
++ }
++
++ if (res < 0) {
++ printk(KERN_ERR "SDMA script not found\n");
++ } else {
++ DBG(1, "%s: PC[%d,%d]=%04x\n", __FUNCTION__,
++ peripheral_type, transfer_type, res);
++ }
++ return res;
++
++}
++
++static inline int sdma_asrc_set_info(dma_channel_params *p,
++ script_data *pcontext, int eflags)
++{
++ dma_channel_ext_params *ep = (dma_channel_ext_params *)p;
++ unsigned int wml, tmp, wml1, wml2;
++ struct dma_channel_asrc_info *info = &ep->info.asrc;
++
++ wml = 0;
++ if (p->transfer_type == per_2_per) {
++ if (!p->ext)
++ return wml;
++ wml1 = p->watermark_level;
++ wml2 = ep->watermark_level2;
++ if (info->channs) {
++ wml |= (info->channs & SDMA_ASRC_INFO_N_MASK) <<
++ SDMA_ASRC_INFO_N_OFF;
++ if (ep->p2p_dir)
++ wml2 *= info->channs & SDMA_ASRC_INFO_N_MASK;
++ else
++ wml1 *= info->channs & SDMA_ASRC_INFO_N_MASK;
++ }
++ if (info->channs & 1) {
++ if (ep->p2p_dir)
++ wml |= SDMA_ASRC_P2P_INFO_PS;
++ else
++ wml |= SDMA_ASRC_P2P_INFO_PA;
++ }
++ if (wml1 > wml2) {
++ tmp = wml2 & SDMA_ASRC_P2P_INFO_LWML_MASK;
++ wml |= tmp << SDMA_ASRC_P2P_INFO_LWML_OFF;
++ tmp = wml1 & SDMA_ASRC_P2P_INFO_HWML_MASK;
++ wml |= tmp << SDMA_ASRC_P2P_INFO_HWML_OFF;
++ if (eflags & (1 << 31))
++ wml |= SDMA_ASRC_P2P_INFO_LWE;
++ if (eflags & (1 << 30))
++ wml |= SDMA_ASRC_P2P_INFO_HWE;
++ } else {
++ tmp = wml1 & SDMA_ASRC_P2P_INFO_LWML_MASK;
++ wml |= tmp << SDMA_ASRC_P2P_INFO_LWML_OFF;
++ tmp = wml2 & SDMA_ASRC_P2P_INFO_HWML_MASK;
++ wml |= tmp << SDMA_ASRC_P2P_INFO_HWML_OFF;
++ wml |= eflags >> 2;
++ tmp = pcontext->event_mask2;
++ pcontext->event_mask2 = pcontext->event_mask1;
++ pcontext->event_mask1 = tmp;
++ }
++ } else {
++ if (p->ext && info->channs) {
++ wml |= (info->channs & SDMA_ASRC_INFO_N_MASK) <<
++ SDMA_ASRC_INFO_N_OFF;
++ tmp = (info->channs * p->watermark_level) &
++ SDMA_ASRC_INFO_WML_MASK;
++ wml |= tmp << SDMA_ASRC_INFO_WML_OFF;
++ } else {
++ tmp = (p->watermark_level & SDMA_ASRC_INFO_WML_MASK);
++ wml |= tmp << SDMA_ASRC_INFO_WML_OFF;
++ }
++
++ if (p->transfer_type == per_2_emi)
++ wml |= SDMA_ASRC_INFO_TXFR_DIR;
++
++ if (p->ext && (info->channs & 1)) {
++ if (p->transfer_type == per_2_emi)
++ wml |= SDMA_ASRC_INFO_PS;
++ else
++ wml |= SDMA_ASRC_INFO_PA;
++ }
++ wml |= eflags;
++ }
++ return wml;
++}
++
++/*
++ * Downloads channel context according to channel parameters
++ *
++ * @param channel channel number
++ * @param p channel parameters
++ */
++static int sdma_load_context(int channel, dma_channel_params *p)
++{
++ script_data context;
++ int res;
++ int event1_greater_than_32;
++ int event2_greater_than_32;
++ dma_channel_ext_params *ep = (dma_channel_ext_params *)p;
++
++ res = 0;
++
++ memset(&context, 0, sizeof(script_data));
++ context.load_address = sdma_get_pc(p->peripheral_type,
++ p->transfer_type);
++
++ if (context.load_address > 0) {
++ if ((p->peripheral_type != MEMORY) &&
++ (p->peripheral_type != DSP)) {
++ /* Handle multiple event channels differently */
++ if (p->event_id2) {
++ if (p->event_id2 < 32) {
++ context.event_mask2 =
++ 0x1 << p->event_id2;
++ event2_greater_than_32 = 0;
++ } else {
++ context.event_mask2 =
++ 0x1 << (p->event_id2 - 32);
++ event2_greater_than_32 = 1 << 31;
++ }
++ if (p->event_id < 32) {
++ context.event_mask1 =
++ 0x1 << p->event_id;
++ event1_greater_than_32 = 0;
++ } else {
++ context.event_mask1 =
++ 0x1 << (p->event_id - 32);
++ event1_greater_than_32 = 1 << 30;
++ }
++ } else {
++ event1_greater_than_32 = 0;
++ event2_greater_than_32 = 0;
++ if (p->event_id < 32) {
++ context.event_mask1 =
++ 0x1 << p->event_id;
++ context.event_mask2 = 0;
++ } else {
++ context.event_mask1 = 0;
++ context.event_mask2 =
++ 0x1 << (p->event_id - 32);
++ }
++ }
++
++ if (p->ext)
++ context.wml = ep->info_bits;
++ /* Watermark Level */
++ if (p->peripheral_type == ASRC) {
++ context.wml |= sdma_asrc_set_info(p,
++ &context,
++ event2_greater_than_32
++ |
++ event1_greater_than_32);
++ } else
++ context.wml |= event2_greater_than_32 |
++ event1_greater_than_32 | p->watermark_level;
++
++ /* Address */
++ context.shp_addr = p->per_address;
++ iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_PERIPHADDR, p->per_address);
++ } else {
++ context.wml = M3_BASE_ADDRESS;
++ }
++
++ sdma_data[channel].transfer_type = p->transfer_type;
++ sdma_data[channel].peripheral_type = p->peripheral_type;
++ sdma_data[channel].watermark_level = p->watermark_level;
++ iapi_AssignScript(sdma_data[channel].cd, &context);
++ } else {
++ res = context.load_address;
++ }
++
++ return res;
++}
++
++/*
++ * Setup channel according to parameters. Must be called once after mxc_request_dma()
++ *
++ * @param channel channel number
++ * @param p channel parameters pointer
++ * @return 0 on success, error code on fail
++ */
++int mxc_dma_setup_channel(int channel, dma_channel_params *p)
++{
++ int err = 0;
++ int i;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ mxc_dma_stop(channel);
++
++ for (i = 0; i < sdma_data[channel].bd_number; i++) {
++ iapi_IoCtl(sdma_data[channel].cd,
++ (i << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_STATUS, 0);
++ }
++
++ DBG(0, "%s: Changing number of BDs for channel %d from %u to %u\n",
++ __FUNCTION__, channel, sdma_data[channel].bd_number,
++ p->bd_number <= 0 ? 1 : p->bd_number);
++ sdma_data[channel].bd_number = (p->bd_number <= 0) ? 1 : p->bd_number;
++
++ sdma_data[channel].word_size = p->word_size;
++
++ sdma_data[channel].event_id = p->event_id;
++ sdma_data[channel].event_id2 = p->event_id2;
++
++ sdma_data[channel].callback = p->callback;
++
++ sdma_data[channel].arg = p->arg;
++
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_BDNUM, sdma_data[channel].bd_number);
++ if (err < 0) {
++ printk(KERN_ERR "Failed to allocate buffer descriptors: %d\n",
++ err);
++ err = -ENOMEM;
++ goto setup_channel_fail;
++ }
++
++ if (channel != 0) {
++ switch (p->transfer_type) {
++ case dsp_2_per:
++ break;
++ case emi_2_per:
++ case int_2_per:
++ case per_2_int:
++ case per_2_emi:
++ case per_2_per:
++ /*
++ * Peripheral <------> Memory
++ * evtOvr = 0 dspOvr = 1
++ */
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_OWNERSHIP,
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ if (err)
++ goto setup_channel_fail;
++ if (p->event_id) {
++ err = iapi_SetChannelEventMapping(p->event_id,
++ 1 << channel);
++ if (err)
++ goto setup_channel_fail;
++ }
++ if (p->event_id2) {
++ err = iapi_SetChannelEventMapping(p->event_id2,
++ 1 << channel);
++ }
++ break;
++ case emi_2_dsp:
++ case int_2_dsp:
++ case dsp_2_int:
++ case dsp_2_emi:
++ case dsp_2_dsp:
++ /*
++ * DSP <-----------> Memory
++ * evtOvr = 1 dspOvr = 0
++ */
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_OWNERSHIP,
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ break;
++ case emi_2_int:
++ case emi_2_emi:
++ case int_2_int:
++ case int_2_emi:
++ case emi_2_dsp_loop:
++ case dsp_2_emi_loop:
++ /* evtOvr = 1 dspOvr = 1 */
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_OWNERSHIP,
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ break;
++ case per_2_dsp:
++ /* evtOvr = 0 dspOvr = 0 */
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_OWNERSHIP,
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ if (err)
++ goto setup_channel_fail;
++ err = iapi_SetChannelEventMapping(p->event_id,
++ 1 << channel);
++ break;
++ default:
++ break;
++ printk(KERN_ERR "Wrong SDMA transfer type\n");
++ err = -EINVAL;
++ }
++ if (err)
++ goto setup_channel_fail;
++
++ err = sdma_load_context(channel, p);
++ if (err)
++ goto setup_channel_fail;
++
++ err = iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY,
++ MXC_SDMA_DEFAULT_PRIORITY);
++ }
++setup_channel_fail:
++ return err;
++}
++EXPORT_SYMBOL(mxc_dma_setup_channel);
++
++/*
++ * Setup the channel priority. This can be used to change the default priority
++ * for the channel.
++ *
++ * @param channel channel number
++ * @param priority priority to be set for the channel
++ *
++ * @return 0 on success, error code on failure
++ */
++int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ if (priority < MXC_SDMA_MIN_PRIORITY
++ || priority > MXC_SDMA_MAX_PRIORITY) {
++ return -EINVAL;
++ }
++ return iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY,
++ priority);
++}
++EXPORT_SYMBOL(mxc_dma_set_channel_priority);
++
++/*
++ * Allocates dma channel.
++ * If channel's value is 0, then the function allocates a free channel
++ * dynamically and sets its value to channel.
++ * Else allocates requested channel if it is free.
++ * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned.
++ *
++ * @param channel pointer to channel number
++ * @param devicename device name
++ * @return 0 on success, error code on fail
++ */
++int mxc_request_dma(int *channel, const char *devicename)
++{
++ int i, res = -EBUSY;
++
++ if (sdma_base_addr == NULL)
++ return -ENOSYS;
++
++ if (channel == NULL || *channel < 0 || *channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ down(&sdma_status_mutex);
++
++ /* Dynamic allocation */
++ if (*channel == 0) {
++ for (i = MAX_DMA_CHANNELS - 1; i > 0; i--) {
++#ifdef CONFIG_SDMA_IRAM
++ /*TODO:It will be removed after DPTC used UDMA interface */
++ if (i >= MXC_DMA_CHANNEL_IRAM)
++ continue;
++#endif /* CONFIG_SDMA_IRAM */
++ if (!sdma_data[i].in_use) {
++ *channel = i;
++ res = 0;
++ break;
++ }
++ }
++ } else {
++ if (sdma_data[*channel].in_use)
++ return -EBUSY;
++ res = 0;
++ }
++ if (res)
++ return res;
++
++ DBG(1, "%s: Opening channel %d\n", __FUNCTION__, *channel);
++
++ res = iapi_Open(sdma_data[0].cd, *channel);
++ if (res < 0) {
++ printk(KERN_ERR "Failed iapi_Open channel %d, 0x%x\n",
++ *channel, res);
++ } else {
++ sdma_data[*channel].in_use = 1;
++ strlcpy(sdma_data[*channel].devicename, devicename,
++ sizeof(sdma_data[*channel].devicename));
++ sdma_data[*channel].cd = CHAD(*channel);
++
++ iapi_IoCtl(sdma_data[*channel].cd, IAPI_CHANGE_SYNCH,
++ CALLBACK_ISR);
++ iapi_IoCtl(sdma_data[*channel].cd,
++ IAPI_CHANGE_CALLBACKFUNC,
++ (unsigned long)iapi_interrupt_callback);
++ iapi_IoCtl(sdma_data[*channel].cd,
++ IAPI_CHANGE_USER_ARG,
++ (unsigned long)&sdma_data[*channel]);
++ }
++
++ up(&sdma_status_mutex);
++
++ return res;
++}
++EXPORT_SYMBOL(mxc_request_dma);
++
++/*
++ * Configures request parameters. Can be called multiple times after
++ * mxc_request_dma() and mxc_dma_setup_channel().
++ *
++ *
++ * @param channel channel number
++ * @param p request parameters pointer
++ * @param bd_index index of buffer descriptor to set
++ * @return 0 on success, error code on fail
++ */
++int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index)
++{
++ int ret;
++ unsigned long param;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ if (!sdma_data[channel].in_use) {
++ return -EINVAL;
++ }
++ DBG(0, "%s: dma_request: src: %08x dst: %08x cont=%d wrap=%d\n",
++ __FUNCTION__, p->sourceAddr, p->destAddr,
++ p->bd_cont, p->bd_wrap);
++
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_TRANSFER_CD, sdma_data[channel].word_size);
++ if (ret < 0)
++ return ret;
++
++ param = BD_DONE | BD_INTR | BD_EXTD;
++
++ if (sdma_data[channel].bd_number > 1 && p->bd_cont) {
++ param |= BD_CONT;
++ }
++
++ if (bd_index == sdma_data[channel].bd_number - 1 || p->bd_wrap) {
++ param |= BD_WRAP;
++ }
++
++ switch (sdma_data[channel].transfer_type) {
++ case emi_2_per:
++ case dsp_2_per:
++ case int_2_per:
++ case emi_2_dsp:
++ case int_2_dsp:
++ case emi_2_dsp_loop:
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_BUFFERADDR,
++ (unsigned long)p->sourceAddr);
++ break;
++ case per_2_int:
++ case per_2_emi:
++ case per_2_dsp:
++ case dsp_2_int:
++ case dsp_2_emi:
++ case dsp_2_dsp:
++ case dsp_2_emi_loop:
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_BUFFERADDR,
++ (unsigned long)p->destAddr);
++ break;
++ case emi_2_int:
++ case emi_2_emi:
++ case int_2_int:
++ case int_2_emi:
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_BUFFERADDR,
++ (unsigned long)p->sourceAddr);
++ if (ret < 0)
++ return ret;
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_EXTDBUFFERADDR,
++ (unsigned long)p->destAddr);
++ break;
++ case per_2_per:
++ case dvfs_pll:
++ case dvfs_pdr:
++ return -EINVAL;
++ }
++ if (ret < 0)
++ return ret;
++
++ /* Change the endianness for DSP to MCU Data transfers */
++ if (sdma_data[channel].transfer_type == dsp_2_emi ||
++ sdma_data[channel].transfer_type == emi_2_dsp) {
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ IAPI_CHANGE_SET_ENDIANNESS,
++ SET_BIT_ALL);
++ if (ret < 0)
++ return ret;
++ }
++
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_COUNT, p->count);
++ if (ret < 0)
++ return ret;
++
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS,
++ param);
++ return ret;
++}
++EXPORT_SYMBOL(mxc_dma_set_config);
++
++/*
++ * Configures the BD_INTR bit on a buffer descriptor parameters.
++ *
++ *
++ * @param channel channel number
++ * @param bd_index index of buffer descriptor to set
++ * @param bd_intr flag to set or clear the BD_INTR bit
++ * @return 0 on success, error code on fail
++ */
++void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr)
++{
++ unsigned long param;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return;
++
++ iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_STATUS, (unsigned long)&param);
++
++ if (bd_intr) {
++ param |= BD_INTR;
++ } else {
++ param &= ~BD_INTR;
++ }
++ iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS, param);
++}
++EXPORT_SYMBOL(mxc_dma_set_bd_intr);
++
++/*
++ * Gets the BD_INTR bit on a buffer descriptor.
++ *
++ *
++ * @param channel channel number
++ * @param bd_index index of buffer descriptor to set
++ *
++ * @return returns the BD_INTR bit status
++ */
++int mxc_dma_get_bd_intr(int channel, int bd_index)
++{
++ int ret;
++ unsigned long bd_status = 0;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ ret = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status);
++
++ return ret == 0 ? !!(bd_status & BD_INTR) : ret;
++}
++EXPORT_SYMBOL(mxc_dma_get_bd_intr);
++
++/*
++ * Stop the current transfer
++ *
++ * @param channel channel number
++ * @param buffer_number number of buffers (beginning with 0),
++ * whose done bits should be reset to 0
++ */
++int mxc_dma_reset(int channel, int buffer_number)
++{
++ unsigned char param = 0;
++ int i = 0;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ if (!sdma_data[channel].in_use) {
++ return -EINVAL;
++ }
++
++ /* clear the BD_DONE bits for all the necessary buffers */
++ for (i = 0; i < buffer_number; i++) {
++
++ iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_STATUS, (unsigned long)&param);
++
++ /* clear the BD_DONE bit of the buffer */
++ param &= ~BD_DONE;
++
++ iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_STATUS, param);
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL(mxc_dma_reset);
++
++/*
++ * Returns request parameters.
++ *
++ * @param channel channel number
++ * @param p request parameters pointer
++ * @param bd_index index of buffer descriptor to get
++ * @return 0 on success, error code on fail
++ */
++int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index)
++{
++ int err = 0;
++ unsigned long bd_status;
++ unsigned long bd_count;
++ dma_addr_t sourceAddr;
++ dma_addr_t destAddr;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ memset(p, 0, sizeof(*p));
++
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status);
++ if (err)
++ return err;
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_COUNT, (unsigned long)&bd_count);
++ if (err)
++ return err;
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_BUFFERADDR, (unsigned long)&sourceAddr);
++ if (err)
++ return err;
++
++ switch (sdma_data[channel].transfer_type) {
++ case emi_2_per:
++ case dsp_2_per:
++ case int_2_per:
++ case emi_2_dsp:
++ case int_2_dsp:
++ case emi_2_dsp_loop:
++ p->sourceAddr = sourceAddr;
++ break;
++ case per_2_int:
++ case per_2_emi:
++ case per_2_dsp:
++ case dsp_2_int:
++ case dsp_2_emi:
++ case dsp_2_dsp:
++ case dsp_2_emi_loop:
++ p->destAddr = sourceAddr;
++ break;
++ case emi_2_int:
++ case emi_2_emi:
++ case int_2_int:
++ case int_2_emi:
++ p->sourceAddr = sourceAddr;
++ err = iapi_IoCtl(sdma_data[channel].cd,
++ (bd_index << BD_NUM_OFFSET) |
++ IAPI_CHANGE_GET_EXTDBUFFERADDR,
++ (unsigned long)&destAddr);
++ if (err)
++ return err;
++ p->destAddr = destAddr;
++ break;
++ default:
++ break;
++ }
++
++ p->count = bd_count;
++ p->bd_done = !!(bd_status & BD_DONE);
++ p->bd_cont = !!(bd_status & BD_CONT);
++ p->bd_error = !!(bd_status & BD_RROR);
++ p->bd_wrap = !!(bd_status & BD_WRAP);
++
++ return err;
++}
++EXPORT_SYMBOL(mxc_dma_get_config);
++
++/*
++ * This function is used by MXC IPC's write_ex2. It passes the pointer to the
++ * data control structure to iapi_write_ipcv2()
++ *
++ * @param channel SDMA channel number
++ * @param ctrl_ptr Data Control structure pointer
++ */
++int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++ return iapi_Write_ipcv2(sdma_data[channel].cd, ctrl_ptr);
++}
++EXPORT_SYMBOL(mxc_sdma_write_ipcv2);
++
++/*
++ * This function is used by MXC IPC's read_ex2. It passes the pointer to the
++ * data control structure to iapi_read_ipcv2()
++ *
++ * @param channel SDMA channel number
++ * @param ctrl_ptr Data Control structure pointer
++ */
++int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++ return iapi_Read_ipcv2(sdma_data[channel].cd, ctrl_ptr);
++}
++EXPORT_SYMBOL(mxc_sdma_read_ipcv2);
++
++/*
++ * Starts dma channel.
++ *
++ * @param channel channel number
++ */
++int mxc_dma_start(int channel)
++{
++ DBG(1, "%s: Starting DMA channel %d\n", __FUNCTION__, channel);
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ if (!sdma_data[channel].running) {
++ sdma_data[channel].running = 1;
++ iapi_StartChannel(channel);
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL(mxc_dma_start);
++
++/*
++ * Stops dma channel.
++ *
++ * @param channel channel number
++ */
++int mxc_dma_stop(int channel)
++{
++ DBG(1, "%s: Stopping DMA channel %d\n", __FUNCTION__, channel);
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ iapi_StopChannel(channel);
++ sdma_data[channel].running = 0;
++
++ return 0;
++}
++EXPORT_SYMBOL(mxc_dma_stop);
++
++/*
++ * Frees dma channel.
++ *
++ * @param channel channel number
++ */
++void mxc_free_dma(int channel)
++{
++ int i;
++
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return;
++
++ mxc_dma_stop(channel);
++
++ if (sdma_data[channel].event_id != 0) {
++ iapi_SetChannelEventMapping(sdma_data[channel].event_id, 0x0);
++ }
++ if (sdma_data[channel].event_id2 != 0) {
++ iapi_SetChannelEventMapping(sdma_data[channel].event_id2, 0x0);
++ }
++
++ sdma_data[channel].event_id = 0;
++
++ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY, 0x0);
++ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++
++ for (i = 0; i < sdma_data[channel].bd_number; i++) {
++ iapi_IoCtl(sdma_data[channel].cd,
++ (i << BD_NUM_OFFSET) |
++ IAPI_CHANGE_SET_STATUS, 0);
++ }
++
++ iapi_Close(sdma_data[channel].cd);
++
++ strlcpy(sdma_data[channel].devicename, "not used",
++ sizeof(sdma_data[channel].devicename));
++
++ sdma_data[channel].in_use = 0;
++}
++EXPORT_SYMBOL(mxc_free_dma);
++
++/*
++ * Initializes channel's priorities
++ *
++ */
++static void __init init_priorities(void)
++{
++ iapi_IoCtl(sdma_data[0].cd, IAPI_CHANGE_PRIORITY, 0x7);
++}
++
++/*
++ * Initializes events table
++ */
++static void __init init_event_table(void)
++{
++ int channel;
++
++ for (channel = 0; channel < MAX_DMA_CHANNELS; channel++) {
++ iapi_SetChannelEventMapping(channel, 0);
++ }
++}
++
++/*
++ * Sets callback function. Used with standard dma api
++ * for supporting interrupts
++ *
++ * @param channel channel number
++ * @param callback callback function pointer
++ * @param arg argument for callback function
++ */
++void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return;
++
++ sdma_data[channel].callback = callback;
++ sdma_data[channel].arg = arg;
++}
++EXPORT_SYMBOL(mxc_dma_set_callback);
++
++/*
++ * Synchronization function used by I.API
++ *
++ * @param channel channel number
++ */
++static int getChannel(int channel)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++
++ if (irqs_disabled() || in_atomic()) {
++ if (down_trylock(&sdma_synch_mutex[channel])) {
++ return -EBUSY;
++ }
++ } else {
++ if (down_interruptible(&sdma_synch_mutex[channel])) {
++ return -EBUSY;
++ }
++ }
++
++ return 0;
++}
++
++/*
++ * Synchronization function used by I.API
++ *
++ * @param channel channel number
++ */
++static int releaseChannel(int channel)
++{
++ if (channel < 0 || channel >= MAX_DMA_CHANNELS)
++ return -EINVAL;
++ up(&sdma_synch_mutex[channel]);
++ return 0;
++}
++
++/*
++ * Unmask interrupt function. Used by I.API
++ *
++ */
++//static unsigned long flags;
++static void unmask_sdma_interrupt(void)
++{
++ /* Commented out to take care of the PREEMPT_RT option
++ * local_irq_restore(flags);
++ */
++}
++
++/*
++ * Mask interrupt function. Used by I.API
++ *
++ */
++static void mask_sdma_interrupt(void)
++{
++ /* Commented to take of the PREEMPT_RT option
++ * local_irq_save(flags);
++ */
++}
++
++#ifdef DEBUG
++static void *sdma_memcpy(void *dst, const void *src, size_t len)
++{
++ DBG(1, "%s: Copying %u byte from %p..%p to %p..%p\n", __FUNCTION__,
++ len, src, src + len - 1, dst, dst + len - 1);
++ memcpy(dst, src, len);
++ return dst;
++}
++#endif
++
++/*
++ * Initializes I.API
++ */
++static int __init init_iapi_struct(void)
++{
++ printk(KERN_INFO "Using SDMA I.API\n");
++
++ iapi_Malloc = &sdma_malloc;
++#ifdef CONFIG_SDMA_IRAM
++ iapi_iram_Malloc = &sdma_iram_malloc;
++#endif /* CONFIG_SDMA_IRAM */
++
++ iapi_Free = &sdma_free;
++ iapi_Virt2Phys = sdma_virt_to_phys;
++ iapi_Phys2Virt = sdma_phys_to_virt;
++ iapi_memset = &memset;
++#ifndef DEBUG
++ iapi_memcpy = &memcpy;
++#else
++ iapi_memcpy = &sdma_memcpy;
++#endif
++ iapi_GotoSleep = &sdma_sleep_channel;
++ iapi_WakeUp = &sdma_wakeup_channel;
++ iapi_InitSleep = &sdma_init_sleep;
++ iapi_ReleaseChannel = &releaseChannel;
++ iapi_GetChannel = &getChannel;
++
++ iapi_EnableInterrupts = &unmask_sdma_interrupt;
++ iapi_DisableInterrupts = &mask_sdma_interrupt;
++
++ sdma_data[0].cd = kzalloc(sizeof(channelDescriptor), GFP_KERNEL);
++ if (sdma_data[0].cd == NULL)
++ return -ENOMEM;
++ return 0;
++}
++
++/*
++ * Initializes channel synchronization mutexes
++ */
++static void __init sdma_init_mutexes(void)
++{
++ int i;
++
++ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
++ init_MUTEX(&sdma_synch_mutex[i]);
++ }
++
++ init_MUTEX(&sdma_status_mutex);
++}
++
++/*
++ * Channels status read proc file system function
++ *
++ * @param buf pointer to the buffer the data shuld be written to.
++ * @param start pointer to the pointer where the new data is
++ * written to.
++ * procedure should update the start pointer to point to
++ * where in the buffer the data was written.
++ * @param offset offset from start of the file
++ * @param count number of bytes to read.
++ * @param eof pointer to eof flag. sould be set to 1 when
++ * reaching eof.
++ * @param data driver specific data pointer.
++ *
++ * @return number byte read from the log buffer.
++ */
++static int proc_read_channels(char *buf, char **start, off_t offset, int count,
++ int *eof, void *data)
++{
++ char *log;
++ char *log_ptr;
++ char tmp[48];
++ int i;
++//#define LOG_BUF_SIZE 4096
++
++#ifdef LOG_BUF_SIZE
++ log = kzalloc(LOG_BUF_SIZE, GFP_KERNEL);
++ if (log == NULL) {
++ return -ENOMEM;
++ }
++#else
++ log = buf;
++#endif
++ log_ptr = log;
++
++ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
++ if (sdma_data[i].in_use == 0) {
++ continue;
++ }
++
++ memset(tmp, 0, sizeof(tmp));
++ snprintf(tmp, sizeof(tmp), "Channel %d: %s\n", i,
++ sdma_data[i].devicename);
++#ifndef LOG_BUF_SIZE
++ strlcpy(log_ptr, tmp, PAGE_SIZE - (log_ptr - log));
++#else
++ strlcpy(log_ptr, tmp, LOG_BUF_SIZE - (log_ptr - log));
++#endif
++ log_ptr += strlen(tmp);
++ if (log_ptr - log >= PAGE_SIZE)
++ break;
++ }
++
++ if (offset > (log_ptr - log)) {
++ *eof = 1;
++ count = 0;
++ } else {
++ if (offset + count > (log_ptr - log)) {
++ count = (log_ptr - log) - offset;
++ *eof = 1;
++ } else {
++ *eof = 0;
++ }
++
++ memcpy(buf, log, count);
++ *start = buf;
++ }
++#ifdef LOG_BUF_SIZE
++ kfree(log);
++#endif
++ return count;
++}
++
++/*
++ * SDMA proc file system read function
++ */
++static int __init init_proc_fs(void)
++{
++ struct proc_dir_entry *sdma_proc_dir;
++ int res;
++
++ res = 0;
++
++ sdma_proc_dir = proc_mkdir("sdma", NULL);
++ create_proc_read_entry("channels", 0, sdma_proc_dir,
++ proc_read_channels, NULL);
++
++ if (res < 0) {
++ printk(KERN_WARNING "Failed create SDMA proc entry\n");
++ }
++
++ return res;
++}
++
++/*
++ * Initializes SDMA private data
++ */
++static void __init init_sdma_data(void)
++{
++ int i;
++
++ sdma_data[0].in_use = 1;
++ strcpy(sdma_data[0].devicename, "MCU");
++
++ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
++ sdma_data[i].channel = i;
++ }
++}
++
++#if defined(CONFIG_MXC_SUPER_GEM)
++/*
++ * Initialize the Super GEM SDMA channel
++ *
++ * @return returns NO FUCKING -1 on error, 0 on success.
++ */
++static int __init init_super_gem(void)
++{
++ channelDescriptor *cd;
++ script_data context;
++ int res = 0;
++
++ res = iapi_Open(sdma_data[0].cd, MXC_DMA_CHANNEL_GEM);
++ if (res < 0) {
++ return res;
++ }
++ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 1;
++ cd = CHAD(MXC_DMA_CHANNEL_GEM);
++ memset(&context, 0, sizeof(script_data));
++ context.load_address = sdma_script_addrs.mxc_sdma_utra_addr;
++ context.wml = M3_BASE_ADDRESS;
++ res = iapi_AssignScript(cd, &context);
++ if (res < 0) {
++ iapi_Close(cd);
++ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
++ return res;
++ }
++ res = iapi_IoCtl(cd, IAPI_CHANGE_OWNERSHIP,
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
++ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
++ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
++ if (res < 0) {
++ iapi_Close(cd);
++ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
++ return res;
++ }
++ /* Set EP=1, which is required to start SuperGem script the first time */
++ /* This can be done only on the AP side */
++ SDMA_H_EVTPEND |= 1 << MXC_DMA_CHANNEL_GEM;
++
++ res = iapi_SetChannelEventMapping(DMA_REQ_GEM,
++ 1 << MXC_DMA_CHANNEL_GEM);
++ if (res < 0) {
++ iapi_Close(cd);
++ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
++ return res;
++ }
++
++ return 0;
++}
++#endif
++
++/*
++ * Initializes dma
++ */
++int __init sdma_init(void)
++{
++ int res;
++ configs_data confreg_data;
++ struct clk *ahb_clk;
++
++ sdma_base_addr = ioremap(SDMA_BASE_ADDR, SZ_16K);
++ if (sdma_base_addr == NULL)
++ return -ENOMEM;
++
++ /* Initialize to the default values */
++ confreg_data = iapi_ConfigDefaults;
++
++#ifdef MXC_SDMA_DSPDMA
++ confreg_data.dspdma = MXC_SDMA_DSPDMA;
++#endif
++ /* Set ACR bit */
++ mxc_sdma_clk = clk_get_sys(NULL, "sdma");
++ if (IS_ERR(mxc_sdma_clk)) {
++ res = PTR_ERR(mxc_sdma_clk);
++ printk(KERN_EMERG "Failed to get SDMA clock: %d\n", res);
++ goto clk_fail;
++ }
++
++ ahb_clk = clk_get_sys(NULL, "ahb");
++ if (IS_ERR(ahb_clk)) {
++ res = PTR_ERR(ahb_clk);
++ printk(KERN_EMERG "Failed to get SDMA clock: %d\n", res);
++ goto clk_fail;
++ }
++ clk_enable(mxc_sdma_clk);
++ clk_enable(ahb_clk);
++ printk(KERN_INFO "AHB clock rate: %lu.%03luMHz SDMA clock rate: %lu.%03luMHz\n",
++ clk_get_rate(ahb_clk) / 1000000,
++ clk_get_rate(ahb_clk) / 1000 % 1000,
++ clk_get_rate(mxc_sdma_clk) / 1000000,
++ clk_get_rate(mxc_sdma_clk) / 1000 % 1000);
++ if (clk_get_rate(ahb_clk) / clk_get_rate(mxc_sdma_clk) != 2) {
++ printk(KERN_INFO "Setting SDMA ACR\n");
++ confreg_data.acr = 1;
++ }
++ clk_disable(ahb_clk);
++ clk_put(ahb_clk);
++
++ init_sdma_data();
++
++ init_sdma_pool();
++
++ res = request_irq(MXC_INT_SDMA, sdma_int_handler, 0, "mxc-sdma", NULL);
++ if (res) {
++ printk(KERN_EMERG "Failed to get SDMA clock: %d\n", res);
++ goto sdma_init_fail;
++ }
++
++ sdma_init_mutexes();
++
++ res = init_iapi_struct();
++ if (res)
++ goto free_irq;
++
++ mxc_sdma_get_script_info(&sdma_script_addrs);
++
++ res = iapi_Init(sdma_data[0].cd, &confreg_data,
++ sdma_script_addrs.mxc_sdma_start_addr,
++ sdma_script_addrs.mxc_sdma_ram_code_size * 2,
++ sdma_script_addrs.mxc_sdma_ram_code_start_addr, 0x50);
++ if (res < 0) {
++ printk(KERN_EMERG "Failed to init SDMA API: %d\n", res);
++ goto free_mem;
++ }
++
++ init_priorities();
++
++ init_event_table();
++
++#if defined(CONFIG_MXC_SUPER_GEM)
++ res = init_super_gem();
++ if (res < 0) {
++ goto free_mem;
++ }
++#endif
++
++ init_proc_fs();
++
++ printk(KERN_INFO "MXC SDMA API initialized\n");
++
++ clk_disable(mxc_sdma_clk);
++ return res;
++free_mem:
++ kfree(sdma_data[0].cd);
++free_irq:
++ free_irq(MXC_INT_SDMA, NULL);
++sdma_init_fail:
++ clk_disable(mxc_sdma_clk);
++ clk_put(mxc_sdma_clk);
++clk_fail:
++ iounmap(sdma_base_addr);
++ sdma_base_addr = NULL;
++ printk(KERN_ERR "Error %d in sdma_init\n", res);
++ return res;
++}
++arch_initcall(sdma_init);
++
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_DESCRIPTION("MXC Linux SDMA API");
++MODULE_LICENSE("GPL");
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/sdma.h linux.35.new/arch/arm/plat-mxc/sdma/sdma.h
+--- linux.35.old/arch/arm/plat-mxc/sdma/sdma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/sdma.h 2010-12-03 09:51:55.416347546 +0100
+@@ -0,0 +1,13 @@
++#ifndef __SDMA_H
++#define __SDMA_H
++
++extern struct clk *mxc_sdma_clk;
++extern void __iomem *sdma_base_addr;
++
++/*
++ * SDMA buffers pool initialization function
++ */
++extern void init_sdma_pool(void);
++
++
++#endif /* __SDMA_H */
+diff -urN linux.35.old/arch/arm/plat-mxc/sdma/sdma_malloc.c linux.35.new/arch/arm/plat-mxc/sdma/sdma_malloc.c
+--- linux.35.old/arch/arm/plat-mxc/sdma/sdma_malloc.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/sdma/sdma_malloc.c 2010-12-03 09:51:55.416347546 +0100
+@@ -0,0 +1,404 @@
++/*
++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/*!
++ * @file plat-mxc/sdma/sdma_malloc.c
++ * @brief This file contains functions for SDMA non-cacheable buffers allocation
++ *
++ * SDMA (Smart DMA) is used for transferring data between MCU and peripherals
++ *
++ * @ingroup SDMA
++ */
++
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++
++#include <asm/dma.h>
++#include <asm/mach/dma.h>
++#include <mach/hardware.h>
++#include <mach/sdma.h>
++
++#include <epm.h>
++#include "sdma.h"
++
++#ifdef CONFIG_SDMA_IRAM
++#define IRAM_VIRT_BASE IRAM_BASE_ADDR_VIRT
++#define IRAM_PHYS_BASE IRAM_BASE_ADDR
++#if (CONFIG_SDMA_IRAM_SIZE & 0x3FF)
++#error "IRAM size of SDMA should be multiple of 1Kbytes"
++#else
++#define IRAM_SDMA_SIZE CONFIG_SDMA_IRAM_SIZE /* 4K */
++#endif
++#define IRAM_UNIT_SIZE 512
++#define IRAM_POOL_SIZE (IRAM_SDMA_SIZE/IRAM_UNIT_SIZE)
++
++#define IS_IRAM_VIRT(x) (((x) < IRAM_VIRT_BASE) ? 0 : \
++ (((x) - IRAM_VIRT_BASE) > IRAM_SDMA_SIZE) ? 0 : 1)
++
++#define IS_IRAM_PHYS(x) (((x) < IRAM_PHYS_BASE) ? 0: \
++ (((x) - IRAM_PHYS_BASE) > IRAM_SDMA_SIZE) ? 0 : 1)
++#endif /*CONFIG_SDMA_IRAM */
++
++/*!
++ * Defines SDMA non-cacheable buffers pool
++ */
++static struct dma_pool *pool;
++
++#ifdef CONFIG_SDMA_IRAM
++typedef struct iram_head_s {
++ struct list_head list;
++} iram_head_t;
++
++static spinlock_t iram_pool_lock = SPIN_LOCK_UNLOCKED;
++static struct list_head iram_free_list;
++static unsigned char iram_pool_flag[IRAM_POOL_SIZE];
++
++static void sdma_iram_free(void *buf);
++#endif /*CONFIG_SDMA_IRAM */
++
++/*!
++ * SDMA memory conversion hashing structure
++ */
++typedef struct {
++ struct list_head node;
++ int use_count;
++ /*! Virtual address */
++ void *virt;
++ /*! Physical address */
++ unsigned long phys;
++} virt_phys_struct;
++
++static struct list_head buf_map;
++
++/*!
++ * Defines the size of each buffer in SDMA pool.
++ * The size must be at least 512 bytes, because
++ * sdma channel control blocks array size is 512 bytes
++ */
++#define SDMA_POOL_SIZE 1024
++
++/*!
++ * Adds new buffer structure into conversion hash tables
++ *
++ * @param vf SDMA memory conversion hashing structure
++ *
++ * @return 1 on success, 0 on fail
++ */
++static int add_entry(virt_phys_struct *vf)
++{
++ virt_phys_struct *p;
++
++ BUG_ON(in_atomic());
++ vf->phys &= PAGE_MASK;
++ vf->virt = (void *)((unsigned long)vf->virt & PAGE_MASK);
++
++ list_for_each_entry(p, &buf_map, node) {
++ if (p->virt == vf->virt) {
++ p->use_count++;
++ return 0;
++ }
++ }
++
++ p = kzalloc(sizeof(virt_phys_struct), GFP_KERNEL);
++ if (p == NULL) {
++ return -ENOMEM;
++ }
++
++ p->phys = vf->phys & PAGE_MASK;
++ p->virt = (void *)((unsigned long)vf->virt & PAGE_MASK);
++ p->use_count = 1;
++ list_add_tail(&p->node, &buf_map);
++
++ DBG(2, "added vaddr 0x%p, paddr 0x%08lX to list\n", p->virt, p->phys);
++ return 0;
++}
++
++/*!
++ * Deletes buffer stracture from conversion hash tables
++ *
++ * @param buf SDMA memory buffer virtual addr
++ *
++ * @return 0 on success, -1 on fail
++ */
++static int delete_entry(void *buf)
++{
++ virt_phys_struct *p;
++
++ buf = (void *)((unsigned long)buf & PAGE_MASK);
++
++ list_for_each_entry(p, &buf_map, node) {
++ if (p->virt == buf) {
++ p->use_count--;
++ break;
++ }
++ }
++
++ if (p->use_count == 0) {
++ list_del(&p->node);
++ kfree(p);
++ }
++
++ return 0;
++}
++
++/*!
++ * Virtual to physical address conversion functio
++ *
++ * @param buf pointer to virtual address
++ *
++ * @return physical address
++ */
++dma_addr_t sdma_virt_to_phys(void *buf)
++{
++ unsigned long offset = (unsigned long)buf & ~PAGE_MASK;
++ virt_phys_struct *p;
++
++ DBG(2, "searching for vaddr 0x%p offs=%08lx\n", buf, offset);
++
++#ifdef CONFIG_SDMA_IRAM
++ if (IS_IRAM_VIRT(buf)) {
++ if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) {
++ printk(KERN_WARNING "%s buffer offset = %ld\n",
++ __FUNCTION__, (unsigned long)buf);
++ }
++ return (unsigned long)buf + IRAM_PHYS_BASE -
++ (unsigned long)IRAM_VIRT_BASE;
++ }
++#endif /* CONFIG_SDMA_IRAM */
++
++ list_for_each_entry(p, &buf_map, node) {
++ if ((unsigned long)p->virt == ((unsigned long)buf & PAGE_MASK)) {
++ return p->phys | offset;
++ }
++ }
++
++ if (virt_addr_valid(buf)) {
++ return virt_to_phys(buf);
++ }
++
++ printk(KERN_ERR "SDMA malloc: could not translate virt address 0x%p\n",
++ buf);
++ __backtrace();
++ return 0;
++}
++EXPORT_SYMBOL(sdma_virt_to_phys);
++
++/*!
++ * Physical to virtual address conversion function
++ *
++ * @param buf pointer to physical address
++ *
++ * @return virtual address
++ */
++void *sdma_phys_to_virt(dma_addr_t buf)
++{
++ unsigned long offset = buf & ~PAGE_MASK;
++ virt_phys_struct *p;
++
++ DBG(1, "%s: phys=%08x\n", __FUNCTION__, buf);
++
++#ifdef CONFIG_SDMA_IRAM
++ if (IS_IRAM_PHYS(buf)) {
++ if (buf & (IRAM_UNIT_SIZE - 1)) {
++ printk(KERN_WARNING "%s buffer offset = %ld\n",
++ __FUNCTION__, (unsigned long)buf);
++ }
++ return buf + IRAM_VIRT_BASE - IRAM_PHYS_BASE;
++ }
++#endif /* CONFIG_SDMA_IRAM */
++
++ list_for_each_entry(p, &buf_map, node) {
++ if (p->phys == (buf & PAGE_MASK)) {
++ void *ptr = (void *)((unsigned long)p->virt | offset);
++
++ DBG(1, "%s: virt: %08lx phys: %08lx\n", __FUNCTION__,
++ (unsigned long)p->virt | offset, p->phys);
++#if 0
++ print_hex_dump(KERN_DEBUG, "sdma: ", DUMP_PREFIX_ADDRESS, 4, 4,
++ ptr, 32 * 16, 0);
++#endif
++ return ptr;
++ }
++ }
++
++ printk(KERN_ERR "SDMA malloc: could not translate phys address 0x%08x\n",
++ buf);
++ __backtrace();
++ return NULL;
++}
++EXPORT_SYMBOL(sdma_phys_to_virt);
++
++/*!
++ * Allocates uncacheable buffer
++ *
++ * @param size size of allocated buffer
++ * @return pointer to buffer
++ */
++void *sdma_malloc(size_t size)
++{
++ void *buf;
++ dma_addr_t dma_addr;
++ virt_phys_struct vf;
++
++ if (size > SDMA_POOL_SIZE) {
++ printk(KERN_ERR "size in sdma_malloc is more than %d bytes\n",
++ SDMA_POOL_SIZE);
++ return NULL;
++ } else {
++ buf = dma_pool_alloc(pool, GFP_KERNEL, &dma_addr);
++ if (buf != NULL) {
++ vf.virt = buf;
++ vf.phys = dma_addr;
++
++ if (add_entry(&vf) < 0) {
++ dma_pool_free(pool, buf, dma_addr);
++ buf = NULL;
++ }
++ }
++ }
++
++ DBG(2, "allocated vaddr 0x%p..%p phys: %08x..%08x\n",
++ buf, buf + size - 1, dma_addr, dma_addr + size - 1);
++ return buf;
++}
++EXPORT_SYMBOL(sdma_malloc);
++
++/*!
++ * Frees uncacheable buffer
++ *
++ * @param buf buffer pointer for deletion
++ */
++void sdma_free(void *buf)
++{
++#ifdef CONFIG_SDMA_IRAM
++ if (IS_IRAM_VIRT(buf)) {
++ sdma_iram_free(buf);
++ return;
++ }
++#endif /* CONFIG_SDMA_IRAM */
++
++ dma_pool_free(pool, buf, sdma_virt_to_phys(buf));
++ delete_entry(buf);
++}
++EXPORT_SYMBOL(sdma_free);
++
++#ifdef CONFIG_SDMA_IRAM
++/*!
++ * Allocates uncacheable buffer from IRAM
++ */
++void *sdma_iram_malloc(size_t size)
++{
++ void *buf = NULL;
++ int index = -1;
++ unsigned long flags;
++
++ if (size > IRAM_UNIT_SIZE) {
++ printk(KERN_WARNING
++ "size in sdma_iram_malloc is more than %d bytes\n",
++ IRAM_UNIT_SIZE);
++ } else {
++ spin_lock_irqsave(&iram_pool_lock, flags);
++ if (!list_empty(&iram_free_list)) {
++ buf =
++ list_entry(iram_free_list.next, iram_head_t, list);
++ list_del(iram_free_list.next);
++ index = ((unsigned long)(buf - IRAM_VIRT_BASE)) /
++ IRAM_UNIT_SIZE;
++ if (index < 0 || index >= IRAM_POOL_SIZE) {
++ spin_unlock_irqrestore(&iram_pool_lock, flags);
++ printk(KERN_ERR "The iram pool has crashed\n");
++ return NULL;
++ }
++ if (iram_pool_flag[index]) {
++ spin_unlock_irqrestore(&iram_pool_lock, flags);
++ printk(KERN_WARNING
++ "iram block %d already has been allocated \n",
++ index);
++ }
++ iram_pool_flag[index] = 1;
++ }
++ spin_unlock_irqrestore(&iram_pool_lock, flags);
++ if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) {
++ printk(KERN_WARNING
++ "the start address is not align of %d, buffer offset %ld\n",
++ IRAM_UNIT_SIZE, (unsigned long)buf);
++
++ buf = PTR_ALIGN(buf, IRAM_UNIT_SIZE);
++ }
++ }
++ return buf;
++}
++
++/*!
++ * Free uncacheable buffer into IRAM.
++ */
++static void sdma_iram_free(void *buf)
++{
++ iram_head_t *p;
++ int index;
++ unsigned long flags;
++
++ /* The check of parameter will be done in sdma_free */
++ index = ((unsigned long)(buf - IRAM_VIRT_BASE)) / IRAM_UNIT_SIZE;
++ spin_lock_irqsave(&iram_pool_lock, flags);
++ p = (iram_head_t *)((unsigned long)buf & ~(IRAM_UNIT_SIZE - 1));
++ list_add_tail(&(p->list), &iram_free_list);
++ if (iram_pool_flag[index]) {
++ iram_pool_flag[index] = 0;
++ } else {
++ printk(KERN_WARNING
++ "Free %p which IRAM block %d is already freed\n", buf,
++ index);
++ }
++ spin_unlock_irqrestore(&iram_pool_lock, flags);
++}
++
++/*!
++ * Initialized the free list of IRAM.
++ */
++static void iram_pool_init(void)
++{
++ int i;
++ iram_head_t *p;
++
++ memset(iram_pool_flag, 0, IRAM_POOL_SIZE);
++ INIT_LIST_HEAD(&iram_free_list);
++ for (i = 0; i < IRAM_POOL_SIZE; i++) {
++ p = (iram_head_t *)(IRAM_VIRT_BASE + i * IRAM_UNIT_SIZE);
++ list_add_tail(&(p->list), &iram_free_list);
++ }
++}
++#endif /* CONFIG_SDMA_IRAM */
++
++/*!
++ * SDMA buffers pool initialization function
++ */
++void __init init_sdma_pool(void)
++{
++#ifdef CONFIG_SDMA_IRAM
++ iram_pool_init();
++#endif /* CONFIG_SDMA_IRAM */
++
++ pool = dma_pool_create("SDMA", NULL, SDMA_POOL_SIZE, 0, 0);
++
++ INIT_LIST_HEAD(&buf_map);
++}
++
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_DESCRIPTION("MXC Linux SDMA API");
++MODULE_LICENSE("GPL");
+diff -urN linux.35.old/arch/arm/plat-mxc/ssi.c linux.35.new/arch/arm/plat-mxc/ssi.c
+--- linux.35.old/arch/arm/plat-mxc/ssi.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/arch/arm/plat-mxc/ssi.c 2010-12-03 09:51:55.420348302 +0100
+@@ -0,0 +1,228 @@
++/*
++ * Copyright (C) 2008 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the:
++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
++ */
++
++#include <linux/kernel.h>
++#include <linux/mutex.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <linux/ioport.h>
++#include <mach/hardware.h>
++
++#include <mach/dma.h>
++#include <mach/ssi_port.h>
++
++#ifdef DEBUG
++static int debug = 1;
++#define dbg_lvl(n) ((n) < debug)
++module_param(debug, int, S_IRUGO | S_IWUSR);
++#else
++#define dbg_lvl(n) 0
++static int debug;
++module_param(debug, int, 0);
++#endif
++
++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0)
++
++static DEFINE_MUTEX(mxc_ssi_lock);
++
++static struct resource mxc_ssi_resources[][4] = {
++ {
++ {
++ .start = SSI1_BASE_ADDR,
++ .end = SSI1_BASE_ADDR + 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = MX25_INT_SSI1,
++ .end = MX25_INT_SSI1,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
++ },
++ {
++ .start = MXC_DMA_SSI1_16BIT_TX0,
++ .end = MXC_DMA_SSI1_16BIT_TX0,
++ .flags = IORESOURCE_DMA,
++ },
++ {
++ .start = MXC_DMA_SSI1_16BIT_RX0,
++ .end = MXC_DMA_SSI1_16BIT_RX0,
++ .flags = IORESOURCE_DMA,
++ },
++ },
++ {
++ {
++ .start = SSI2_BASE_ADDR,
++ .end = SSI2_BASE_ADDR + 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = MX25_INT_SSI2,
++ .end = MX25_INT_SSI2,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
++ },
++ {
++ .start = MXC_DMA_SSI2_16BIT_TX0,
++ .end = MXC_DMA_SSI2_16BIT_TX0,
++ .flags = IORESOURCE_DMA,
++ },
++ {
++ .start = MXC_DMA_SSI2_16BIT_RX0,
++ .end = MXC_DMA_SSI2_16BIT_RX0,
++ .flags = IORESOURCE_DMA,
++ },
++ },
++};
++#define NUM_SSI_PORTS ARRAY_SIZE(mxc_ssi_ports)
++
++static struct mxc_ssi_port mxc_ssi_ports[] = {
++ {
++ .num = 0,
++ .owner = THIS_MODULE,
++ .res = mxc_ssi_resources[0],
++ },
++ {
++ .num = 1,
++ .owner = THIS_MODULE,
++ .res = mxc_ssi_resources[1],
++ },
++};
++
++static int _mxc_ssi_init_port(int index, struct platform_device *parent,
++ struct mxc_ssi_port **ssi_port)
++{
++ int ret = -EBUSY;
++ struct mxc_ssi_port *port = &mxc_ssi_ports[index];
++ struct platform_device *pdev;
++ struct resource *res;
++
++ BUG_ON(index < 0 || index >= NUM_SSI_PORTS);
++
++ pdev = platform_device_register_simple("mxc-ssi", index,
++ port->res,
++ ARRAY_SIZE(mxc_ssi_resources[index]));
++ if (pdev == NULL) {
++ return -ENOMEM;
++ }
++ DBG(0, "%s: Added platform_device %s\n", __FUNCTION__, pdev->name);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ ret = -ENODEV;
++ goto pdev_free;
++ }
++
++ DBG(0, "%s: Requesting mem region %08lx..%08lx\n", __FUNCTION__,
++ (unsigned long)res->start, (unsigned long)res->end);
++ if (!request_mem_region(res->start, resource_size(res), parent->name)) {
++ ret = -EBUSY;
++ goto pdev_free;
++ }
++
++ port->ssi_clk = clk_get(&pdev->dev, NULL);
++ if (IS_ERR(port->ssi_clk)) {
++ ret = PTR_ERR(port->ssi_clk);
++ dev_err(&pdev->dev, "Failed to get SSI clock: %d\n", ret);
++ goto pdev_free;
++ }
++ port->in_use = 1;
++ port->parent = pdev;
++ *ssi_port = port;
++ return 0;
++
++pdev_free:
++ DBG(0, "%s: Unregistering %s\n", __FUNCTION__, pdev->name);
++ platform_device_unregister(pdev);
++ return ret;
++}
++
++static inline void mxc_ssi_reserve_port(int index)
++{
++ mxc_ssi_ports[index].in_use++;
++ BUG_ON(mxc_ssi_ports[index].in_use != 1);
++}
++
++static inline void mxc_ssi_unreserve_port(int index)
++{
++ mxc_ssi_ports[index].in_use--;
++ BUG_ON(mxc_ssi_ports[index].in_use);
++}
++
++static inline int mxc_ssi_port_in_use(int index)
++{
++ return mxc_ssi_ports[index].in_use;
++}
++
++int mxc_ssi_request_port(int index, struct platform_device *parent,
++ struct mxc_ssi_port **ssi_port)
++{
++ int ret = -EBUSY;
++
++ if (index > 0 && index >= NUM_SSI_PORTS) {
++ dev_err(&parent->dev, "Bad SSI port index %d; valid range: 0..%d or <0 for any port\n",
++ index, NUM_SSI_PORTS - 1);
++ return -EINVAL;
++ }
++
++ if (ssi_port == NULL) {
++ dev_err(&parent->dev, "No pointer for return value\n");
++ return -EINVAL;
++ }
++
++ mutex_lock(&mxc_ssi_lock);
++ if (index >= 0 && !mxc_ssi_port_in_use(index)) {
++ ret = 0;
++ } else {
++ for (index = 0; index < NUM_SSI_PORTS; index++) {
++ if (!mxc_ssi_port_in_use(index)) {
++ ret = 0;
++ break;
++ }
++ }
++ }
++ if (ret != 0) {
++ dev_dbg(&parent->dev, "All SSI ports are in use\n");
++ goto unlock;
++ }
++ mxc_ssi_reserve_port(index);
++
++ ret = _mxc_ssi_init_port(index, parent, ssi_port);
++ if (ret)
++ goto err;
++
++ ret = index;
++ goto unlock;
++
++err:
++ mxc_ssi_unreserve_port(index);
++unlock:
++ mutex_unlock(&mxc_ssi_lock);
++ return ret;
++}
++EXPORT_SYMBOL(mxc_ssi_request_port);
++
++void mxc_ssi_release_port(struct mxc_ssi_port *ssi_port)
++{
++ if (ssi_port != NULL) {
++ WARN_ON(!ssi_port->in_use);
++ clk_put(ssi_port->ssi_clk);
++ ssi_port->in_use = 0;
++ platform_device_unregister(ssi_port->parent);
++ }
++}
++EXPORT_SYMBOL(mxc_ssi_release_port);
+diff -urN linux.35.old/drivers/input/touchscreen/ads7846.c linux.35.new/drivers/input/touchscreen/ads7846.c
+--- linux.35.old/drivers/input/touchscreen/ads7846.c 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/drivers/input/touchscreen/ads7846.c 2011-01-12 08:13:18.592488310 +0100
+@@ -604,6 +604,9 @@
+ if (ts->swap_xy)
+ swap(x, y);
+
++ if (1/*ts->mirror_x*/)
++ x = 4096 - x;
++
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);
+diff -urN linux.35.old/drivers/input/touchscreen/imx_adc_ts.c linux.35.new/drivers/input/touchscreen/imx_adc_ts.c
+--- linux.35.old/drivers/input/touchscreen/imx_adc_ts.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/drivers/input/touchscreen/imx_adc_ts.c 2010-12-03 09:51:55.420348302 +0100
+@@ -0,0 +1,162 @@
++/*
++ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/*!
++ * @file imx_adc_ts.c
++ *
++ * @brief Driver for the Freescale Semiconductor i.MX ADC touchscreen.
++ *
++ * This touchscreen driver is designed as a standard input driver. It is a
++ * wrapper around the low level ADC driver. Much of the hardware configuration
++ * and touchscreen functionality is implemented in the low level ADC driver.
++ * During initialization, this driver creates a kernel thread. This thread
++ * then calls the ADC driver to obtain touchscreen values continously. These
++ * values are then passed to the input susbsystem.
++ *
++ * @ingroup touchscreen
++ */
++
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/input.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/freezer.h>
++#include <linux/imx_adc.h>
++
++#define IMX_ADC_TS_NAME "imx_adc_ts"
++
++static struct input_dev *imx_inputdev;
++static u32 input_ts_installed;
++
++static int cal[7] = {1,0,0,0,1,0,1};
++module_param_array(cal, int, NULL, 0);
++MODULE_PARM_DESC(cal, "Touchscreen calibration values as reported by \
++ts_calibrate");
++
++static int dim[4] = { 190, 3960, 60, 4000};
++module_param_array(dim, int, NULL, 0);
++MODULE_PARM_DESC(dim, "Maximum touchscreen range (x-left, x-right, y-top, \
++y-bottom)");
++
++static int axis_swap = 0;
++module_param(axis_swap, int, 0);
++MODULE_PARM_DESC(axis_swap, "Swap X and Y axis");
++
++static void imx_adc_ts_calibrate(struct input_dev *idev, u32 *pressure,
++u32 *x, u32 *y)
++{
++ int xtemp,ytemp;
++
++ if (!cal[6])
++ cal[6] = 1;
++
++ xtemp = *x; ytemp = *y;
++ *x = ( cal[2] +
++ cal[0]*xtemp +
++ cal[1]*ytemp ) / cal[6];
++ *y = ( cal[5] +
++ cal[3]*xtemp +
++ cal[4]*ytemp ) / cal[6];
++
++}
++
++
++static int ts_thread(void *arg)
++{
++ struct t_touch_screen ts_sample;
++ int wait = 0;
++ daemonize("imx_adc_ts");
++ while (input_ts_installed) {
++ try_to_freeze();
++
++ memset(&ts_sample, 0, sizeof(ts_sample));
++ if (0 != imx_adc_get_touch_sample(&ts_sample, !wait))
++ continue;
++
++ if (axis_swap)
++ swap(ts_sample.x_position, ts_sample.y_position);
++
++ if (!(dim[0] || dim[1] || dim[2] || dim[3]))
++ imx_adc_ts_calibrate(imx_inputdev, &ts_sample.contact_resistance, &ts_sample.x_position, &ts_sample.y_position);
++
++ input_report_abs(imx_inputdev, ABS_X, ts_sample.x_position);
++ input_report_abs(imx_inputdev, ABS_Y, ts_sample.y_position);
++ input_report_abs(imx_inputdev, ABS_PRESSURE,
++ ts_sample.contact_resistance);
++ input_sync(imx_inputdev);
++ wait = ts_sample.contact_resistance;
++ msleep(10);
++ }
++
++ return 0;
++}
++
++static int __init imx_adc_ts_init(void)
++{
++ int retval;
++
++ if (!is_imx_adc_ready())
++ return -ENODEV;
++
++ imx_inputdev = input_allocate_device();
++ if (!imx_inputdev) {
++ pr_err("imx_ts_init: not enough memory for input device\n");
++ return -ENOMEM;
++ }
++
++ imx_inputdev->name = IMX_ADC_TS_NAME;
++ imx_inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
++ imx_inputdev->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
++ imx_inputdev->absbit[0] =
++ BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE);
++
++
++ if (axis_swap) {
++ swap(dim[0], dim[2]);
++ swap(dim[1], dim[3]);
++ }
++
++ input_set_abs_params(imx_inputdev, ABS_X, dim[0], dim[1], 0, 0);
++ input_set_abs_params(imx_inputdev, ABS_Y, dim[2], dim[3], 0, 0);
++
++ retval = input_register_device(imx_inputdev);
++ if (retval < 0) {
++ input_free_device(imx_inputdev);
++ return retval;
++ }
++
++ input_ts_installed = 1;
++ kthread_run(ts_thread, NULL, "ts_thread");
++ pr_info("i.MX ADC input touchscreen loaded.\n");
++ return 0;
++}
++
++static void __exit imx_adc_ts_exit(void)
++{
++ input_ts_installed = 0;
++ input_unregister_device(imx_inputdev);
++// if (imx_inputdev) { // input_free_device() must not be used after calling input_unregister_device()
++// input_free_device(imx_inputdev);
++ imx_inputdev = NULL;
++// }
++}
++
++late_initcall(imx_adc_ts_init);
++module_exit(imx_adc_ts_exit);
++
++MODULE_DESCRIPTION("i.MX ADC input touchscreen driver");
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_LICENSE("GPL");
+diff -urN linux.35.old/drivers/input/touchscreen/Kconfig linux.35.new/drivers/input/touchscreen/Kconfig
+--- linux.35.old/drivers/input/touchscreen/Kconfig 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/drivers/input/touchscreen/Kconfig 2010-12-03 09:51:55.420348302 +0100
+@@ -268,6 +268,18 @@
+ To compile this driver as a module, choose M here: the
+ module will be called jornada720_ts.
+
++config TOUCHSCREEN_IMX_ADC
++ tristate "Freescale i.MX ADC touchscreen input driver"
++ depends on IMX_ADC
++ help
++ Say Y here if you have a Freescale i.MX based board with a
++ touchscreen interfaced to the processor's integrated ADC.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called imx_adc_ts.
++
+ config TOUCHSCREEN_HTCPEN
+ tristate "HTC Shift X9500 touchscreen"
+ depends on ISA
+@@ -339,6 +351,13 @@
+ To compile this driver as a module, choose M here: the
+ module will be called atmel_tsadcc.
+
++config TOUCHSCREEN_MXC_TSC
++ tristate "i.MX25 Touchscreen Interface"
++ depends on ARCH_MX25
++ help
++ Say Y here if you have a 4-wire touchscreen connected to the
++ ADC Controller on your Freescale i.MX25 SoC.
++
+ config TOUCHSCREEN_UCB1400
+ tristate "Philips UCB1400 touchscreen"
+ depends on AC97_BUS
+diff -urN linux.35.old/drivers/input/touchscreen/Makefile linux.35.new/drivers/input/touchscreen/Makefile
+--- linux.35.old/drivers/input/touchscreen/Makefile 2010-08-02 00:11:14.000000000 +0200
++++ linux.35.new/drivers/input/touchscreen/Makefile 2010-12-03 09:51:55.420348302 +0100
+@@ -27,6 +27,8 @@
+ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
++obj-$(CONFIG_TOUCHSCREEN_MXC_TSC) += mxc_tsc.o
++obj-$(CONFIG_TOUCHSCREEN_IMX_ADC) += imx_adc_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
+ obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
+diff -urN linux.35.old/drivers/input/touchscreen/mxc_tsc.c linux.35.new/drivers/input/touchscreen/mxc_tsc.c
+--- linux.35.old/drivers/input/touchscreen/mxc_tsc.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/drivers/input/touchscreen/mxc_tsc.c 2010-12-03 09:51:55.424347282 +0100
+@@ -0,0 +1,1162 @@
++/*
++ * Freescale i.MX25 Touch Screen Driver
++ *
++ * Copyright (c) 2009 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ * Based on atmel_tsadcc.c
++ * Copyright (c) 2008 ATMEL et. al.
++ * and code from Freescale BSP
++ *
++ * 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
++
++/* FIXME: pressure values, calculated according to the formula
++ * found in the i.MX25 Reference Manual, seem rather bogus
++ */
++#define REPORT_PRESSURE
++
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/input.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/slab.h>
++#include <mach/mxc_tsc.h>
++
++#include "mxc_tsc.h"
++
++#define TSC_NUM_SAMPLES 4 /* 1..16 */
++#define ADC_NUM_SAMPLES 16 /* 1..16 */
++
++/* Default settling times */
++#define SETTLE_PCHG 0 /* 0..255 */
++#define SETTLE_DET 16
++#define SETTLE_MEAS 32
++
++
++#if (TSC_NUM_SAMPLES <= 0) || (TSC_NUM_SAMPLES > 16)
++#error Invalid value for TSC_NUM_SAMPLES
++#endif
++
++#if (ADC_NUM_SAMPLES <= 0) || (ADC_NUM_SAMPLES > 16)
++#error Invalid value for ADC_NUM_SAMPLES
++#endif
++
++#ifdef DEBUG
++static int debug = 1;
++#define dbg_lvl(n) ((n) < debug)
++module_param(debug, int, S_IRUGO | S_IWUSR);
++
++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0)
++#else
++static int debug;
++#define dbg_lvl(n) 0
++module_param(debug, int, 0);
++
++#define DBG(lvl, fmt...) do { } while (0)
++#endif
++
++static unsigned int settle_detect;
++static unsigned int settle_measure;
++static unsigned int settle_precharge;
++module_param(settle_detect, int, S_IRUGO);
++module_param(settle_measure, int, S_IRUGO);
++module_param(settle_precharge, int, S_IRUGO);
++
++
++#define DEFAULT_ADC_CLOCK 1666667
++#define DEFAULT_RX_VALUE 360
++
++struct mxc_tsc_fifo_entry {
++ unsigned int id:4,
++ data:12;
++};
++
++/* The layout of this structure depends on the setup created by mxc_tsc_config() */
++struct mxc_tsc_ts_data {
++ struct mxc_tsc_fifo_entry pendown[TSC_NUM_SAMPLES];
++ struct mxc_tsc_fifo_entry pos_x[TSC_NUM_SAMPLES];
++ struct mxc_tsc_fifo_entry pos_y[TSC_NUM_SAMPLES];
++#ifdef REPORT_PRESSURE
++ struct mxc_tsc_fifo_entry yn[TSC_NUM_SAMPLES];
++ struct mxc_tsc_fifo_entry xp[TSC_NUM_SAMPLES];
++#endif
++ struct mxc_tsc_fifo_entry pendown2[TSC_NUM_SAMPLES];
++};
++
++struct mxc_tsc_adc_data {
++ struct mxc_tsc_fifo_entry data[ADC_NUM_SAMPLES];
++};
++
++typedef union {
++ unsigned int fifo[sizeof(struct mxc_tsc_adc_data) / sizeof(int)];
++ struct mxc_tsc_adc_data data;
++} mxc_tsc_adc_fifo;
++
++typedef union {
++ unsigned int fifo[sizeof(struct mxc_tsc_ts_data) / sizeof(int)];
++ struct mxc_tsc_ts_data data;
++ struct mxc_tsc_fifo_entry raw[sizeof(struct mxc_tsc_ts_data) / sizeof(int)];
++} mxc_tsc_ts_fifo;
++
++struct mxc_tsc_irqbuf {
++ wait_queue_head_t wq;
++ long timeout;
++ unsigned long reg_base;
++ unsigned int *data;
++ unsigned short reqcount;
++ unsigned short irqcount;
++ unsigned short chunk_size;
++};
++
++struct mxc_tsc {
++ struct input_dev *input;
++ char phys[32];
++ void __iomem *reg_base;
++ struct clk *clk;
++ int irq;
++ struct work_struct work;
++ struct timer_list timer;
++ spinlock_t irq_lock;
++ wait_queue_head_t wq;
++ unsigned int pendown:1,
++ clk_enabled:1,
++ attrs:1,
++ active:1;
++ struct mxc_tsc_irqbuf adc_buf;
++ struct mxc_tsc_irqbuf tsc_buf;
++ mxc_tsc_ts_fifo *tsc_data;
++ mxc_tsc_adc_fifo *adc_data;
++ struct mutex tsc_mutex;
++ struct mutex adc_mutex;
++
++ /* parameters from platform_data or module_param */
++ mxc_tsc_mode tsc_mode;
++ unsigned int r_xplate;
++ unsigned int settle_pchg;
++ unsigned int settle_meas;
++ unsigned int settle_det;
++
++ /* conversion clock rate in kHz */
++ unsigned long clkrate;
++ unsigned short pressure;
++ unsigned short prev_absx;
++ unsigned short prev_absy;
++};
++
++static inline u32 mxc_tsc_read(struct mxc_tsc *ts_dev, int reg)
++{
++ return __raw_readl(ts_dev->reg_base + reg);
++}
++
++static inline void mxc_tsc_write(struct mxc_tsc *ts_dev, int reg, u32 val)
++{
++ __raw_writel(val, ts_dev->reg_base + reg);
++}
++
++static inline void mxc_tsc_set_mask(struct mxc_tsc *ts_dev, int reg, u32 mask)
++{
++ u32 val = mxc_tsc_read(ts_dev, reg);
++ val |= mask;
++ mxc_tsc_write(ts_dev, reg, val);
++}
++
++static inline void mxc_tsc_clr_mask(struct mxc_tsc *ts_dev, int reg, u32 mask)
++{
++ u32 val = mxc_tsc_read(ts_dev, reg);
++ val &= ~mask;
++ mxc_tsc_write(ts_dev, reg, val);
++}
++
++static void tsc_clk_enable(struct mxc_tsc *ts_dev)
++{
++ if (!ts_dev->clk_enabled) {
++ clk_enable(ts_dev->clk);
++ mxc_tsc_set_mask(ts_dev, TGCR, TGCR_IPG_CLK_EN);
++ ts_dev->clk_enabled = 1;
++ }
++}
++
++static void tsc_clk_disable(struct mxc_tsc *ts_dev)
++{
++ if (ts_dev->clk_enabled) {
++ mxc_tsc_clr_mask(ts_dev, TGCR, TGCR_IPG_CLK_EN);
++ clk_disable(ts_dev->clk);
++ ts_dev->clk_enabled = 0;
++ }
++}
++
++static inline int mxc_tsc_pendown(struct mxc_tsc *ts_dev)
++{
++ return ts_dev->pendown;
++}
++
++static inline void mxc_tsc_read_fifo(struct mxc_tsc *ts_dev,
++ struct mxc_tsc_irqbuf *irqbuf)
++{
++ int start = irqbuf->irqcount;
++ int cqsr = mxc_tsc_read(ts_dev, irqbuf->reg_base + CQSR);
++ int num_items = irqbuf->chunk_size;
++ int i;
++
++ for (i = 0; i < num_items && !(cqsr & CQSR_EMPT); i++) {
++ u32 reg = mxc_tsc_read(ts_dev, irqbuf->reg_base + CQFIFO);
++
++ BUG_ON(irqbuf->irqcount < 0);
++ if (likely(irqbuf->irqcount < irqbuf->reqcount)) {
++ BUG_ON(irqbuf->data == NULL);
++ irqbuf->data[irqbuf->irqcount] = reg;
++ } else {
++ DBG(0, "%s: Dropping spurious data sample[%d/%d] on %s queue: %08x\n",
++ __FUNCTION__, irqbuf->irqcount,
++ irqbuf->reqcount,
++ irqbuf == &ts_dev->adc_buf ? "ADC" : "TSC",
++ reg);
++ }
++ irqbuf->irqcount++;
++ cqsr = mxc_tsc_read(ts_dev, irqbuf->reg_base + CQSR);
++ }
++
++ if (irqbuf->irqcount == irqbuf->reqcount) {
++ WARN_ON(!(mxc_tsc_read(ts_dev, irqbuf->reg_base + CQSR) &
++ CQSR_EMPT));
++ wake_up(&irqbuf->wq);
++ }
++ DBG(1, "%s: Read %u items [%d..%d] from fifo\n", __FUNCTION__,
++ irqbuf->irqcount - start, start, irqbuf->irqcount - 1);
++}
++
++static int mxc_tsc_wait_data(struct mxc_tsc *ts_dev,
++ struct mxc_tsc_irqbuf *irqbuf)
++{
++ int ret;
++
++ ret = wait_event_timeout(irqbuf->wq,
++ irqbuf->irqcount >= irqbuf->reqcount,
++ irqbuf->timeout);
++
++ if (ret == 0 && irqbuf->irqcount < irqbuf->reqcount) {
++ DBG(0, "%s: Timeout waiting for %s data: got %u of %u samples\n",
++ __FUNCTION__, irqbuf == &ts_dev->adc_buf ?
++ "ADC" : "TSC", irqbuf->irqcount, irqbuf->reqcount);
++
++ mxc_tsc_set_mask(ts_dev, irqbuf->reg_base + CQCR,
++ CQCR_FRST | CQCR_QRST);
++ mxc_tsc_clr_mask(ts_dev, irqbuf->reg_base + CQCR,
++ CQCR_FRST | CQCR_QRST);
++ return -ETIME;
++ }
++ return 0;
++}
++
++static int mxc_tsc_read_adc(struct mxc_tsc *ts_dev, int chan)
++{
++ int ret;
++ u32 reg;
++ int i;
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->adc_buf;
++ struct mxc_tsc_adc_data *adc_data = &ts_dev->adc_data->data;
++
++ mutex_lock(&ts_dev->adc_mutex);
++
++ memset(adc_data, 0, sizeof(*adc_data));
++ if (WARN_ON(irqbuf->irqcount)) {
++ irqbuf->irqcount = 0;
++ }
++ irqbuf->reqcount = ADC_NUM_SAMPLES;
++
++ reg = mxc_tsc_read(ts_dev, GCC0);
++ reg = (reg & ~CC_SELIN_MASK) | chan;
++ mxc_tsc_write(ts_dev, GCC0, reg);
++
++ /* enable data ready and end of conversion interrupt */
++ mxc_tsc_clr_mask(ts_dev, GCQMR,
++ CQMR_EOQ_IRQ_MSK |
++ CQMR_FDRY_IRQ_MSK |
++ CQMR_FOR_IRQ_MSK |
++ CQMR_FER_IRQ_MSK);
++ /* start conversion */
++ mxc_tsc_set_mask(ts_dev, GCQCR, CQCR_FQS);
++
++ ret = mxc_tsc_wait_data(ts_dev, irqbuf);
++ if (ret) {
++ goto exit;
++ }
++ irqbuf->irqcount = 0;
++
++ DBG(2, "%s: Read %u words from fifo\n", __FUNCTION__, irqbuf->reqcount);
++ for (i = 0; i < irqbuf->reqcount; i++) {
++ DBG(2, "%s: data[0x%x]=%4d\n", __FUNCTION__, i,
++ adc_data->data[i].data);
++ }
++exit:
++ mxc_tsc_set_mask(ts_dev, GCQMR, CQMR_EOQ_IRQ_MSK | CQMR_FDRY_IRQ_MSK);
++ mutex_unlock(&ts_dev->adc_mutex);
++
++ return ret;
++}
++
++static int mxc_tsc_data_valid(struct mxc_tsc_fifo_entry *data, int num_samples)
++{
++ int valid = 0;
++ int i;
++
++ for (i = 0; i < num_samples; i++) {
++ DBG(2, "%s: data[%d]=%d:%d\n", __FUNCTION__, i,
++ data[i].id, data[i].data);
++ valid |= data[i].data != 0;
++ }
++ return valid;
++}
++
++static int mxc_tsc_get_data(struct mxc_tsc_fifo_entry *data, int num_samples)
++{
++ int value = 0;
++ int count = 0;
++ int i;
++
++ for (i = 0; i < num_samples; i++) {
++ DBG(3, "%s: data[%d]=%d:%d\n", __FUNCTION__, i,
++ data[i].id, data[i].data);
++ if (data[i].data == 0) {
++ DBG(2, "%s: Skipping value %d\n", __FUNCTION__, i);
++ continue;
++ }
++ if (count == 0) {
++ value = data[i].data;
++ } else {
++ value = (value * count + data[i].data) / (count + 1);
++ }
++ count++;
++ }
++ data[0].data = value;
++ return value;
++}
++
++struct mxc_tsc_attr {
++ struct device_attribute attr;
++ unsigned int chan;
++};
++
++#define to_mxc_tsc_attr(a) container_of(a, struct mxc_tsc_attr, attr)
++
++#define MXC_TSC_DEV_ATTR(_name, _mode, _chan, _read) \
++ struct mxc_tsc_attr mxc_tsc_attr_##_name = { \
++ .attr = __ATTR(_name,_mode,_read, NULL), \
++ .chan = _chan, \
++ }
++
++static ssize_t mxc_tsc_attr_get(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ ssize_t ret;
++ struct mxc_tsc *ts_dev = dev_get_drvdata(dev);
++ struct mxc_tsc_attr *mxc_tsc_attr = to_mxc_tsc_attr(attr);
++ struct mxc_tsc_adc_data *adc_data = &ts_dev->adc_data->data;
++
++ ret = mxc_tsc_read_adc(ts_dev, mxc_tsc_attr->chan);
++ if (ret != 0) {
++ dev_err(dev, "%s: Failed to read ADC%d\n", __FUNCTION__,
++ ((mxc_tsc_attr->chan & CC_SELIN_MASK) >>
++ CC_SELIN_SHIFT) - 5);
++ return ret;
++ }
++ ret = sprintf(buf, "%d\n", mxc_tsc_get_data(adc_data->data,
++ ADC_NUM_SAMPLES));
++ return ret;
++}
++
++MXC_TSC_DEV_ATTR(inaux0, S_IRUGO, CC_SELIN_INAUX0, mxc_tsc_attr_get);
++MXC_TSC_DEV_ATTR(inaux1, S_IRUGO, CC_SELIN_INAUX1, mxc_tsc_attr_get);
++MXC_TSC_DEV_ATTR(inaux2, S_IRUGO, CC_SELIN_INAUX2, mxc_tsc_attr_get);
++
++static struct attribute *mxc_tsc_attrs[] = {
++ &mxc_tsc_attr_inaux0.attr.attr,
++ &mxc_tsc_attr_inaux1.attr.attr,
++ &mxc_tsc_attr_inaux2.attr.attr,
++ NULL
++};
++
++static const struct attribute_group mxc_tsc_attr_group = {
++ .attrs = mxc_tsc_attrs,
++};
++
++static void mxc_tsc_start_measure(struct mxc_tsc *ts_dev)
++{
++ u32 reg;
++ struct mxc_tsc_ts_data *tsc_data = &ts_dev->tsc_data->data;
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->tsc_buf;
++ mxc_tsc_ts_fifo *fifo_data = ts_dev->tsc_data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ts_dev->irq_lock, flags);
++ if (ts_dev->active) {
++ goto out;
++ }
++ ts_dev->active = 1;
++
++ memset(tsc_data, 0xee, sizeof(*tsc_data));
++ irqbuf->irqcount = 0;
++ irqbuf->reqcount = ARRAY_SIZE(fifo_data->fifo);
++
++ reg = mxc_tsc_read(ts_dev, TCQSR);
++ if (WARN_ON(!(reg & CQSR_EMPT))) {
++ DBG(0, "%s: Clearing TSC FIFO\n", __FUNCTION__);
++ mxc_tsc_set_mask(ts_dev, TCQCR, CQCR_FRST | CQCR_QRST);
++ mxc_tsc_clr_mask(ts_dev, TCQCR, CQCR_FRST | CQCR_QRST);
++ }
++ mxc_tsc_write(ts_dev, TCQSR, reg);
++
++ if (mxc_tsc_pendown(ts_dev)) {
++ /* change configuration for FQS mode */
++ reg = (0x1 << CC_YPLLSW_SHIFT) | (0x1 << CC_XNURSW_SHIFT) |
++ CC_XPULSW;
++ mxc_tsc_write(ts_dev, TICR, reg);
++
++ /* FQS */
++ reg = mxc_tsc_read(ts_dev, TCQCR);
++ reg &= ~CQCR_QSM_MASK;
++ reg |= CQCR_QSM_FQS;
++ mxc_tsc_write(ts_dev, TCQCR, reg);
++ mxc_tsc_write(ts_dev, TCQCR, reg | CQCR_FQS);
++
++ /* enable end of conversion interrupt */
++ mxc_tsc_clr_mask(ts_dev, TCQMR, CQMR_EOQ_IRQ_MSK |
++ CQMR_FDRY_IRQ_MSK);
++ } else {
++ /* Config idle for 4-wire */
++ mxc_tsc_write(ts_dev, TICR, TSC_4WIRE_TOUCH_DETECT);
++
++ /* Pen interrupt starts new conversion queue */
++ reg = mxc_tsc_read(ts_dev, TCQCR);
++ reg &= ~CQCR_QSM_MASK;
++ reg |= CQCR_QSM_PEN;
++ mxc_tsc_write(ts_dev, TCQCR, reg);
++
++ /* PDEN and PDBEN */
++ mxc_tsc_set_mask(ts_dev, TGCR, TGCR_PDB_EN | TGCR_PD_EN);
++
++ /* enable end of conversion interrupt */
++ mxc_tsc_clr_mask(ts_dev, TCQMR,
++ CQMR_EOQ_IRQ_MSK |
++ CQMR_FOR_IRQ_MSK |
++ CQMR_FER_IRQ_MSK |
++ CQMR_FDRY_IRQ_MSK);
++ }
++out:
++ spin_unlock_irqrestore(&ts_dev->irq_lock, flags);
++}
++
++#define LOCK_WORK
++static int mxc_tsc_read_ts(struct mxc_tsc *ts_dev, int force)
++{
++ int ret;
++ mxc_tsc_ts_fifo *fifo_data = ts_dev->tsc_data;
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->tsc_buf;
++ struct mxc_tsc_ts_data *tsc_data = &ts_dev->tsc_data->data;
++
++#ifndef LOCK_WORK
++ mutex_lock(&ts_dev->tsc_mutex);
++#endif
++ ret = mxc_tsc_wait_data(ts_dev, irqbuf);
++ if (ret) {
++ DBG(1, "%s: Failed to get data\n", __FUNCTION__);
++ goto exit;
++ }
++
++ for (ret = 0; ret < irqbuf->reqcount; ret++) {
++ struct mxc_tsc_fifo_entry *data = &fifo_data->raw[ret];
++ DBG(2, "%s: data[%02x]@%p=%d:%03x (%08x)\n", __FUNCTION__, ret,
++ data, data->id, data->data, fifo_data->fifo[ret]);
++ }
++
++ ret = tsc_data->pendown[0].data <= 0x600 &&
++ tsc_data->pendown2[0].data <= 0x600;
++ if (ret) {
++ int pos_x = mxc_tsc_get_data(tsc_data->pos_x, TSC_NUM_SAMPLES);
++ int pos_y = mxc_tsc_get_data(tsc_data->pos_y, TSC_NUM_SAMPLES);
++#ifdef REPORT_PRESSURE
++ int xp = mxc_tsc_get_data(tsc_data->xp, TSC_NUM_SAMPLES);
++ int yn = mxc_tsc_get_data(tsc_data->yn, TSC_NUM_SAMPLES);
++#endif
++
++ DBG(1, "%s: pos_x=%4d pos_y=%4d pd=%d\n",
++ __FUNCTION__, pos_x, pos_y, ts_dev->pendown);
++ if (pos_x) {
++#ifdef REPORT_PRESSURE
++ if (mxc_tsc_data_valid(tsc_data->xp, TSC_NUM_SAMPLES)) {
++ ts_dev->pressure = ts_dev->r_xplate *
++ pos_x * (yn - xp) / xp / 4096;
++ DBG(2, "%s: xp=%4d yn=%4d p=%d\n", __FUNCTION__,
++ xp, yn, ts_dev->pressure);
++ if (ts_dev->pressure > 4095) {
++ ts_dev->pressure = 4095;
++ }
++ } else {
++ DBG(0, "%s: Invalid pressure data\n",
++ __FUNCTION__);
++ ret = -EINVAL;
++ }
++#else
++ ts_dev->pressure = 4095;
++#endif
++ DBG(1, "%s: Detected PEN DOWN with pressure %4d\n",
++ __FUNCTION__, ts_dev->pressure);
++ } else {
++ DBG(0, "%s: Discarding measurement\n", __FUNCTION__);
++ ret = -EINVAL;
++ }
++ } else {
++ DBG(1, "%s: Detected PEN UP\n", __FUNCTION__);
++ ts_dev->pendown = 0;
++ }
++exit:
++ ts_dev->active = 0;
++#ifndef LOCK_WORK
++ mutex_unlock(&ts_dev->tsc_mutex);
++#endif
++ return ret;
++}
++
++static void mxc_tsc_work(struct work_struct *w)
++{
++ struct mxc_tsc *ts_dev = container_of(w, struct mxc_tsc, work);
++ struct input_dev *input_dev = ts_dev->input;
++ struct mxc_tsc_ts_data *tsc_data = &ts_dev->tsc_data->data;
++ int ret;
++#ifdef LOCK_WORK
++ mutex_lock(&ts_dev->tsc_mutex);
++#endif
++ ret = mxc_tsc_read_ts(ts_dev, 0);
++ DBG(1, "%s: mxc_tsc_read_ts() returned %d\n", __FUNCTION__, ret);
++ if (ret > 0) {
++ DBG(1, "%s: Got sample pd=%d\n", __FUNCTION__,
++ ts_dev->pendown);
++ if (mxc_tsc_pendown(ts_dev)) {
++ DBG(2, "%s: Reporting PD event %4d @ %4d,%4d\n",
++ __FUNCTION__, ts_dev->pressure,
++ tsc_data->pos_x[0].data,
++ tsc_data->pos_y[0].data);
++
++ input_report_abs(input_dev, ABS_X,
++ tsc_data->pos_x[0].data);
++ input_report_abs(input_dev, ABS_Y,
++ tsc_data->pos_y[0].data);
++#ifdef REPORT_PRESSURE
++ input_report_abs(input_dev, ABS_PRESSURE,
++ ts_dev->pressure);
++#endif
++ input_report_key(input_dev, BTN_TOUCH, 1);
++ input_sync(input_dev);
++
++ ts_dev->prev_absx = tsc_data->pos_x[0].data;
++ ts_dev->prev_absy = tsc_data->pos_y[0].data;
++
++ mod_timer(&ts_dev->timer, jiffies +
++ msecs_to_jiffies(5));
++#ifdef LOCK_WORK
++ goto out;
++#endif
++ return;
++ }
++ } else if (ret == 0) {
++ DBG(2, "%s: Reporting PU event: %4d,%4d\n", __FUNCTION__,
++ ts_dev->prev_absx, ts_dev->prev_absy);
++ input_report_abs(input_dev, ABS_X,
++ ts_dev->prev_absx);
++ input_report_abs(input_dev, ABS_Y,
++ ts_dev->prev_absy);
++#ifdef REPORT_PRESSURE
++ input_report_abs(input_dev, ABS_PRESSURE, 0);
++#endif
++ input_report_key(input_dev, BTN_TOUCH, 0);
++ input_sync(input_dev);
++ }
++ mxc_tsc_start_measure(ts_dev);
++#ifdef LOCK_WORK
++out:
++ mutex_unlock(&ts_dev->tsc_mutex);
++#endif
++}
++
++static void mxc_tsc_timer(unsigned long data)
++{
++ struct mxc_tsc *ts_dev = (void *)data;
++ struct mxc_tsc_ts_data *tsc_data = &ts_dev->tsc_data->data;
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->tsc_buf;
++
++ /* trigger a new conversion */
++ memset(tsc_data, 0xed, sizeof(*tsc_data));
++ irqbuf->irqcount = 0;
++
++ mxc_tsc_start_measure(ts_dev);
++}
++
++static irqreturn_t mxc_tsc_interrupt(int irq, void *dev)
++{
++ struct mxc_tsc *ts_dev = dev;
++ //struct input_dev *input_dev = ts_dev->input;
++ u32 reg;
++ u32 status = mxc_tsc_read(ts_dev, TGSR);
++
++ DBG(4, "%s: TGSR=%08x\n", __FUNCTION__, status);
++
++ if (status & TGSR_TCQ_INT) {
++ u32 mask = mxc_tsc_read(ts_dev, TCQMR);
++ u32 tcqsr;
++
++ reg = mxc_tsc_read(ts_dev, TCQSR);
++ tcqsr = reg;
++ DBG(3, "%s: TCQSR=%08x TCQMR=%08x:%08x\n", __FUNCTION__,
++ reg, mask, reg & ~mask);
++ reg &= ~mask;
++ mxc_tsc_write(ts_dev, TCQSR, reg);
++ if (reg & (CQSR_FOR | CQSR_FER)) {
++ DBG(-1, "%s: Fifo overrun on TSC queue\n",
++ __FUNCTION__);
++ mxc_tsc_set_mask(ts_dev, TCQCR, CQCR_FRST | CQCR_QRST);
++ mxc_tsc_clr_mask(ts_dev, TCQCR, CQCR_FRST | CQCR_QRST);
++ } else if (reg & CQSR_FDRY) {
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->tsc_buf;
++
++ mxc_tsc_clr_mask(ts_dev, TCQCR, CQCR_FQS);
++ if (!(reg & CQSR_EMPT)) {
++ mxc_tsc_read_fifo(ts_dev, irqbuf);
++ }
++ }
++ if (reg & CQSR_PD) {
++ ts_dev->pendown = 1;
++
++ /* disable pen down detect */
++ mxc_tsc_clr_mask(ts_dev, TGCR, TGCR_PD_EN);
++
++ /* schedule new measurement */
++ schedule_work(&ts_dev->work);
++ }
++ if (reg & CQSR_EOQ) {
++ mxc_tsc_clr_mask(ts_dev, TCQCR, CQCR_FQS);
++
++ /* disable end of conversion interrupt */
++ mxc_tsc_set_mask(ts_dev, TCQMR, CQMR_EOQ_IRQ_MSK);
++
++ DBG(1, "%s: Got EOQ interrupt TCQSR=%08x:%08x\n", __FUNCTION__,
++ tcqsr, mxc_tsc_read(ts_dev, TCQSR));
++ schedule_work(&ts_dev->work);
++ }
++ }
++ if (status & TGSR_GCQ_INT) {
++ u32 mask = mxc_tsc_read(ts_dev, GCQMR);
++
++ reg = mxc_tsc_read(ts_dev, GCQSR);
++ DBG(3, "%s: GCQSR=%08x GCQMR=%08x:%08x\n", __FUNCTION__,
++ reg, mask, reg & ~mask);
++ reg &= ~mask;
++ mxc_tsc_write(ts_dev, GCQSR, reg);
++ if (reg & (CQSR_FOR | CQSR_FER)) {
++ DBG(-1, "%s: Fifo overrun on ADC queue\n",
++ __FUNCTION__);
++ mxc_tsc_set_mask(ts_dev, GCQCR, CQCR_FRST | CQCR_QRST);
++ mxc_tsc_clr_mask(ts_dev, GCQCR, CQCR_FRST | CQCR_QRST);
++ } else if (reg & CQSR_FDRY) {
++ struct mxc_tsc_irqbuf *irqbuf = &ts_dev->adc_buf;
++
++ mxc_tsc_clr_mask(ts_dev, GCQCR, CQCR_FQS);
++ if (!(reg & CQSR_EMPT)) {
++ mxc_tsc_read_fifo(ts_dev, irqbuf);
++ }
++ }
++ if (reg & CQSR_EOQ) {
++ mxc_tsc_clr_mask(ts_dev, GCQCR, CQCR_FQS);
++
++ /* disable end of conversion interrupt */
++ mxc_tsc_set_mask(ts_dev, GCQMR, CQMR_EOQ_IRQ_MSK);
++ }
++ }
++ return IRQ_HANDLED;
++}
++
++static void mxc_tsc_4wire_config(struct mxc_tsc *ts_dev)
++{
++ u32 reg;
++ int lastitemid;
++
++ /* Configure 4-wire */
++ reg = TSC_4WIRE_PRECHARGE;
++ reg |= CC_IGS;
++ mxc_tsc_write(ts_dev, TCC0, reg);
++
++ reg = TSC_4WIRE_TOUCH_DETECT;
++ reg |= (TSC_NUM_SAMPLES - 1) << CC_NOS_SHIFT;
++ reg |= ts_dev->settle_det << CC_SETTLING_TIME_SHIFT;
++ mxc_tsc_write(ts_dev, TCC1, reg);
++
++ reg = TSC_4WIRE_X_MEASURE;
++ reg |= (TSC_NUM_SAMPLES - 1) << CC_NOS_SHIFT;
++ reg |= ts_dev->settle_meas << CC_SETTLING_TIME_SHIFT;
++ mxc_tsc_write(ts_dev, TCC2, reg);
++
++ reg = TSC_4WIRE_Y_MEASURE;
++ reg |= (TSC_NUM_SAMPLES - 1) << CC_NOS_SHIFT;
++ reg |= ts_dev->settle_meas << CC_SETTLING_TIME_SHIFT;
++ mxc_tsc_write(ts_dev, TCC3, reg);
++
++ reg = TSC_4WIRE_YN_MEASURE;
++ reg |= (TSC_NUM_SAMPLES - 1) << CC_NOS_SHIFT;
++ reg |= ts_dev->settle_meas << CC_SETTLING_TIME_SHIFT;
++ mxc_tsc_write(ts_dev, TCC4, reg);
++
++ reg = TSC_4WIRE_XP_MEASURE;
++ reg |= (TSC_NUM_SAMPLES - 1) << CC_NOS_SHIFT;
++ reg |= ts_dev->settle_meas << CC_SETTLING_TIME_SHIFT;
++ mxc_tsc_write(ts_dev, TCC5, reg);
++
++#ifdef REPORT_PRESSURE
++ reg = (TCQ_ITEM_TCC0 << CQ_ITEM0_SHIFT) |
++ (TCQ_ITEM_TCC1 << CQ_ITEM1_SHIFT) |
++ (TCQ_ITEM_TCC2 << CQ_ITEM2_SHIFT) |
++ (TCQ_ITEM_TCC3 << CQ_ITEM3_SHIFT) |
++ (TCQ_ITEM_TCC4 << CQ_ITEM4_SHIFT) |
++ (TCQ_ITEM_TCC5 << CQ_ITEM5_SHIFT) |
++ (TCQ_ITEM_TCC0 << CQ_ITEM6_SHIFT) |
++ (TCQ_ITEM_TCC1 << CQ_ITEM7_SHIFT);
++ lastitemid = 7;
++ ts_dev->tsc_buf.chunk_size = 6;
++
++ /* ADC conversion requires 14 clock cycles per sample
++ * plus the settling time programmed in the TICR registers.
++ * Add 1 extra jiffy to make sure the timeout is > 0
++ */
++ ts_dev->tsc_buf.timeout = msecs_to_jiffies(
++ ((6 * TSC_NUM_SAMPLES * 14) +
++ (2 * (ts_dev->settle_pchg * 8 + 1)) +
++ (5 * (ts_dev->settle_meas * 8 + 1)) +
++ (2 * (ts_dev->settle_det * 8 + 1))) /
++ ts_dev->clkrate) + 10;
++#else
++ reg = (TCQ_ITEM_TCC0 << CQ_ITEM0_SHIFT) |
++ (TCQ_ITEM_TCC1 << CQ_ITEM1_SHIFT) |
++ (TCQ_ITEM_TCC2 << CQ_ITEM2_SHIFT) |
++ (TCQ_ITEM_TCC3 << CQ_ITEM3_SHIFT) |
++ (TCQ_ITEM_TCC0 << CQ_ITEM4_SHIFT) |
++ (TCQ_ITEM_TCC1 << CQ_ITEM5_SHIFT);
++ lastitemid = 5;
++ ts_dev->tsc_buf.chunk_size = 4;
++
++ /* ADC conversion requires 14 clock cycles per sample
++ * plus the settling time programmed in the TICR registers.
++ * Add 1 extra jiffy to make sure the timeout is > 0
++ */
++ ts_dev->tsc_buf.timeout = msecs_to_jiffies(
++ ((5 * TSC_NUM_SAMPLES * 14) +
++ (2 * (ts_dev->settle_pchg * 8 + 1)) +
++ (4 * (ts_dev->settle_meas * 8 + 1)) +
++ (2 * (ts_dev->settle_det * 8 + 1))) /
++ ts_dev->clkrate + (1000 / HZ - 1)) + 1;
++#endif
++ DBG(0, "%s: TSC timeout set to %lu jiffies %lums (%u ADC clock cycles) clock: %lu\n",
++ __FUNCTION__, ts_dev->tsc_buf.timeout,
++ ((6 * TSC_NUM_SAMPLES * 14) +
++ (2 * (ts_dev->settle_pchg * 8 + 1)) +
++ (5 * (ts_dev->settle_meas * 8 + 1)) +
++ (2 * (ts_dev->settle_det * 8 + 1))) / ts_dev->clkrate + (1000 / HZ - 1),
++ (6 * TSC_NUM_SAMPLES * 14) +
++ (2 * (ts_dev->settle_pchg * 8 + 1)) +
++ (5 * (ts_dev->settle_meas * 8 + 1)) +
++ (2 * (ts_dev->settle_det * 8 + 1)), ts_dev->clkrate);
++ mxc_tsc_write(ts_dev, TCQ_ITEM_7_0, reg);
++
++ reg = mxc_tsc_read(ts_dev, TCQCR);
++ reg &= ~(CQCR_FIFOWATERMARK_MASK | CQCR_LAST_ITEM_ID_MASK);
++ reg |= (ts_dev->tsc_buf.chunk_size - 1) << CQCR_FIFOWATERMARK_SHIFT;
++ reg |= lastitemid << CQCR_LAST_ITEM_ID_SHIFT;
++ reg &= ~CQCR_PD_MSK;
++ mxc_tsc_write(ts_dev, TCQCR, reg);
++ DBG(0, "%s: TSC FIFO watermark set to %u\n", __FUNCTION__,
++ ((reg & CQCR_FIFOWATERMARK_MASK) >> CQCR_FIFOWATERMARK_SHIFT) + 1);
++
++ /* clear status bits */
++ reg = mxc_tsc_read(ts_dev, TCQSR);
++ mxc_tsc_write(ts_dev, TCQSR, reg);
++
++ mxc_tsc_clr_mask(ts_dev, TCQMR,
++ CQMR_PD_IRQ_MSK |
++ CQMR_EOQ_IRQ_MSK |
++ CQMR_FDRY_IRQ_MSK |
++ CQMR_FOR_IRQ_MSK |
++ CQMR_FER_IRQ_MSK);
++
++ /* Config idle for 4-wire */
++ mxc_tsc_write(ts_dev, TICR, TSC_4WIRE_TOUCH_DETECT);
++}
++
++static void mxc_tsc_adc_config(struct mxc_tsc *ts_dev)
++{
++ u32 reg;
++
++ ts_dev->adc_buf.chunk_size = ADC_NUM_SAMPLES % 32;
++ reg = ((ts_dev->adc_buf.chunk_size - 1) << CQCR_FIFOWATERMARK_SHIFT) |
++ (0 << CQCR_LAST_ITEM_ID_SHIFT) |
++ CQCR_QSM_FQS;
++ mxc_tsc_write(ts_dev, GCQCR, reg);
++ DBG(0, "%s: ADC FIFO watermark set to %u\n", __FUNCTION__,
++ ((reg & CQCR_FIFOWATERMARK_MASK) >> CQCR_FIFOWATERMARK_SHIFT) + 1);
++
++ reg = ((ADC_NUM_SAMPLES - 1) << CC_NOS_SHIFT) |
++ (ts_dev->settle_meas << CC_SETTLING_TIME_SHIFT) |
++ CC_YPLLSW_OFF | CC_XNURSW_OFF | CC_XPULSW |
++ CC_SEL_REFP_INT | CC_SEL_REFN_AGND;
++ mxc_tsc_write(ts_dev, GCC0, reg);
++
++ /* ADC conversion requires 14 clock cycles per sample
++ * plus the settling time programmed in the TICR registers.
++ * Add 1 extra jiffy to make sure the timeout is > 0
++ */
++ ts_dev->adc_buf.timeout = msecs_to_jiffies(
++ ((ADC_NUM_SAMPLES * 14) +
++ (ts_dev->settle_meas * 8 + 1)) /
++ ts_dev->clkrate) + 1;
++ DBG(0, "%s: ADC timeout set to %lu jiffies\n", __FUNCTION__,
++ ts_dev->adc_buf.timeout);
++}
++
++static void mxc_tsc_config(struct platform_device *pdev)
++{
++ struct mxc_tsc *ts_dev = platform_get_drvdata(pdev);
++ struct mxc_tsc_pdata *pdata = pdev->dev.platform_data;
++ unsigned int tgcr;
++ unsigned int pdbt = TGCR_PDBTIME128;
++ unsigned int pdben = 1;
++ unsigned int intref = 1;
++ unsigned int adc_clk = DEFAULT_ADC_CLOCK;
++ unsigned long ipg_clk;
++ unsigned int clkdiv;
++ unsigned int hsync_en = 0;
++ unsigned int hsync_pol = 0;
++
++ /* setup default settling times */
++ ts_dev->settle_det = SETTLE_DET;
++ ts_dev->settle_meas = SETTLE_MEAS;
++ ts_dev->settle_pchg = SETTLE_PCHG;
++
++ if (pdata) {
++ pdbt = pdata->pen_debounce_time - 1;
++ if (pdbt > 31) {
++ dev_dbg(&pdev->dev, "Pen debounce time %d out of range[0..32]; using max. value\n",
++ pdata->pen_debounce_time);
++ }
++ pdben = pdata->pen_debounce_time > 0;
++ intref = pdata->intref;
++ if (pdata->adc_clk > 0) {
++ adc_clk = pdata->adc_clk;
++ }
++ ts_dev->r_xplate = pdata->r_xplate;
++ hsync_en = pdata->hsyncen;
++ hsync_pol = pdata->hsyncpol;
++ if (pdata->settle_detect > 0 &&
++ pdata->settle_detect < 256)
++ ts_dev->settle_det = pdata->settle_detect;
++ if (pdata->settle_measure > 0 &&
++ pdata->settle_measure < 256)
++ ts_dev->settle_meas = pdata->settle_measure;
++ if (pdata->settle_precharge > 0 &&
++ pdata->settle_precharge < 256)
++ ts_dev->settle_pchg = pdata->settle_precharge;
++ DBG(0, "%s: pdbt=%d intref=%d r_xplate=%d hsync_en=%d hsync_pol=%d\n",
++ __FUNCTION__, pdbt + 1, intref, ts_dev->r_xplate,
++ hsync_en, hsync_pol);
++ } else {
++ dev_dbg(&pdev->dev, "No platform_data; using defaults\n");
++ }
++ if (settle_detect > 0 && settle_detect < 256)
++ ts_dev->settle_det = settle_detect;
++ if (settle_measure > 0 && settle_measure < 256)
++ ts_dev->settle_meas = settle_measure;
++ if (settle_precharge > 0 && settle_precharge < 256)
++ ts_dev->settle_pchg = settle_precharge;
++
++
++ if (ts_dev->r_xplate == 0) {
++ ts_dev->r_xplate = DEFAULT_RX_VALUE;
++ DBG(0, "%s: Assuming default Rx value of %u Ohms\n",
++ __FUNCTION__, ts_dev->r_xplate);
++ }
++ ipg_clk = clk_get_rate(ts_dev->clk);
++ dev_info(&pdev->dev, "Master clock is: %lu.%06luMHz requested ADC clock: %u.%06uMHz\n",
++ ipg_clk / 1000000, ipg_clk % 1000000,
++ adc_clk / 1000000, adc_clk % 1000000);
++ /*
++ * adc_clk = ipg_clk / (2 * clkdiv + 2)
++ * The exact formula for the clock divider would be:
++ * clkdiv = ipg_clk / (2 * adc_clk) - 1
++ * but we drop the '- 1' due to integer truncation
++ * and to make sure the actual clock is always less or equal
++ * to the designated clock.
++ */
++ clkdiv = ipg_clk / (2 * adc_clk + 1);
++ if (clkdiv > 31) {
++ clkdiv = 31;
++ dev_warn(&pdev->dev,
++ "cannot accomodate designated clock of %u.%06uMHz; using %lu.%06luMHz\n",
++ adc_clk / 1000000, adc_clk % 1000000,
++ ipg_clk / (2 * clkdiv + 2) / 1000000,
++ ipg_clk / (2 * clkdiv + 2) % 1000000);
++ }
++ /* calculate the actual ADC clock rate in kHz */
++ if (clkdiv < 4)
++ ts_dev->clkrate = ipg_clk / 10000;
++ else
++ ts_dev->clkrate = ipg_clk / (2 * clkdiv + 2) / 1000;
++ dev_dbg(&pdev->dev, "clkdiv=%u actual ADC clock: %lukHz\n",
++ clkdiv, ts_dev->clkrate);
++
++ tgcr = ((pdbt << TGCR_PDBTIME_SHIFT) & TGCR_PDBTIME_MASK) | /* pen debounce time */
++ (pdben * TGCR_PDB_EN) | /* pen debounce enable */
++ (intref * TGCR_INTREFEN) | /* pen debounce enable */
++ (hsync_en * TGCR_HSYNC_EN) | /* sync conversion with hsync */
++ (hsync_pol * TGCR_HSYNC_POL) | /* HSYNC polarity */
++ TGCR_POWER_SAVE | /* Switch TSC on */
++ TGCR_PD_EN | /* Enable Pen Detect */
++ ((clkdiv << TGCR_ADCCLKCFG_SHIFT) & TGCR_ADCCLKCFG_MASK);
++
++ /* reset TSC */
++ mxc_tsc_write(ts_dev, TGCR, TGCR_TSC_RST);
++ while (mxc_tsc_read(ts_dev, TGCR) & TGCR_TSC_RST) {
++ cpu_relax();
++ }
++ mxc_tsc_write(ts_dev, TGCR, tgcr);
++
++ tsc_clk_enable(ts_dev);
++ mxc_tsc_4wire_config(ts_dev);
++ mxc_tsc_adc_config(ts_dev);
++
++ mxc_tsc_start_measure(ts_dev);
++}
++
++static int __devinit mxc_tsc_probe(struct platform_device *pdev)
++{
++ int err;
++ struct mxc_tsc *ts_dev;
++ struct input_dev *input_dev;
++ struct resource *res;
++ int irq;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "No mmio resource defined\n");
++ return -ENODEV;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "No IRQ assigned\n");
++ return -ENODEV;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res),
++ "mxc tsc regs")) {
++ return -EBUSY;
++ }
++
++ /* Allocate memory for device */
++ ts_dev = kzalloc(sizeof(struct mxc_tsc), GFP_KERNEL);
++ if (!ts_dev) {
++ dev_err(&pdev->dev, "Failed to allocate memory\n");
++ err = -ENOMEM;
++ goto err_release_mem;
++ }
++
++ /* allocate conversion buffers separately to prevent
++ * cacheline alignment issues if using DMA */
++ ts_dev->tsc_data = kzalloc(sizeof(mxc_tsc_ts_fifo), GFP_KERNEL);
++ ts_dev->adc_data = kzalloc(sizeof(mxc_tsc_adc_fifo), GFP_KERNEL);
++ if (ts_dev->tsc_data == NULL || ts_dev->adc_data == NULL) {
++ err = -ENOMEM;
++ goto err_free_mem;
++ }
++ ts_dev->irq = irq;
++ INIT_WORK(&ts_dev->work, mxc_tsc_work);
++ mutex_init(&ts_dev->tsc_mutex);
++ mutex_init(&ts_dev->adc_mutex);
++ spin_lock_init(&ts_dev->irq_lock);
++ setup_timer(&ts_dev->timer, mxc_tsc_timer, (unsigned long)ts_dev);
++ init_waitqueue_head(&ts_dev->wq);
++ init_waitqueue_head(&ts_dev->tsc_buf.wq);
++ init_waitqueue_head(&ts_dev->adc_buf.wq);
++
++ ts_dev->tsc_buf.reg_base = TCQ_REG_BASE;
++ ts_dev->adc_buf.reg_base = GCQ_REG_BASE;
++ ts_dev->tsc_buf.data = ts_dev->tsc_data->fifo;
++ ts_dev->adc_buf.data = ts_dev->adc_data->fifo;
++
++ platform_set_drvdata(pdev, ts_dev);
++
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ dev_err(&pdev->dev, "Failed to allocate input device\n");
++ err = -ENOMEM;
++ goto err_free_mem;
++ }
++
++ ts_dev->reg_base = ioremap(res->start, resource_size(res));
++ if (!ts_dev->reg_base) {
++ dev_err(&pdev->dev, "Failed to map registers\n");
++ err = -ENOMEM;
++ goto err_free_dev;
++ }
++
++ err = request_irq(ts_dev->irq, mxc_tsc_interrupt, 0,
++ pdev->dev.driver->name, ts_dev);
++ if (err) {
++ dev_err(&pdev->dev, "Failed to install irq handler: %d\n", err);
++ goto err_unmap_regs;
++ }
++
++ ts_dev->clk = clk_get(&pdev->dev, "tsc_clk");
++ if (IS_ERR(ts_dev->clk)) {
++ dev_err(&pdev->dev, "Failed to get tsc_clk\n");
++ err = PTR_ERR(ts_dev->clk);
++ goto err_free_irq;
++ }
++
++ ts_dev->input = input_dev;
++
++ snprintf(ts_dev->phys, sizeof(ts_dev->phys),
++ "%s/input0", dev_name(&pdev->dev));
++
++ input_dev->name = "mxc touch screen controller";
++ input_dev->phys = ts_dev->phys;
++ input_dev->dev.parent = &pdev->dev;
++
++ __set_bit(EV_KEY, input_dev->evbit);
++ __set_bit(EV_ABS, input_dev->evbit);
++ __set_bit(BTN_TOUCH, input_dev->keybit);
++ __set_bit(ABS_X, input_dev->absbit);
++ __set_bit(ABS_Y, input_dev->absbit);
++ input_set_abs_params(input_dev, ABS_X, 0, 0xFFF, 0, 0);
++ input_set_abs_params(input_dev, ABS_Y, 0, 0xFFF, 0, 0);
++#ifdef REPORT_PRESSURE
++ __set_bit(ABS_PRESSURE, input_dev->absbit);
++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFFF, 0, 0);
++#endif
++ mxc_tsc_config(pdev);
++
++ /* All went ok, so register to the input system */
++ err = input_register_device(input_dev);
++ if (err)
++ goto err_fail;
++
++ err = sysfs_create_group(&pdev->dev.kobj, &mxc_tsc_attr_group);
++ if (err) {
++ dev_warn(&pdev->dev, "Failed to create sysfs attributes: %d\n",
++ err);
++ }
++ ts_dev->attrs = !err;
++
++ return 0;
++
++err_fail:
++ clk_disable(ts_dev->clk);
++ clk_put(ts_dev->clk);
++err_free_irq:
++ free_irq(ts_dev->irq, ts_dev);
++err_unmap_regs:
++ iounmap(ts_dev->reg_base);
++err_free_dev:
++ input_free_device(ts_dev->input);
++err_free_mem:
++ kfree(ts_dev->tsc_data);
++ kfree(ts_dev->adc_data);
++ kfree(ts_dev);
++err_release_mem:
++ release_mem_region(res->start, resource_size(res));
++ return err;
++}
++
++static int __devexit mxc_tsc_remove(struct platform_device *pdev)
++{
++ struct mxc_tsc *ts_dev = platform_get_drvdata(pdev);
++ struct resource *res;
++
++ if (ts_dev->attrs) {
++ DBG(0, "%s: Removing sysfs attributes\n", __FUNCTION__);
++ sysfs_remove_group(&pdev->dev.kobj, &mxc_tsc_attr_group);
++ }
++ del_timer_sync(&ts_dev->timer);
++ input_unregister_device(ts_dev->input);
++
++ clk_disable(ts_dev->clk);
++ clk_put(ts_dev->clk);
++
++ free_irq(ts_dev->irq, ts_dev);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ iounmap(ts_dev->reg_base);
++ release_mem_region(res->start, resource_size(res));
++
++ kfree(ts_dev->tsc_data);
++ kfree(ts_dev->adc_data);
++ kfree(ts_dev);
++ return 0;
++}
++
++#ifdef CONFIG_SUSPEND
++static int mxc_tsc_suspend(struct device *dev)
++{
++ struct mxc_tsc *ts_dev = dev_get_drvdata(dev);
++
++ if (ts_dev->clk_enabled) {
++ tsc_clk_disable(ts_dev);
++ ts_dev->clk_enabled = 1;
++ }
++ return 0;
++}
++
++static int mxc_tsc_resume(struct device *dev)
++{
++ struct mxc_tsc *ts_dev = dev_get_drvdata(dev);
++
++ if (ts_dev->clk_enabled) {
++ ts_dev->clk_enabled = 0;
++ tsc_clk_enable(ts_dev);
++ }
++ return 0;
++}
++
++static struct dev_pm_ops mxc_tsc_pm_ops = {
++ .suspend = mxc_tsc_suspend,
++ .resume = mxc_tsc_resume,
++};
++#endif
++
++static struct platform_driver mxc_tsc_driver = {
++ .driver = {
++ .name = "imx-tsc",
++// .pm = __dev_pm_ops_p(mxc_tsc_pm_ops),
++ },
++ .probe = mxc_tsc_probe,
++ .remove = __devexit_p(mxc_tsc_remove),
++};
++
++static int __init mxc_tsc_init(void)
++{
++ return platform_driver_register(&mxc_tsc_driver);
++}
++
++static void __exit mxc_tsc_exit(void)
++{
++ platform_driver_unregister(&mxc_tsc_driver);
++}
++
++module_init(mxc_tsc_init);
++module_exit(mxc_tsc_exit);
++
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("i.MX25 TouchScreen Driver");
++MODULE_AUTHOR("Lothar Wassmann <LW@KARO-electronics.de>");
++MODULE_ALIAS("platform:imx-tsc");
+diff -urN linux.35.old/drivers/input/touchscreen/mxc_tsc.h linux.35.new/drivers/input/touchscreen/mxc_tsc.h
+--- linux.35.old/drivers/input/touchscreen/mxc_tsc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.35.new/drivers/input/touchscreen/mxc_tsc.h 2010-12-03 09:51:55.428348260 +0100
+@@ -0,0 +1,327 @@
++/*
++ * Freescale i.MX25 Touch Screen Driver
++ *
++ * Copyright (c) 2009 Lothar Wassmann <LW@KARO-electronics.de>
++ *
++ * Based on code from Freescale BSP
++ *
++ * 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.
++ */
++
++/* TSC General Config Register */
++#define TGCR 0x000
++#define TGCR_IPG_CLK_EN (1 << 0)
++#define TGCR_TSC_RST (1 << 1)
++#define TGCR_FUNC_RST (1 << 2)
++#define TGCR_SLPC (1 << 4)
++#define TGCR_STLC (1 << 5)
++#define TGCR_HSYNC_EN (1 << 6)
++#define TGCR_HSYNC_POL (1 << 7)
++#define TGCR_POWERMODE_SHIFT 8
++#define TGCR_POWER_OFF (0x0 << TGCR_POWERMODE_SHIFT)
++#define TGCR_POWER_SAVE (0x1 << TGCR_POWERMODE_SHIFT)
++#define TGCR_POWER_ON (0x3 << TGCR_POWERMODE_SHIFT)
++#define TGCR_POWER_MASK (0x3 << TGCR_POWERMODE_SHIFT)
++#define TGCR_INTREFEN (1 << 10)
++#define TGCR_ADCCLKCFG_SHIFT 16
++#define TGCR_ADCCLKCFG_MASK (0x1f << TGCR_ADCCLKCFG_SHIFT)
++#define TGCR_PD_EN (1 << 23)
++#define TGCR_PDB_EN (1 << 24)
++#define TGCR_PDBTIME_SHIFT 25
++#define TGCR_PDBTIME128 (0x3f << TGCR_PDBTIME_SHIFT)
++#define TGCR_PDBTIME_MASK (0x7f << TGCR_PDBTIME_SHIFT)
++
++/* TSC General Status Register */
++#define TGSR 0x004
++#define TGSR_TCQ_INT (1 << 0)
++#define TGSR_GCQ_INT (1 << 1)
++#define TGSR_SLP_INT (1 << 2)
++#define TGSR_TCQ_DMA (1 << 16)
++#define TGSR_GCQ_DMA (1 << 17)
++
++/* TSC IDLE Config Register */
++#define TICR 0x008
++
++/* queue dependent register offsets wrt *_REG_BASE */
++#define CQFIFO 0x00
++#define CQCR 0x04
++#define CQSR 0x08
++#define CQMR 0x0c
++#define CQ_ITEM_7_0 0x20
++#define CQ_ITEM_15_8 0x24
++
++/* TouchScreen Convert Queue FIFO Register */
++#define TCQ_REG_BASE 0x400
++#define TCQFIFO (TCQ_REG_BASE + CQFIFO)
++/* TouchScreen Convert Queue Control Register */
++#define TCQCR (TCQ_REG_BASE + CQCR)
++#define CQCR_QSM_SHIFT 0
++#define CQCR_QSM_STOP (0x0 << CQCR_QSM_SHIFT)
++#define CQCR_QSM_PEN (0x1 << CQCR_QSM_SHIFT)
++#define CQCR_QSM_FQS (0x2 << CQCR_QSM_SHIFT)
++#define CQCR_QSM_FQS_PEN (0x3 << CQCR_QSM_SHIFT)
++#define CQCR_QSM_MASK (0x3 << CQCR_QSM_SHIFT)
++#define CQCR_FQS (1 << 2)
++#define CQCR_RPT (1 << 3)
++#define CQCR_LAST_ITEM_ID_SHIFT 4
++#define CQCR_LAST_ITEM_ID_MASK (0xf << CQCR_LAST_ITEM_ID_SHIFT)
++#define CQCR_FIFOWATERMARK_SHIFT 8
++#define CQCR_FIFOWATERMARK_MASK (0xf << CQCR_FIFOWATERMARK_SHIFT)
++#define CQCR_REPEATWAIT_SHIFT 12
++#define CQCR_REPEATWAIT_MASK (0xf << CQCR_REPEATWAIT_SHIFT)
++#define CQCR_QRST (1 << 16)
++#define CQCR_FRST (1 << 17)
++#define CQCR_PD_MSK (1 << 18)
++#define CQCR_PD_CFG (1 << 19)
++
++/* TouchScreen Convert Queue Status Register */
++#define TCQSR (TCQ_REG_BASE + CQSR)
++#define CQSR_PD (1 << 0)
++#define CQSR_EOQ (1 << 1)
++#define CQSR_FOR (1 << 4)
++#define CQSR_FUR (1 << 5)
++#define CQSR_FER (1 << 6)
++#define CQSR_EMPT (1 << 13)
++#define CQSR_FULL (1 << 14)
++#define CQSR_FDRY (1 << 15)
++
++/* TouchScreen Convert Queue Mask Register */
++#define TCQMR (TCQ_REG_BASE + CQMR)
++#define CQMR_PD_IRQ_MSK (1 << 0)
++#define CQMR_EOQ_IRQ_MSK (1 << 1)
++#define CQMR_FOR_IRQ_MSK (1 << 4)
++#define CQMR_FUR_IRQ_MSK (1 << 5)
++#define CQMR_FER_IRQ_MSK (1 << 6)
++#define CQMR_FDRY_IRQ_MSK (1 << 15)
++#define CQMR_PD_DMA_MSK (1 << 16)
++#define CQMR_EOQ_DMA_MSK (1 << 17)
++#define CQMR_FOR_DMA_MSK (1 << 20)
++#define CQMR_FUR_DMA_MSK (1 << 21)
++#define CQMR_FER_DMA_MSK (1 << 22)
++#define CQMR_FDRY_DMA_MSK (1 << 31)
++
++/* TouchScreen Convert Queue ITEM 7~0 */
++#define TCQ_ITEM_7_0 (TCQ_REG_BASE + CQ_ITEM_7_0)
++
++/* TouchScreen Convert Queue ITEM 15~8 */
++#define TCQ_ITEM_15_8 (TCQ_REG_BASE + CQ_ITEM_15_8)
++
++#define TCQ_ITEM_TCC0 0x0
++#d