summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-omap-2.6.31
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2009-09-04 15:32:30 +0200
committerKoen Kooi <koen@openembedded.org>2009-09-04 15:32:30 +0200
commit881f92e3409f67f70cffd5cfaca0de8248729145 (patch)
tree49f15add251b6ded5b2c5efc29f5603b76619e0e /recipes/linux/linux-omap-2.6.31
parenteff28b3b4ec8309ac1d51d98b8bfc9f5d48ed43f (diff)
linux-omap git: another checkpoint
* add V4l2 interfaces to DSS2 * add back MADC driver * add zippy support for beagleboard * add DSS2 for omap3evm
Diffstat (limited to 'recipes/linux/linux-omap-2.6.31')
-rw-r--r--recipes/linux/linux-omap-2.6.31/beagleboard/defconfig401
-rw-r--r--recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch387
-rw-r--r--recipes/linux/linux-omap-2.6.31/dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch152
-rw-r--r--recipes/linux/linux-omap-2.6.31/dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch40
-rw-r--r--recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch3248
-rw-r--r--recipes/linux/linux-omap-2.6.31/expansion-boards/tincantools-zippy.patch122
-rw-r--r--recipes/linux/linux-omap-2.6.31/madc/madc-driver.patch708
-rw-r--r--recipes/linux/linux-omap-2.6.31/madc/madc.patch56
8 files changed, 4945 insertions, 169 deletions
diff --git a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig
index c9f8e9962b..81f3cadce4 100644
--- a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig
+++ b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-omap1
-# Thu Aug 13 12:58:49 2009
+# Linux kernel version: 2.6.31-rc8-omap1
+# Fri Sep 4 15:16:17 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,14 +17,13 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_OPROFILE_ARMV7=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -70,6 +68,9 @@ CONFIG_USER_SCHED=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -91,20 +92,31 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+
+#
+# Performance Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
-# CONFIG_MARKERS is not set
+CONFIG_MARKERS=y
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -116,8 +128,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -144,12 +155,14 @@ CONFIG_FREEZER=y
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -158,24 +171,25 @@ CONFIG_FREEZER=y
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
CONFIG_ARCH_OMAP=y
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
#
# TI OMAP Implementations
@@ -184,26 +198,20 @@ CONFIG_ARCH_OMAP_OTG=y
# CONFIG_ARCH_OMAP1 is not set
# CONFIG_ARCH_OMAP2 is not set
CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
#
# OMAP Feature Selections
#
# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
-# CONFIG_OMAP_SMARTREFLEX is not set
CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_BOOT_TAG=y
-CONFIG_OMAP_BOOT_REASON=y
-# CONFIG_OMAP_COMPONENT_VERSION is not set
-# CONFIG_OMAP_GPIO_SWITCH is not set
# CONFIG_OMAP_MUX is not set
CONFIG_OMAP_MCBSP=y
# CONFIG_OMAP_MBOX_FWK is not set
-CONFIG_OMAP_IOMMU=m
# CONFIG_OMAP_MPU_TIMER is not set
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_32K_TIMER_HZ=128
-CONFIG_OMAP_TICK_GPTIMER=12
CONFIG_OMAP_DM_TIMER=y
# CONFIG_OMAP_LL_DEBUG_UART1 is not set
# CONFIG_OMAP_LL_DEBUG_UART2 is not set
@@ -214,13 +222,14 @@ CONFIG_ARCH_OMAP3430=y
#
# OMAP Board Type
#
-# CONFIG_MACH_NOKIA_RX51 is not set
-# CONFIG_MACH_OMAP_LDP is not set
-# CONFIG_MACH_OMAP_3430SDP is not set
-CONFIG_MACH_OMAP3EVM=y
CONFIG_MACH_OMAP3_BEAGLE=y
+# CONFIG_MACH_OMAP_LDP is not set
CONFIG_MACH_OVERO=y
+CONFIG_MACH_OMAP3EVM=y
# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
#
# Processor Type
@@ -248,7 +257,11 @@ CONFIG_ARM_THUMBEE=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_HAS_TLS_REG=y
-# CONFIG_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
#
# Bus support
@@ -272,9 +285,9 @@ CONFIG_PREEMPT=y
CONFIG_HZ=128
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -286,9 +299,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_LEDS=y
CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
#
# Boot options
@@ -330,7 +346,6 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_NEON=y
-# CONFIG_ARM_ERRATUM_451034 is not set
#
# Userspace binary formats
@@ -358,7 +373,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -390,7 +404,7 @@ CONFIG_INET_TUNNEL=m
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_LRO=m
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_TCP_CONG_ADVANCED=y
@@ -470,6 +484,8 @@ CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -478,6 +494,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -488,6 +505,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -510,6 +528,7 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_DEBUG=y
@@ -564,7 +583,6 @@ CONFIG_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_IDLETIMER=m
CONFIG_NF_NAT_SNMP_BASIC=m
CONFIG_NF_NAT_PROTO_DCCP=m
CONFIG_NF_NAT_PROTO_GRE=m
@@ -600,11 +618,11 @@ CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
# CONFIG_BRIDGE_NF_EBTABLES is not set
CONFIG_IP_DCCP=m
@@ -654,6 +672,8 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
CONFIG_WAN_ROUTER=m
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
CONFIG_NET_SCHED=y
#
@@ -699,6 +719,7 @@ CONFIG_NET_SCH_FIFO=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
@@ -708,6 +729,7 @@ CONFIG_CAN_BCM=m
# CAN Device Drivers
#
CONFIG_CAN_VCAN=m
+# CONFIG_CAN_DEV is not set
# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=m
@@ -759,7 +781,6 @@ CONFIG_KS959_DONGLE=m
CONFIG_USB_IRDA=m
CONFIG_SIGMATEL_FIR=m
CONFIG_MCS_FIR=m
-# CONFIG_OMAP_IR is not set
CONFIG_BT=y
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
@@ -782,18 +803,15 @@ CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIBCM203X=y
CONFIG_BT_HCIBPA10X=y
CONFIG_BT_HCIBFUSB=y
-# CONFIG_BT_HCIBRF6150 is not set
-# CONFIG_BT_HCIH4P is not set
# CONFIG_BT_HCIVHCI is not set
CONFIG_AF_RXRPC=m
# CONFIG_AF_RXRPC_DEBUG is not set
# CONFIG_RXKAD is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
+# CONFIG_CFG80211_DEBUGFS is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
@@ -803,6 +821,8 @@ CONFIG_LIB80211_CRYPT_CCMP=y
CONFIG_LIB80211_CRYPT_TKIP=y
# CONFIG_LIB80211_DEBUG is not set
CONFIG_MAC80211=y
+CONFIG_MAC80211_DEFAULT_PS=y
+CONFIG_MAC80211_DEFAULT_PS_VALUE=1
#
# Rate control algorithm selection
@@ -812,7 +832,6 @@ CONFIG_MAC80211_RC_PID=y
CONFIG_MAC80211_RC_DEFAULT_PID=y
# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
CONFIG_MAC80211_RC_DEFAULT="pid"
-# CONFIG_MAC80211_MESH is not set
CONFIG_MAC80211_LEDS=y
# CONFIG_MAC80211_DEBUGFS is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
@@ -948,10 +967,12 @@ CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
CONFIG_MISC_DEVICES=y
# CONFIG_ICS932S401 is not set
# CONFIG_OMAP_STI is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
#
@@ -960,6 +981,7 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -984,10 +1006,6 @@ CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -1005,8 +1023,10 @@ CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=m
# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
@@ -1015,7 +1035,7 @@ CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=m
@@ -1023,8 +1043,11 @@ CONFIG_BLK_DEV_DM=m
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
+# CONFIG_DM_LOG_USERSPACE is not set
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_QL is not set
+# CONFIG_DM_MULTIPATH_ST is not set
CONFIG_DM_DELAY=m
# CONFIG_DM_UEVENT is not set
CONFIG_NETDEVICES=y
@@ -1061,6 +1084,7 @@ CONFIG_MII=y
# CONFIG_DM9000 is not set
CONFIG_ENC28J60=y
# CONFIG_ENC28J60_WRITEVERIFY is not set
+# CONFIG_ETHOC is not set
CONFIG_SMC911X=y
CONFIG_SMSC911X=y
# CONFIG_DNET is not set
@@ -1072,6 +1096,8 @@ CONFIG_SMSC911X=y
# 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_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -1083,20 +1109,26 @@ CONFIG_WLAN_80211=y
CONFIG_LIBERTAS=y
CONFIG_LIBERTAS_USB=y
# CONFIG_LIBERTAS_SDIO is not set
+# CONFIG_LIBERTAS_SPI is not set
# CONFIG_LIBERTAS_DEBUG is not set
# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
CONFIG_USB_ZD1201=y
CONFIG_USB_NET_RNDIS_WLAN=y
CONFIG_RTL8187=y
+CONFIG_RTL8187_LEDS=y
# CONFIG_MAC80211_HWSIM is not set
CONFIG_P54_COMMON=y
CONFIG_P54_USB=y
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_P54_SPI is not set
+CONFIG_P54_LEDS=y
+# CONFIG_AR9170_USB is not set
CONFIG_HOSTAP=y
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_B43=y
CONFIG_B43_LEDS=y
+CONFIG_B43_HWRNG=y
# CONFIG_B43_DEBUG is not set
# CONFIG_B43LEGACY is not set
CONFIG_ZD1211RW=y
@@ -1104,12 +1136,16 @@ CONFIG_ZD1211RW=y
CONFIG_RT2X00=y
CONFIG_RT2500USB=y
CONFIG_RT73USB=y
+# CONFIG_RT2800USB is not set
CONFIG_RT2X00_LIB_USB=y
CONFIG_RT2X00_LIB=y
CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_RFKILL=y
CONFIG_RT2X00_LIB_LEDS=y
# CONFIG_RT2X00_DEBUG is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
#
# WiMAX Wireless Broadband devices
@@ -1127,6 +1163,7 @@ CONFIG_USB_RTL8150=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_CDCETHER=y
+# CONFIG_USB_NET_CDC_EEM is not set
CONFIG_USB_NET_DM9601=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_NET_GL620A=y
@@ -1142,6 +1179,7 @@ CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=y
+# CONFIG_USB_NET_INT51X1 is not set
# CONFIG_WAN is not set
CONFIG_ATM_DRIVERS=y
# CONFIG_ATM_DUMMY is not set
@@ -1171,7 +1209,7 @@ CONFIG_NET_POLL_CONTROLLER=y
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_POLLDEV=y
#
# Userland interfaces
@@ -1189,14 +1227,14 @@ CONFIG_INPUT_EVDEV=y
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_TWL4030 is not set
-# CONFIG_KEYBOARD_LM8323 is not set
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
@@ -1210,6 +1248,7 @@ CONFIG_MOUSE_PS2_TRACKPOINT=y
# 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 is not set
@@ -1222,6 +1261,7 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_CM109 is not set
CONFIG_INPUT_TWL4030_PWRBUTTON=y
CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
#
# Hardware I/O ports
@@ -1259,6 +1299,7 @@ CONFIG_SERIAL_8250_RSA=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
@@ -1266,6 +1307,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -1281,6 +1323,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_DESIGNWARE is not set
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
CONFIG_I2C_OMAP=y
@@ -1306,12 +1349,7 @@ CONFIG_I2C_OMAP=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-CONFIG_TWL4030_MADC=m
-CONFIG_TWL4030_POWEROFF=y
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_SENSORS_TSL2563 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -1330,8 +1368,6 @@ CONFIG_SPI_OMAP24XX=y
#
# SPI Protocol Masters
#
-# CONFIG_SPI_TSC210X is not set
-# CONFIG_SPI_TSC2301 is not set
CONFIG_SPI_SPIDEV=y
# CONFIG_SPI_TLE62X0 is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
@@ -1365,8 +1401,9 @@ CONFIG_POWER_SUPPLY=m
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_TWL4030_BCI_BATTERY is not set
+# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_AD7414 is not set
@@ -1387,6 +1424,7 @@ CONFIG_HWMON=y
# 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
@@ -1402,18 +1440,23 @@ CONFIG_HWMON=y
# 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_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -1423,6 +1466,7 @@ CONFIG_HWMON=y
# 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_TSC210X is not set
CONFIG_SENSORS_OMAP34XX=y
# CONFIG_HWMON_DEBUG_CHIP is not set
@@ -1436,6 +1480,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_OMAP_WATCHDOG=y
+# CONFIG_TWL4030_WATCHDOG is not set
#
# USB-based Watchdog Cards
@@ -1460,7 +1505,7 @@ CONFIG_SSB=y
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TPS65010 is not set
CONFIG_TWL4030_CORE=y
-# CONFIG_TWL4030_POWER is not set
+CONFIG_TWL4030_MADC=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
@@ -1469,10 +1514,9 @@ CONFIG_TWL4030_CORE=y
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_MEDIA_SUPPORT=y
#
# Multimedia core support
@@ -1489,7 +1533,7 @@ CONFIG_VIDEO_MEDIA=m
#
CONFIG_MEDIA_ATTACH=y
CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA827X=m
@@ -1504,6 +1548,8 @@ CONFIG_MEDIA_TUNER_QT1010=m
CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC5000=m
CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_MEDIA_TUNER_MXL5007T=m
+CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_VIDEO_V4L2=m
CONFIG_VIDEO_V4L1=m
CONFIG_VIDEOBUF_GEN=m
@@ -1521,6 +1567,7 @@ CONFIG_VIDEO_IR_I2C=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_MT9V011=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TVP5150=m
CONFIG_VIDEO_CX25840=m
@@ -1531,8 +1578,10 @@ CONFIG_VIDEO_VIVI=m
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_VIDEO_AU0828 is not set
-CONFIG_VIDEO_OMAP3=m
-CONFIG_VIDEO_OMAP34XX_ISP_RESIZER=m
+CONFIG_VIDEO_OMAP3=y
+CONFIG_VIDEO_OMAP_VIDEOOUT=m
+# CONFIG_NTSC_M is not set
+CONFIG_PAL_BDGHI=y
# CONFIG_SOC_CAMERA is not set
CONFIG_V4L_USB_DRIVERS=y
CONFIG_USB_VIDEO_CLASS=m
@@ -1544,10 +1593,12 @@ CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_MARS=m
+# CONFIG_USB_GSPCA_MR97310A is not set
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7311=m
+# CONFIG_USB_GSPCA_SN9C20X is not set
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA500=m
@@ -1556,6 +1607,8 @@ CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
CONFIG_USB_GSPCA_SPCA508=m
CONFIG_USB_GSPCA_SPCA561=m
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
CONFIG_USB_GSPCA_STK014=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
@@ -1566,9 +1619,13 @@ CONFIG_VIDEO_PVRUSB2=m
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_HDPVR=m
CONFIG_VIDEO_EM28XX=m
CONFIG_VIDEO_EM28XX_ALSA=m
CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_VIDEO_CX231XX=m
+# CONFIG_VIDEO_CX231XX_ALSA is not set
+CONFIG_VIDEO_CX231XX_DVB=m
CONFIG_VIDEO_USBVISION=m
CONFIG_VIDEO_USBVIDEO=m
CONFIG_USB_VICAM=m
@@ -1585,6 +1642,7 @@ CONFIG_USB_STV680=m
CONFIG_USB_ZC0301=m
CONFIG_USB_PWC=m
# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
CONFIG_USB_ZR364XX=m
CONFIG_USB_STKWEBCAM=m
CONFIG_USB_S2255=m
@@ -1627,6 +1685,7 @@ CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_ANYSEE=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_AF9015=m
+# CONFIG_DVB_USB_CE6230 is not set
CONFIG_DVB_SIANO_SMS1XXX=m
CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y
@@ -1640,48 +1699,20 @@ CONFIG_DVB_B2C2_FLEXCOP_USB=m
#
# Supported DVB Frontends
#
-
-#
-# Customise DVB Frontends
-#
# CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# Multistandard (satellite) frontends
-#
-CONFIG_DVB_STB0899=m
-CONFIG_DVB_STB6100=m
-
-#
-# DVB-S (satellite) frontends
-#
-CONFIG_DVB_CX24110=m
CONFIG_DVB_CX24123=m
CONFIG_DVB_MT312=m
CONFIG_DVB_S5H1420=m
CONFIG_DVB_STV0288=m
CONFIG_DVB_STB6000=m
CONFIG_DVB_STV0299=m
-CONFIG_DVB_TDA8083=m
CONFIG_DVB_TDA10086=m
-CONFIG_DVB_TDA8261=m
-CONFIG_DVB_VES1X93=m
CONFIG_DVB_TUNER_ITD1000=m
CONFIG_DVB_TUNER_CX24113=m
CONFIG_DVB_TDA826X=m
-CONFIG_DVB_TUA6100=m
CONFIG_DVB_CX24116=m
CONFIG_DVB_SI21XX=m
-
-#
-# DVB-T (terrestrial) frontends
-#
-CONFIG_DVB_SP8870=m
-CONFIG_DVB_SP887X=m
-CONFIG_DVB_CX22700=m
CONFIG_DVB_CX22702=m
-CONFIG_DVB_DRX397XD=m
-CONFIG_DVB_L64781=m
CONFIG_DVB_TDA1004X=m
CONFIG_DVB_NXT6000=m
CONFIG_DVB_MT352=m
@@ -1691,52 +1722,21 @@ CONFIG_DVB_DIB3000MC=m
CONFIG_DVB_DIB7000M=m
CONFIG_DVB_DIB7000P=m
CONFIG_DVB_TDA10048=m
-
-#
-# DVB-C (cable) frontends
-#
-CONFIG_DVB_VES1820=m
+CONFIG_DVB_AF9013=m
CONFIG_DVB_TDA10021=m
CONFIG_DVB_TDA10023=m
CONFIG_DVB_STV0297=m
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
CONFIG_DVB_NXT200X=m
-CONFIG_DVB_OR51211=m
-CONFIG_DVB_OR51132=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LGDT330X=m
-CONFIG_DVB_LGDT3304=m
+CONFIG_DVB_LGDT3305=m
CONFIG_DVB_S5H1409=m
-CONFIG_DVB_AU8522=m
CONFIG_DVB_S5H1411=m
-
-#
-# ISDB-T (terrestrial) frontends
-#
-CONFIG_DVB_S921=m
-
-#
-# Digital terrestrial only tuners/PLL
-#
CONFIG_DVB_PLL=m
CONFIG_DVB_TUNER_DIB0070=m
-
-#
-# SEC control devices for DVB-S
-#
CONFIG_DVB_LNBP21=m
-# CONFIG_DVB_ISL6405 is not set
CONFIG_DVB_ISL6421=m
CONFIG_DVB_LGS8GL5=m
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-CONFIG_DVB_AF9013=m
# CONFIG_DAB is not set
#
@@ -1770,9 +1770,12 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
CONFIG_OMAP2_DSS=y
-CONFIG_OMAP2_DSS_VRAM_SIZE=14
+CONFIG_OMAP2_VRAM_SIZE=14
CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
# CONFIG_OMAP2_DSS_RFBI is not set
CONFIG_OMAP2_DSS_VENC=y
@@ -1781,19 +1784,18 @@ CONFIG_OMAP2_DSS_DSI=y
CONFIG_OMAP2_DSS_USE_DSI_PLL=y
# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
#
# OMAP2/3 Display Device Drivers
#
CONFIG_PANEL_GENERIC=y
CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=m
-# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
-# CONFIG_PANEL_N800 is not set
-# CONFIG_CTRL_BLIZZARD is not set
-CONFIG_FB_OMAP2=y
-CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
-# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
-CONFIG_FB_OMAP2_NUM_FBS=3
+CONFIG_PANEL_SHARP_LS037V7DW01=m
+# CONFIG_PANEL_TAAL is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1827,6 +1829,7 @@ CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_HWDEP=y
CONFIG_SND_RAWMIDI=y
+CONFIG_SND_JACK=y
CONFIG_SND_SEQUENCER=m
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
@@ -1841,6 +1844,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
+CONFIG_SND_RAWMIDI_SEQ=m
+# 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=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
@@ -1857,6 +1865,7 @@ CONFIG_SND_SOC=y
CONFIG_SND_OMAP_SOC=y
CONFIG_SND_OMAP_SOC_MCBSP=y
# CONFIG_SND_OMAP_SOC_OVERO is not set
+# CONFIG_SND_OMAP_SOC_OMAP3EVM is not set
CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_ALL_CODECS is not set
@@ -1877,15 +1886,17 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1898,10 +1909,12 @@ CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
-CONFIG_GREENASIA_FF=y
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
CONFIG_HID_TOPSEED=y
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1929,12 +1942,11 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_EHCI_HCD=y
-CONFIG_OMAP_EHCI_PHY_MODE=y
-# CONFIG_OMAP_EHCI_TLL_MODE is not set
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_OXU210HP_HCD=y
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_U132_HCD is not set
# CONFIG_USB_SL811_HCD is not set
@@ -1965,11 +1977,11 @@ CONFIG_USB_WDM=m
CONFIG_USB_TMC=m
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -2004,7 +2016,7 @@ CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_CP2101=m
+# CONFIG_USB_SERIAL_CP210X is not set
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -2040,12 +2052,14 @@ CONFIG_USB_SERIAL_MOTOROLA=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
+# CONFIG_USB_SERIAL_QUALCOMM is not set
CONFIG_USB_SERIAL_SPCP8X5=m
CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
# CONFIG_USB_SERIAL_SAFE_PADDED is not set
CONFIG_USB_SERIAL_SIEMENS_MPI=m
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+# CONFIG_USB_SERIAL_SYMBOL is not set
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
@@ -2068,10 +2082,6 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
-CONFIG_USB_PHIDGET=m
-CONFIG_USB_PHIDGETKIT=m
-CONFIG_USB_PHIDGETMOTORCONTROL=m
-CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
# CONFIG_USB_APPLEDISPLAY is not set
@@ -2101,18 +2111,21 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
# CONFIG_USB_GADGET_M66592 is not set
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_FSL_QE is not set
# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
CONFIG_USB_GADGET_DUALSPEED=y
CONFIG_USB_ZERO=m
CONFIG_USB_ZERO_HNPTEST=y
+# CONFIG_USB_AUDIO is not set
CONFIG_USB_ETH=m
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_GADGETFS=m
@@ -2130,7 +2143,7 @@ CONFIG_USB_OTG_UTILS=y
CONFIG_USB_GPIO_VBUS=y
# CONFIG_ISP1301_OMAP is not set
CONFIG_TWL4030_USB=y
-# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_NOP_USB_XCEIV=y
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_UNSAFE_RESUME=y
@@ -2162,8 +2175,11 @@ CONFIG_LEDS_OMAP=y
# CONFIG_LEDS_OMAP_PWM is not set
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
-# CONFIG_LEDS_LP5521 is not set
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
@@ -2172,7 +2188,12 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+# CONFIG_LEDS_TRIGGER_GPIO is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -2205,6 +2226,7 @@ CONFIG_RTC_DRV_TWL4030=m
# 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
@@ -2236,12 +2258,16 @@ CONFIG_RTC_DRV_TWL4030=m
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
CONFIG_UIO=m
CONFIG_UIO_PDRV=m
CONFIG_UIO_PDRV_GENIRQ=m
@@ -2252,8 +2278,8 @@ CONFIG_STAGING=y
# CONFIG_MEILHAUS is not set
# CONFIG_USB_IP_COMMON is not set
CONFIG_W35UND=m
-CONFIG_PRISM2_USB=m
-# CONFIG_ECHO is not set
+# CONFIG_PRISM2_USB is not set
+CONFIG_ECHO=m
CONFIG_USB_ATMEL=m
# CONFIG_AGNX is not set
CONFIG_OTUS=m
@@ -2272,8 +2298,17 @@ CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set
# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set
+CONFIG_ANDROID_TIMED_OUTPUT=y
CONFIG_ANDROID_TIMED_GPIO=m
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set
+# CONFIG_DST is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_STLC45XX is not set
+# CONFIG_PLAN9AUTH is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_USB_SERIAL_QUATECH2 is not set
+# CONFIG_USB_CPC is not set
+# CONFIG_FB_UDL is not set
#
# CBUS support
@@ -2287,6 +2322,7 @@ 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=m
# CONFIG_EXT4DEV_COMPAT is not set
@@ -2310,14 +2346,13 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
CONFIG_XFS_FS=m
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=m
+# CONFIG_GFS2_FS_LOCKING_DLM is not set
CONFIG_OCFS2_FS=m
CONFIG_OCFS2_FS_O2CB=m
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
@@ -2327,6 +2362,8 @@ CONFIG_OCFS2_DEBUG_MASKLOG=y
# CONFIG_OCFS2_FS_POSIX_ACL is not set
CONFIG_BTRFS_FS=m
# CONFIG_BTRFS_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -2340,6 +2377,12 @@ CONFIG_QUOTACTL=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
@@ -2417,15 +2460,21 @@ CONFIG_OMFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_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=y
+# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
@@ -2439,7 +2488,6 @@ CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -2451,8 +2499,8 @@ CONFIG_CIFS_STATS2=y
# CONFIG_CIFS_UPCALL is not set
# CONFIG_CIFS_XATTR is not set
# CONFIG_CIFS_DEBUG2 is not set
-CONFIG_CIFS_EXPERIMENTAL=y
# CONFIG_CIFS_DFS_UPCALL is not set
+CONFIG_CIFS_EXPERIMENTAL=y
CONFIG_NCP_FS=m
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -2548,11 +2596,15 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -2573,7 +2625,6 @@ CONFIG_STACKTRACE=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
-CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -2581,27 +2632,34 @@ CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_ERRORS is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -2635,10 +2693,12 @@ CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=m
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_TEST=m
@@ -2708,6 +2768,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
#
@@ -2715,6 +2776,7 @@ CONFIG_CRYPTO_LZO=y
#
CONFIG_CRYPTO_ANSI_CPRNG=m
CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
#
# Library routines
@@ -2732,11 +2794,12 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch b/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch
new file mode 100644
index 0000000000..9a4ea8b9ad
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch
@@ -0,0 +1,387 @@
+From 798f9b1bc478c7ded724fc190c65e413c2401314 Mon Sep 17 00:00:00 2001
+From: Vaibhav Hiremath <hvaibhav@ti.com>
+Date: Tue, 11 Aug 2009 15:52:04 +0530
+Subject: [PATCH 1/5] OMAP3: Enable DSS2 for OMAP3EVM board
+
+Tested -
+ - Validated all three outut interfaces (LCD, DVI and TV)
+TODO:
+ - Support for Backlight control range (0 - 100)
+ - Enable selection for both S-Video and Composite TV out
+ - DVI color (VPLL2_DEV_GRP should be equal to 0x7)
+
+Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
+---
+ arch/arm/configs/omap3_evm_defconfig | 51 +++++++-
+ arch/arm/mach-omap2/board-omap3evm.c | 234 ++++++++++++++++++++++++++++++++--
+ 2 files changed, 273 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig
+index d5ff477..ba395a2 100644
+--- a/arch/arm/configs/omap3_evm_defconfig
++++ b/arch/arm/configs/omap3_evm_defconfig
+@@ -903,7 +903,56 @@ CONFIG_DAB=y
+ #
+ # CONFIG_VGASTATE is not set
+ CONFIG_VIDEO_OUTPUT_CONTROL=m
+-# CONFIG_FB is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
++CONFIG_OMAP2_VRAM=y
++CONFIG_OMAP2_VRFB=y
++CONFIG_OMAP2_DSS=y
++CONFIG_OMAP2_VRAM_SIZE=4
++# CONFIG_OMAP2_DSS_DEBUG_SUPPORT is not set
++# CONFIG_OMAP2_DSS_RFBI is not set
++CONFIG_OMAP2_DSS_VENC=y
++# CONFIG_OMAP2_DSS_SDI is not set
++# CONFIG_OMAP2_DSS_DSI is not set
++# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
++CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
++CONFIG_FB_OMAP2=y
++# CONFIG_FB_OMAP2_DEBUG_SUPPORT is not set
++# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
++CONFIG_FB_OMAP2_NUM_FBS=3
++
++#
++# OMAP2/3 Display Device Drivers
++#
++CONFIG_PANEL_GENERIC=y
++# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set
++CONFIG_PANEL_SHARP_LS037V7DW01=y
+ # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+ #
+diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
+index c0cb29d..0bc26b3 100644
+--- a/arch/arm/mach-omap2/board-omap3evm.c
++++ b/arch/arm/mach-omap2/board-omap3evm.c
+@@ -22,6 +22,7 @@
+ #include <linux/input.h>
+ #include <linux/leds.h>
+
++#include <linux/regulator/machine.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/ads7846.h>
+ #include <linux/i2c/twl4030.h>
+@@ -38,6 +39,7 @@
+ #include <mach/common.h>
+ #include <mach/mcspi.h>
+ #include <mach/keypad.h>
++#include <mach/display.h>
+
+ #include "sdram-micron-mt46h32m32lf-6.h"
+ #include "mmc-twl4030.h"
+@@ -91,6 +93,174 @@ static inline void __init omap3evm_init_smc911x(void)
+
+ gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
+ }
++/*
++ * OMAP3EVM LCD Panel control signals
++ */
++#define OMAP3EVM_LCD_PANEL_LR 2
++#define OMAP3EVM_LCD_PANEL_UD 3
++#define OMAP3EVM_LCD_PANEL_INI 152
++#define OMAP3EVM_LCD_PANEL_ENVDD 153
++#define OMAP3EVM_LCD_PANEL_QVGA 154
++#define OMAP3EVM_LCD_PANEL_RESB 155
++#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210
++#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
++
++static int lcd_enabled;
++static int dvi_enabled;
++
++static void __init omap3_evm_display_init(void)
++{
++ int r;
++ r = gpio_request(OMAP3EVM_LCD_PANEL_RESB, "lcd_panel_resb");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_resb\n");
++ return;
++ }
++ gpio_direction_output(OMAP3EVM_LCD_PANEL_RESB, 1);
++
++ r = gpio_request(OMAP3EVM_LCD_PANEL_INI, "lcd_panel_ini");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_ini\n");
++ goto err_1;
++ }
++ gpio_direction_output(OMAP3EVM_LCD_PANEL_INI, 1);
++
++ r = gpio_request(OMAP3EVM_LCD_PANEL_QVGA, "lcd_panel_qvga");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_qvga\n");
++ goto err_2;
++ }
++ gpio_direction_output(OMAP3EVM_LCD_PANEL_QVGA, 0);
++
++ r = gpio_request(OMAP3EVM_LCD_PANEL_LR, "lcd_panel_lr");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_lr\n");
++ goto err_3;
++ }
++ gpio_direction_output(OMAP3EVM_LCD_PANEL_LR, 1);
++
++ r = gpio_request(OMAP3EVM_LCD_PANEL_UD, "lcd_panel_ud");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_ud\n");
++ goto err_4;
++ }
++ gpio_direction_output(OMAP3EVM_LCD_PANEL_UD, 1);
++
++ r = gpio_request(OMAP3EVM_LCD_PANEL_ENVDD, "lcd_panel_envdd");
++ if (r) {
++ printk(KERN_ERR "failed to get lcd_panel_envdd\n");
++ goto err_5;
++ }
++
++ return;
++
++err_5:
++ gpio_free(OMAP3EVM_LCD_PANEL_UD);
++err_4:
++ gpio_free(OMAP3EVM_LCD_PANEL_LR);
++err_3:
++ gpio_free(OMAP3EVM_LCD_PANEL_QVGA);
++err_2:
++ gpio_free(OMAP3EVM_LCD_PANEL_INI);
++err_1:
++ gpio_free(OMAP3EVM_LCD_PANEL_RESB);
++
++}
++
++static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
++{
++ if (dvi_enabled) {
++ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
++ return -EINVAL;
++ }
++
++ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
++ gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
++ lcd_enabled = 1;
++ return 0;
++}
++
++static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
++{
++ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
++ gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
++ lcd_enabled = 0;
++}
++
++static struct omap_dss_device omap3_evm_lcd_device = {
++ .type = OMAP_DISPLAY_TYPE_DPI,
++ .name = "lcd",
++ .driver_name = "sharp_ls_panel",
++ .phy.dpi.data_lines = 18,
++ .platform_enable = omap3_evm_enable_lcd,
++ .platform_disable = omap3_evm_disable_lcd,
++};
++
++static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
++{
++ return 0;
++}
++
++static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
++{
++}
++
++static struct omap_dss_device omap3_evm_tv_device = {
++ .type = OMAP_DISPLAY_TYPE_VENC,
++ .name = "tv",
++ .driver_name = "venc",
++ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
++ .platform_enable = omap3_evm_enable_tv,
++ .platform_disable = omap3_evm_disable_tv,
++};
++
++static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev)
++{
++ if (lcd_enabled) {
++ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
++ return -EINVAL;
++ }
++
++ gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 1);
++ dvi_enabled = 1;
++
++ return 0;
++}
++
++static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
++{
++ gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 0);
++ dvi_enabled = 0;
++}
++
++static struct omap_dss_device omap3_evm_dvi_device = {
++ .type = OMAP_DISPLAY_TYPE_DPI,
++ .name = "dvi",
++ .driver_name = "generic_panel",
++ .phy.dpi.data_lines = 24,
++ .platform_enable = omap3_evm_enable_dvi,
++ .platform_disable = omap3_evm_disable_dvi,
++};
++
++static struct omap_dss_device *omap3_evm_dss_devices[] = {
++ &omap3_evm_lcd_device,
++ &omap3_evm_tv_device,
++ &omap3_evm_dvi_device,
++};
++
++static struct omap_dss_board_info omap3_evm_dss_data = {
++ .num_devices = ARRAY_SIZE(omap3_evm_dss_devices),
++ .devices = omap3_evm_dss_devices,
++ .default_device = &omap3_evm_lcd_device,
++};
++
++static struct platform_device omap3_evm_dss_device = {
++ .name = "omapdss",
++ .id = -1,
++ .dev = {
++ .platform_data = &omap3_evm_dss_data,
++ },
++};
+
+ static struct omap_uart_platform_data omap3_evm_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+@@ -143,6 +313,14 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
++ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
++ gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL");
++ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
++
++ /* gpio + 7 == DVI Enable */
++ gpio_request(gpio + 7, "EN_DVI");
++ gpio_direction_output(gpio + 7, 0);
++
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+@@ -194,6 +372,47 @@ static struct twl4030_madc_platform_data omap3evm_madc_data = {
+ .irq_line = 1,
+ };
+
++static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = {
++ .supply = "vdda_dac",
++ .dev = &omap3_evm_dss_device.dev,
++};
++
++/* VDAC for DSS driving S-Video */
++static struct regulator_init_data omap3_evm_vdac = {
++ .constraints = {
++ .min_uV = 1800000,
++ .max_uV = 1800000,
++ .apply_uV = true,
++ .valid_modes_mask = REGULATOR_MODE_NORMAL
++ | REGULATOR_MODE_STANDBY,
++ .valid_ops_mask = REGULATOR_CHANGE_MODE
++ | REGULATOR_CHANGE_STATUS,
++ },
++ .num_consumer_supplies = 1,
++ .consumer_supplies = &omap3_evm_vdda_dac_supply,
++};
++
++/* VPLL2 for digital video outputs */
++static struct regulator_consumer_supply omap3_evm_vpll2_supply = {
++ .supply = "vdvi",
++ .dev = &omap3_evm_lcd_device.dev,
++};
++
++static struct regulator_init_data omap3_evm_vpll2 = {
++ .constraints = {
++ .name = "VDVI",
++ .min_uV = 1800000,
++ .max_uV = 1800000,
++ .apply_uV = true,
++ .valid_modes_mask = REGULATOR_MODE_NORMAL
++ | REGULATOR_MODE_STANDBY,
++ .valid_ops_mask = REGULATOR_CHANGE_MODE
++ | REGULATOR_CHANGE_STATUS,
++ },
++ .num_consumer_supplies = 1,
++ .consumer_supplies = &omap3_evm_vpll2_supply,
++};
++
+ static struct twl4030_platform_data omap3evm_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+@@ -203,6 +422,8 @@ static struct twl4030_platform_data omap3evm_twldata = {
+ .madc = &omap3evm_madc_data,
+ .usb = &omap3evm_usb_data,
+ .gpio = &omap3evm_gpio_data,
++ .vdac = &omap3_evm_vdac,
++ .vpll2 = &omap3_evm_vpll2,
+ };
+
+ static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
+@@ -223,15 +444,6 @@ static int __init omap3_evm_i2c_init(void)
+ return 0;
+ }
+
+-static struct platform_device omap3_evm_lcd_device = {
+- .name = "omap3evm_lcd",
+- .id = -1,
+-};
+-
+-static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
+- .ctrl_name = "internal",
+-};
+-
+ static void ads7846_dev_init(void)
+ {
+ if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
+@@ -287,11 +499,10 @@ static void __init omap3_evm_init_irq(void)
+ }
+
+ static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
+- { OMAP_TAG_LCD, &omap3_evm_lcd_config },
+ };
+
+ static struct platform_device *omap3_evm_devices[] __initdata = {
+- &omap3_evm_lcd_device,
++ &omap3_evm_dss_device,
+ &omap3evm_smc911x_device,
+ };
+
+@@ -314,6 +525,7 @@ static void __init omap3_evm_init(void)
+ usb_musb_init();
+ usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61);
+ ads7846_dev_init();
++ omap3_evm_display_init();
+ }
+
+ static void __init omap3_evm_map_io(void)
+--
+1.6.2.4
+
diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch b/recipes/linux/linux-omap-2.6.31/dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch
new file mode 100644
index 0000000000..f05929088f
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch
@@ -0,0 +1,152 @@
+From bcb3cd3f6dd8d80a4f7cc524b769d711addfc48d Mon Sep 17 00:00:00 2001
+From: Vaibhav Hiremath <hvaibhav@ti.com>
+Date: Wed, 22 Jul 2009 23:49:29 +0530
+Subject: [PATCH 2/5] V4L2: Added New V4L2 CIDs for omap devices V4L2 IOCTL
+
+Changes -
+ - Renamed V4L2_CID_ROTATION to V4L2_CID_ROTATE
+ - Implementationadded for VIDIOC_S/G_COLOR_SPACE_CONV
+
+Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
+---
+ drivers/media/video/v4l2-ioctl.c | 19 +++++++++++++++++++
+ include/linux/videodev2.h | 21 ++++++++++++++++++---
+ include/media/v4l2-ioctl.h | 4 ++++
+ 3 files changed, 41 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
+index f2afc4e..74d2ed9 100644
+--- a/drivers/media/video/v4l2-ioctl.c
++++ b/drivers/media/video/v4l2-ioctl.c
+@@ -278,6 +278,8 @@ static const char *v4l2_ioctls[] = {
+ [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
+ [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
+ #endif
++ [_IOC_NR(VIDIOC_S_COLOR_SPACE_CONV)] = "VIDIOC_S_COLOR_SPACE_CONV",
++ [_IOC_NR(VIDIOC_G_COLOR_SPACE_CONV)] = "VIDIOC_G_COLOR_SPACE_CONV",
+ };
+ #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+@@ -1784,6 +1786,23 @@ static long __video_do_ioctl(struct file *file,
+ break;
+ }
+
++ /*---------------Color space conversion------------------------------*/
++ case VIDIOC_S_COLOR_SPACE_CONV:
++ {
++ struct v4l2_color_space_conversion *p = arg;
++ if (!ops->vidioc_s_color_space_conv)
++ break;
++ ret = ops->vidioc_s_color_space_conv(file, fh, p);
++ break;
++ }
++ case VIDIOC_G_COLOR_SPACE_CONV:
++ {
++ struct v4l2_color_space_conversion *p = arg;
++ if (!ops->vidioc_g_color_space_conv)
++ break;
++ ret = ops->vidioc_g_color_space_conv(file, fh, p);
++ break;
++ }
+ default:
+ {
+ if (!ops->vidioc_default)
+diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
+index 74f1687..78e8158 100644
+--- a/include/linux/videodev2.h
++++ b/include/linux/videodev2.h
+@@ -554,6 +554,7 @@ struct v4l2_framebuffer {
+ #define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
+ #define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
+ #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
++#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
+ /* Flags for the 'flags' field. */
+ #define V4L2_FBUF_FLAG_PRIMARY 0x0001
+ #define V4L2_FBUF_FLAG_OVERLAY 0x0002
+@@ -561,6 +562,7 @@ struct v4l2_framebuffer {
+ #define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
+ #define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
+ #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
++#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
+
+ struct v4l2_clip {
+ struct v4l2_rect c;
+@@ -902,6 +904,8 @@ enum v4l2_colorfx {
+
+ /* last CID + 1 */
+ #define V4L2_CID_LASTP1 (V4L2_CID_BASE+33)
++#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
++#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
+
+ /* MPEG-class control IDs defined by V4L2 */
+ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+@@ -1213,6 +1217,18 @@ struct v4l2_hw_freq_seek {
+ };
+
+ /*
++ * Color conversion
++ * User needs to pass pointer to color conversion matrix
++ * defined by hardware
++ */
++struct v4l2_color_space_conversion {
++ __s32 coefficients[3][3];
++ __s32 const_factor;
++ __s32 input_offs[3];
++ __s32 output_offs[3];
++};
++
++/*
+ * A U D I O
+ */
+ struct v4l2_audio {
+@@ -1265,7 +1281,6 @@ struct v4l2_enc_idx {
+ struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+ };
+
+-
+ #define V4L2_ENC_CMD_START (0)
+ #define V4L2_ENC_CMD_STOP (1)
+ #define V4L2_ENC_CMD_PAUSE (2)
+@@ -1286,7 +1301,6 @@ struct v4l2_encoder_cmd {
+
+ #endif
+
+-
+ /*
+ * D A T A S E R V I C E S ( V B I )
+ *
+@@ -1423,7 +1437,6 @@ struct v4l2_format {
+ } fmt;
+ };
+
+-
+ /* Stream type-dependent parameters
+ */
+ struct v4l2_streamparm {
+@@ -1551,6 +1564,8 @@ struct v4l2_dbg_chip_ident {
+ #endif
+
+ #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
++#define VIDIOC_S_COLOR_SPACE_CONV _IOW('V', 83, struct v4l2_color_space_conversion)
++#define VIDIOC_G_COLOR_SPACE_CONV _IOR('V', 84, struct v4l2_color_space_conversion)
+ /* Reminder: when adding new ioctls please add support for them to
+ drivers/media/video/v4l2-compat-ioctl32.c as well! */
+
+diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
+index 7a4529d..6f46d09 100644
+--- a/include/media/v4l2-ioctl.h
++++ b/include/media/v4l2-ioctl.h
+@@ -242,6 +242,10 @@ struct v4l2_ioctl_ops {
+ /* For other private ioctls */
+ long (*vidioc_default) (struct file *file, void *fh,
+ int cmd, void *arg);
++ int (*vidioc_s_color_space_conv) (struct file *file, void *fh,
++ struct v4l2_color_space_conversion *a);
++ int (*vidioc_g_color_space_conv) (struct file *file, void *fh,
++ struct v4l2_color_space_conversion *a);
+ };
+
+
+--
+1.6.2.4
+
diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch b/recipes/linux/linux-omap-2.6.31/dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch
new file mode 100644
index 0000000000..0fd8135bb1
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch
@@ -0,0 +1,40 @@
+From 691a4534df820b6c90a37de1941197efbe86984a Mon Sep 17 00:00:00 2001
+From: Vaibhav Hiremath <hvaibhav@ti.com>
+Date: Fri, 21 Aug 2009 11:19:46 +0530
+Subject: [PATCH 3/5] V4L2: Updated v4l2_common for new V4L2 CIDs.
+
+Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
+---
+ drivers/media/video/v4l2-common.c | 9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
+index b91d66a..5dae426 100644
+--- a/drivers/media/video/v4l2-common.c
++++ b/drivers/media/video/v4l2-common.c
+@@ -421,6 +421,8 @@ const char *v4l2_ctrl_get_name(u32 id)
+ case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
+ case V4L2_CID_COLOR_KILLER: return "Color Killer";
+ case V4L2_CID_COLORFX: return "Color Effects";
++ case V4L2_CID_ROTATE: return "Rotate";
++ case V4L2_CID_BG_COLOR: return "Background color";
+
+ /* MPEG controls */
+ case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
+@@ -546,6 +548,13 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
+ qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ min = max = step = def = 0;
+ break;
++ case V4L2_CID_BG_COLOR:
++ qctrl->type = V4L2_CTRL_TYPE_INTEGER;
++ step = 1;
++ min = 0;
++ /* Max is calculated as RGB888 that is 2^12*/
++ max = 0xFFFFFF;
++ break;
+ default:
+ qctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+--
+1.6.2.4
+
diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch b/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch
new file mode 100644
index 0000000000..5db9c65d41
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch
@@ -0,0 +1,3248 @@
+From 2ae2dbacb82c5f0cb0fbcde7b49510d5cf2d45b5 Mon Sep 17 00:00:00 2001
+From: Vaibhav Hiremath <hvaibhav@ti.com>
+Date: Wed, 12 Aug 2009 19:38:30 +0530
+Subject: [PATCH 4/5] OMAP2/3 V4L2: Add support for OMAP2/3 V4L2 driver on top of DSS2
+
+Features Supported -
+ 1. Provides V4L2 user interface for the video pipelines of DSS
+ 2. Basic streaming working on LCD, DVI and TV.
+ 3. Works on latest DSS2 library from Tomi
+ 4. Support for various pixel formats like YUV, UYVY, RGB32, RGB24,
+ RGB565
+ 5. Supports Alpha blending.
+ 6. Supports Color keying both source and destination.
+ 7. Supports rotation.
+ 8. Supports cropping.
+ 9. Supports Background color setting.
+
+TODO:
+ 1. Complete Testing is pending, only basic test passed.
+
+Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
+---
+ arch/arm/plat-omap/devices.c | 29 +
+ drivers/media/video/Kconfig | 12 +
+ drivers/media/video/Makefile | 2 +
+ drivers/media/video/omap/Kconfig | 22 +
+ drivers/media/video/omap/Makefile | 2 +
+ drivers/media/video/omap/omap_vout.c | 2623 +++++++++++++++++++++++++++++++
+ drivers/media/video/omap/omap_voutdef.h | 148 ++
+ drivers/media/video/omap/omap_voutlib.c | 258 +++
+ drivers/media/video/omap/omap_voutlib.h | 34 +
+ 9 files changed, 3130 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/media/video/omap/Kconfig
+ create mode 100644 drivers/media/video/omap/Makefile
+ create mode 100644 drivers/media/video/omap/omap_vout.c
+ create mode 100644 drivers/media/video/omap/omap_voutdef.h
+ create mode 100644 drivers/media/video/omap/omap_voutlib.c
+ create mode 100644 drivers/media/video/omap/omap_voutlib.h
+
+diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
+index a64b692..8b6a9a0 100644
+--- a/arch/arm/plat-omap/devices.c
++++ b/arch/arm/plat-omap/devices.c
+@@ -357,6 +357,34 @@ static void omap_init_rng(void)
+ static inline void omap_init_rng(void) {}
+ #endif
+
++/*---------------------------------------------------------------------------*/
++
++#if defined(CONFIG_VIDEO_OMAP_VIDEOOUT) || \
++ defined(CONFIG_VIDEO_OMAP_VIDEOOUT_MODULE)
++#ifdef CONFIG_FB_OMAP2
++static struct resource omap3evm_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
++};
++#else
++static struct resource omap3evm_vout_resource[2] = {
++};
++#endif
++
++static struct platform_device omap3evm_vout_device = {
++ .name = "omap_vout",
++ .num_resources = ARRAY_SIZE(omap3evm_vout_resource),
++ .resource = &omap3evm_vout_resource[0],
++ .id = -1,
++};
++static void omap_init_vout(void)
++{
++ (void) platform_device_register(&omap3evm_vout_device);
++}
++#else
++static inline void omap_init_vout(void) {}
++#endif
++
++/*---------------------------------------------------------------------------*/
++
+ /*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+@@ -387,6 +415,7 @@ static int __init omap_init_devices(void)
+ omap_init_uwire();
+ omap_init_wdt();
+ omap_init_rng();
++ omap_init_vout();
+ return 0;
+ }
+ arch_initcall(omap_init_devices);
+diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
+index dcf9fa9..afb4478 100644
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -718,6 +718,18 @@ config VIDEO_CAFE_CCIC
+ CMOS camera controller. This is the controller found on first-
+ generation OLPC systems.
+
++config VIDEO_OMAP3
++ bool "OMAP2/OMAP3 Camera and V4L2-DSS drivers"
++ select VIDEOBUF_GEN
++ select VIDEOBUF_DMA_SG
++ select OMAP2_DSS
++ depends on VIDEO_DEV && (ARCH_OMAP24XX || ARCH_OMAP34XX)
++ default y
++ ---help---
++ V4L2 DSS and Camera driver support for OMAP2/3 based boards.
++
++source "drivers/media/video/omap/Kconfig"
++
+ config SOC_CAMERA
+ tristate "SoC camera support"
+ depends on VIDEO_V4L2 && HAS_DMA && I2C
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index 9f2e321..36040b9 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -117,6 +117,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
+
+ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
+
++obj-$(CONFIG_VIDEO_OMAP3) += omap/
++
+ obj-$(CONFIG_USB_DABUSB) += dabusb.o
+ obj-$(CONFIG_USB_OV511) += ov511.o
+ obj-$(CONFIG_USB_SE401) += se401.o
+diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig
+new file mode 100644
+index 0000000..5b86db3
+--- /dev/null
++++ b/drivers/media/video/omap/Kconfig
+@@ -0,0 +1,22 @@
++config VIDEO_OMAP_VIDEOOUT
++ tristate "OMAP Video out driver"
++ select VIDEOBUF_DMA_SG
++ select VIDEOBUF_GEN
++ depends on VIDEO_OMAP3
++ default VIDEO_OMAP3
++
++choice
++ prompt "TV Mode"
++ default NTSC_M
++
++config NTSC_M
++ bool "Use NTSC_M mode"
++ help
++ Select this option if you want NTSC_M mode on TV
++
++config PAL_BDGHI
++ bool "Use PAL_BDGHI mode"
++ help
++ Select this option if you want PAL_BDGHI mode on TV
++
++endchoice
+diff --git a/drivers/media/video/omap/Makefile b/drivers/media/video/omap/Makefile
+new file mode 100644
+index 0000000..18854c7
+--- /dev/null
++++ b/drivers/media/video/omap/Makefile
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_VIDEO_OMAP_VIDEOOUT) += omap_vout.o omap_voutlib.o
++
+diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
+new file mode 100644
+index 0000000..7e15db2
+--- /dev/null
++++ b/drivers/media/video/omap/omap_vout.c
+@@ -0,0 +1,2623 @@
++/*
++ * drivers/media/video/omap/omap_vout.c
++ *
++ * Copyright (C) 2005-2009 Texas Instruments.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ *
++ * Leveraged code from the OMAP2 camera driver
++ * Video-for-Linux (Version 2) camera capture driver for
++ * the OMAP24xx camera controller.
++ *
++ * Author: Andy Lowe (source@mvista.com)
++ *
++ * Copyright (C) 2004 MontaVista Software, Inc.
++ * Copyright (C) 2009 Texas Instruments.
++ *
++ * History:
++ * 20-APR-2006 Khasim Modified VRFB based Rotation,
++ * The image data is always read from 0 degree
++ * view and written
++ * to the virtual space of desired rotation angle
++ * 4-DEC-2006 Jian Changed to support better memory management
++ *
++ * 17-Nov-2008 Hardik Changed to used the new DSS paches by Tomi
++ * Changed driver to use video_ioctl2
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/kernel.h>
++#include <linux/vmalloc.h>
++#include <linux/interrupt.h>
++#include <linux/kdev_t.h>
++#include <linux/types.h>
++#include <linux/wait.h>
++#include <linux/videodev2.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/irq.h>
++
++#include <media/videobuf-dma-sg.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++
++#include <asm/processor.h>
++#include <mach/dma.h>
++#include <mach/vram.h>
++#include <mach/vrfb.h>
++#include <mach/display.h>
++
++#include "omap_voutlib.h"
++#include "omap_voutdef.h"
++
++MODULE_AUTHOR("Texas Instruments.");
++MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
++MODULE_LICENSE("GPL");
++
++#define OMAP_VIDEO1 0
++#define OMAP_VIDEO2 1
++
++/* configuration macros */
++#define VOUT_NAME "omap_vout"
++
++#define QQVGA_WIDTH 160
++#define QQVGA_HEIGHT 120
++
++#define NUM_OF_VIDEO_CHANNELS 2
++
++#define VID_MAX_WIDTH 1280 /* Largest width */
++#define VID_MAX_HEIGHT 720/* Largest height */
++
++/* Mimimum requirement is 2x2 for DSS */
++#define VID_MIN_WIDTH 2
++#define VID_MIN_HEIGHT 2
++
++/* 2048 x 2048 is max res supported by OMAP display controller */
++#define DMA_CHAN_ALLOTED 1
++#define DMA_CHAN_NOT_ALLOTED 0
++#define MAX_PIXELS_PER_LINE 2048
++#define VRFB_TX_TIMEOUT 1000
++
++/* IRQ Bits mask of DSS */
++#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
++
++static struct videobuf_queue_ops video_vbq_ops;
++
++static u32 video1_numbuffers = 3;
++static u32 video2_numbuffers = 3;
++static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
++static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
++static u32 vid1_static_vrfb_alloc;
++static u32 vid2_static_vrfb_alloc;
++static int debug;
++
++/* Module parameters */
++module_param(video1_numbuffers, uint, S_IRUGO);
++MODULE_PARM_DESC(video1_numbuffers,
++ "Number of buffers to be allocated at init time for Video1 device.");
++
++module_param(video2_numbuffers, uint, S_IRUGO);
++MODULE_PARM_DESC(video2_numbuffers,
++ "Number of buffers to be allocated at init time for Video2 device.");
++
++module_param(video1_bufsize, uint, S_IRUGO);
++MODULE_PARM_DESC(video1_bufsize,
++ "Size of the buffer to be allocated for video1 device");
++
++module_param(video2_bufsize, uint, S_IRUGO);
++MODULE_PARM_DESC(video2_bufsize,
++ "Size of the buffer to be allocated for video2 device");
++
++module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
++MODULE_PARM_DESC(vid1_static_vrfb_alloc,
++ "Static allocation of the VRFB buffer for video1 device");
++
++module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
++MODULE_PARM_DESC(vid2_static_vrfb_alloc,
++ "Static allocation of the VRFB buffer for video2 device");
++
++module_param(debug, bool, S_IRUGO);
++MODULE_PARM_DESC(debug, "Debug level (0-1)");
++
++/* Local Helper functions */
++static void omap_vout_isr(void *arg, unsigned int irqstatus);
++static void omap_vout_cleanup_device(struct omap_vout_device *vout);
++/*
++ * Maximum amount of memory to use for rendering buffers.
++ * Default is enough to four (RGB24) DVI 720P buffers.
++ */
++#define MAX_ALLOWED_VIDBUFFERS 4
++
++/* list of image formats supported by OMAP2 video pipelines */
++const static struct v4l2_fmtdesc omap_formats[] = {
++ {
++ /* Note: V4L2 defines RGB565 as:
++ *
++ * Byte 0 Byte 1
++ * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
++ *
++ * We interpret RGB565 as:
++ *
++ * Byte 0 Byte 1
++ * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
++ */
++ .description = "RGB565, le",
++ .pixelformat = V4L2_PIX_FMT_RGB565,
++ },
++ {
++ /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
++ * this for RGB24 unpack mode, the last 8 bits are ignored
++ * */
++ .description = "RGB32, le",
++ .pixelformat = V4L2_PIX_FMT_RGB32,
++ },
++ {
++ /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
++ * this for RGB24 packed mode
++ *
++ */
++ .description = "RGB24, le",
++ .pixelformat = V4L2_PIX_FMT_RGB24,
++ },
++ {
++ .description = "YUYV (YUV 4:2:2), packed",
++ .pixelformat = V4L2_PIX_FMT_YUYV,
++ },
++ {
++ .description = "UYVY, packed",
++ .pixelformat = V4L2_PIX_FMT_UYVY,
++ },
++};
++
++#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
++
++/* Allocate buffers */
++static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
++{
++ unsigned long virt_addr, addr;
++ u32 order, size;
++
++ size = PAGE_ALIGN(buf_size);
++ order = get_order(size);
++ virt_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, order);
++ addr = virt_addr;
++
++ if (virt_addr) {
++ while (size > 0) {
++ SetPageReserved(virt_to_page(addr));
++ addr += PAGE_SIZE;
++ size -= PAGE_SIZE;
++ }
++ }
++ *phys_addr = (u32) virt_to_phys((void *) virt_addr);
++ return virt_addr;
++}
++
++/* Free buffers */
++static void omap_vout_free_buffer(unsigned long virtaddr, u32 phys_addr,
++ u32 buf_size)
++{
++ unsigned long addr = virtaddr;
++ u32 order, size;
++
++ size = PAGE_ALIGN(buf_size);
++ order = get_order(size);
++
++ while (size > 0) {
++ ClearPageReserved(virt_to_page(addr));
++ addr += PAGE_SIZE;
++ size -= PAGE_SIZE;
++ }
++ free_pages((unsigned long) virtaddr, order);
++}
++
++/* Function for allocating video buffers */
++static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
++ unsigned int *count, int startindex)
++{
++ int i, j;
++
++ for (i = 0; i < *count; i++) {
++ if (!vout->smsshado_virt_addr[i]) {
++ vout->smsshado_virt_addr[i] =
++ omap_vout_alloc_buffer(vout->smsshado_size,
++ &vout->smsshado_phy_addr[i]);
++ }
++ if (!vout->smsshado_virt_addr[i] && startindex != -1) {
++ if (V4L2_MEMORY_MMAP == vout->memory
++ && i >= startindex)
++ break;
++ }
++ if (!vout->smsshado_virt_addr[i]) {
++ for (j = 0; j < i; j++) {
++ omap_vout_free_buffer(
++ vout->smsshado_virt_addr[j],
++ vout->smsshado_phy_addr[j],
++ vout->smsshado_size);
++ vout->smsshado_virt_addr[j] = 0;
++ vout->smsshado_phy_addr[j] = 0;
++ }
++ *count = 0;
++ return -ENOMEM;
++ }
++ memset((void *) vout->smsshado_virt_addr[i], 0,
++ vout->smsshado_size);
++ }
++ return 0;
++}
++
++/* Try format */
++static int omap_vout_try_format(struct v4l2_pix_format *pix)
++{
++ int ifmt, bpp = 0;
++
++ pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
++ (u32)VID_MAX_HEIGHT);
++ pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
++
++ for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
++ if (pix->pixelformat == omap_formats[ifmt].pixelformat)
++ break;
++ }
++
++ if (ifmt == NUM_OUTPUT_FORMATS)
++ ifmt = 0;
++
++ pix->pixelformat = omap_formats[ifmt].pixelformat;
++ pix->field = V4L2_FIELD_ANY;
++ pix->priv = 0;
++
++ switch (pix->pixelformat) {
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_UYVY:
++ default:
++ pix->colorspace = V4L2_COLORSPACE_JPEG;
++ bpp = YUYV_BPP;
++ break;
++ case V4L2_PIX_FMT_RGB565:
++ case V4L2_PIX_FMT_RGB565X:
++ pix->colorspace = V4L2_COLORSPACE_SRGB;
++ bpp = RGB565_BPP;
++ break;
++ case V4L2_PIX_FMT_RGB24:
++ pix->colorspace = V4L2_COLORSPACE_SRGB;
++ bpp = RGB24_BPP;
++ break;
++ case V4L2_PIX_FMT_RGB32:
++ case V4L2_PIX_FMT_BGR32:
++ pix->colorspace = V4L2_COLORSPACE_SRGB;
++ bpp = RGB32_BPP;
++ break;
++ }
++ pix->bytesperline = pix->width * bpp;
++ pix->sizeimage = pix->bytesperline * pix->height;
++ return bpp;
++}
++
++/*
++ * omap_vout_uservirt_to_phys: This inline function is used to convert user
++ * space virtual address to physical address.
++ */
++static inline u32 omap_vout_uservirt_to_phys(u32 virtp)
++{
++ unsigned long physp = 0;
++ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma;
++
++ vma = find_vma(mm, virtp);
++ /* For kernel direct-mapped memory, take the easy way */
++ if (virtp >= PAGE_OFFSET) {
++ physp = virt_to_phys((void *) virtp);
++ } else if (vma && (vma->vm_flags & VM_IO)
++ && vma->vm_pgoff) {
++ /* this will catch, kernel-allocated,
++ mmaped-to-usermode addresses */
++ physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
++ } else {
++ /* otherwise, use get_user_pages() for general userland pages */
++ int res, nr_pages = 1;
++ struct page *pages;
++ down_read(&current->mm->mmap_sem);
++
++ res = get_user_pages(current, current->mm, virtp, nr_pages,
++ 1, 0, &pages, NULL);
++ up_read(&current->mm->mmap_sem);
++
++ if (res == nr_pages) {
++ physp = __pa(page_address(&pages[0]) +
++ (virtp & ~PAGE_MASK));
++ } else {
++ printk(KERN_WARNING VOUT_NAME
++ "get_user_pages failed\n");
++ return 0;
++ }
++ }
++
++ return physp;
++}
++
++/* This functions wakes up the application once
++ * the DMA transfer to VRFB space is completed. */
++static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
++{
++ struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
++
++ t->tx_status = 1;
++ wake_up_interruptible(&t->wait);
++}
++
++/* Release the VRFB context once the module exits */
++static void omap_vout_release_vrfb(struct omap_vout_device *vout)
++{
++ int i;
++
++ for (i = 0; i < 4; i++)
++ omap_vrfb_release_ctx(&vout->vrfb_context[i]);
++
++ if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
++ vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
++ omap_free_dma(vout->vrfb_dma_tx.dma_ch);
++ }
++
++}
++
++/* Return true if rotation is 90 or 270 */
++static inline int rotate_90_or_270(const struct omap_vout_device *vout)
++{
++ return (vout->rotation == dss_rotation_90_degree ||
++ vout->rotation == dss_rotation_270_degree);
++}
++
++/* Return true if rotation is enabled */
++static inline int rotation_enabled(const struct omap_vout_device *vout)
++{
++ return vout->rotation || vout->mirror;
++}
++
++/* Reverse the rotation degree if mirroring is enabled */
++static inline int calc_rotation(const struct omap_vout_device *vout)
++{
++ if (!vout->mirror)
++ return vout->rotation;
++
++ switch (vout->rotation) {
++ case dss_rotation_90_degree:
++ return dss_rotation_270_degree;
++ case dss_rotation_270_degree:
++ return dss_rotation_90_degree;
++ case dss_rotation_180_degree:
++ return dss_rotation_0_degree;
++ default:
++ return dss_rotation_180_degree;
++ }
++}
++
++/* Free the V4L2 buffers */
++static void omap_vout_free_buffers(struct omap_vout_device *vout)
++{
++ int i, numbuffers;
++
++ /* Allocate memory for the buffers */
++ numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers;
++ vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
++
++ for (i = 0; i < numbuffers; i++) {
++ omap_vout_free_buffer(vout->buf_virt_addr[i],
++ vout->buf_phy_addr[i], vout->buffer_size);
++ vout->buf_phy_addr[i] = 0;
++ vout->buf_virt_addr[i] = 0;
++ }
++}
++
++/* Free VRFB buffers */
++static void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
++{
++ int j;
++
++ for (j = 0; j < 4; j++) {
++ omap_vout_free_buffer(vout->smsshado_virt_addr[j],
++ vout->smsshado_phy_addr[j],
++ vout->smsshado_size);
++ vout->smsshado_virt_addr[j] = 0;
++ vout->smsshado_phy_addr[j] = 0;
++ }
++}
++
++/* Allocate the buffers for the VRFB space. Data is copied from V4L2
++ * buffers to the VRFB buffers using the DMA engine.*/
++static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
++ unsigned int *count, unsigned int startindex)
++{
++ int i;
++ bool yuv_mode;
++
++ /* Allocate the VRFB buffers only if the buffers are not
++ * allocated during init time.
++ */
++ if ((rotation_enabled(vout)) &&
++ !vout->vrfb_static_allocation)
++ if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
++ return -ENOMEM;
++
++ if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
++ vout->dss_mode == OMAP_DSS_COLOR_UYVY)
++ yuv_mode = true;
++ else
++ yuv_mode = false;
++
++ for (i = 0; i < *count; i++) {
++ omap_vrfb_setup(&vout->vrfb_context[i],
++ vout->smsshado_phy_addr[i],
++ vout->pix.width, vout->pix.height,
++ vout->bpp, yuv_mode);
++ }
++ return 0;
++}
++
++/* Convert V4L2 rotation to DSS rotation
++ * V4L2 understand 0, 90, 180, 270.
++ * convert to 0, 1, 2 and 3 repsectively for DSS */
++static int v4l2_rot_to_dss_rot(int v4l2_rotation, enum dss_rotation *rotation,
++ bool mirror)
++{
++ switch (v4l2_rotation) {
++ case 90:
++ *rotation = dss_rotation_90_degree;
++ return 0;
++ case 180:
++ *rotation = dss_rotation_180_degree;
++ return 0;
++ case 270:
++ *rotation = dss_rotation_270_degree;
++ return 0;
++ case 0:
++ *rotation = dss_rotation_0_degree;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++
++}
++
++/* Calculate the buffer offsets from which the streaming should
++ * start. This offset calculation is mainly required because of
++ * the VRFB 32 pixels alignment with rotation
++ */
++static int omap_vout_calculate_offset(struct omap_vout_device *vout)
++{
++ struct v4l2_pix_format *pix = &vout->pix;
++ struct v4l2_rect *crop = &vout->crop;
++ enum dss_rotation rotation;
++ bool mirroring = vout->mirror;
++ int vr_ps = 1, ps = 2, temp_ps = 2;
++ int offset = 0, ctop = 0, cleft = 0, line_length = 0;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ struct omap_dss_device *cur_display;
++ int *cropped_offset = &vout->cropped_offset;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++ /* get the display device attached to the overlay */
++ if (!ovl->manager || !ovl->manager->device)
++ return -1;
++ cur_display = ovl->manager->device;
++
++ rotation = calc_rotation(vout);
++
++ if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
++ V4L2_PIX_FMT_UYVY == pix->pixelformat) {
++ if (rotation_enabled(vout)) {
++ /*
++ * ps - Actual pixel size for YUYV/UYVY for
++ * VRFB/Mirroring is 4 bytes
++ * vr_ps - Virtually pixel size for YUYV/UYVY is
++ * 2 bytes
++ */
++ ps = 4;
++ vr_ps = 2;
++ } else {
++ ps = 2; /* otherwise the pixel size is 2 byte */
++ }
++ } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
++ ps = 4;
++ } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
++ ps = 3;
++ }
++ vout->ps = ps;
++ vout->vr_ps = vr_ps;
++ if (rotation_enabled(vout)) {
++ line_length = MAX_PIXELS_PER_LINE;
++ ctop = (pix->height - crop->height) - crop->top;
++ cleft = (pix->width - crop->width) - crop->left;
++ } else {
++ line_length = pix->width;
++ }
++ vout->line_length = line_length;
++ switch (rotation) {
++ case dss_rotation_90_degree:
++ offset = vout->vrfb_context[0].yoffset *
++ vout->vrfb_context[0].bytespp;
++ temp_ps = ps / vr_ps;
++ if (mirroring == 0) {
++ *cropped_offset = offset + line_length *
++ temp_ps * cleft + crop->top * temp_ps;
++ } else {
++ *cropped_offset = offset + line_length * temp_ps *
++ cleft + crop->top * temp_ps + (line_length *
++ ((crop->width / (vr_ps)) - 1) * ps);
++ }
++ break;
++ case dss_rotation_180_degree:
++ offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset *
++ vout->vrfb_context[0].bytespp) +
++ (vout->vrfb_context[0].xoffset *
++ vout->vrfb_context[0].bytespp));
++ if (mirroring == 0) {
++ *cropped_offset = offset + (line_length * ps * ctop) +
++ (cleft / vr_ps) * ps;
++
++ } else {
++ *cropped_offset = offset + (line_length * ps * ctop) +
++ (cleft / vr_ps) * ps + (line_length *
++ (crop->height - 1) * ps);
++ }
++ break;
++ case dss_rotation_270_degree:
++ offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset *
++ vout->vrfb_context[0].bytespp;
++ temp_ps = ps / vr_ps;
++ if (mirroring == 0) {
++ *cropped_offset = offset + line_length *
++ temp_ps * crop->left + ctop * ps;
++ } else {
++ *cropped_offset = offset + line_length *
++ temp_ps * crop->left + ctop * ps +
++ (line_length * ((crop->width / vr_ps) - 1) *
++ ps);
++ }
++ break;
++ case dss_rotation_0_degree:
++ if (mirroring == 0) {
++ *cropped_offset = (line_length * ps) *
++ crop->top + (crop->left / vr_ps) * ps;
++ } else {
++ *cropped_offset = (line_length * ps) *
++ crop->top + (crop->left / vr_ps) * ps +
++ (line_length * (crop->height - 1) * ps);
++ }
++ break;
++ default:
++ *cropped_offset = (line_length * ps * crop->top) /
++ vr_ps + (crop->left * ps) / vr_ps +
++ ((crop->width / vr_ps) - 1) * ps;
++ break;
++ }
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ "%s Offset:%x\n", __func__, *cropped_offset);
++ return 0;
++}
++
++/* convert V4L2 pixel format to DSS pixel format */
++static enum omap_color_mode video_mode_to_dss_mode(struct omap_vout_device
++ *vout)
++{
++ struct omap_overlay *ovl;
++ struct omapvideo_info *ovid;
++ struct v4l2_pix_format *pix = &vout->pix;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ switch (pix->pixelformat) {
++ case 0:
++ break;
++ case V4L2_PIX_FMT_YUYV:
++ return OMAP_DSS_COLOR_YUV2;
++
++ case V4L2_PIX_FMT_UYVY:
++ return OMAP_DSS_COLOR_UYVY;
++
++ case V4L2_PIX_FMT_RGB565:
++ return OMAP_DSS_COLOR_RGB16;
++
++ case V4L2_PIX_FMT_RGB24:
++ return OMAP_DSS_COLOR_RGB24P;
++
++ case V4L2_PIX_FMT_RGB32:
++ return (ovl->id == OMAP_DSS_VIDEO1) ?
++ OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
++ case V4L2_PIX_FMT_BGR32:
++ return OMAP_DSS_COLOR_RGBX32;
++
++ default:
++ return -EINVAL;
++ }
++ return -EINVAL;
++}
++
++/* Setup the overlay */
++int omapvid_setup_overlay(struct omap_vout_device *vout,
++ struct omap_overlay *ovl, int posx, int posy, int outw,
++ int outh, u32 addr)
++{
++ int r = 0;
++ enum omap_color_mode mode = 0;
++ enum dss_rotation rotation;
++ bool mirror;
++ int cropheight, cropwidth, pixheight, pixwidth;
++ struct omap_overlay_info info;
++
++ if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
++ (outw != vout->pix.width || outh != vout->pix.height)) {
++ r = -EINVAL;
++ goto err;
++ }
++
++ vout->dss_mode = video_mode_to_dss_mode(vout);
++
++ if (mode == -EINVAL) {
++ r = -EINVAL;
++ goto err;
++ }
++
++ rotation = vout->rotation;
++ mirror = vout->mirror;
++
++ /* Setup the input plane parameters according to
++ * rotation value selected.
++ */
++ if (rotate_90_or_270(vout)) {
++ cropheight = vout->crop.width;
++ cropwidth = vout->crop.height;
++ pixheight = vout->pix.width;
++ pixwidth = vout->pix.height;
++ } else {
++ cropheight = vout->crop.height;
++ cropwidth = vout->crop.width;
++ pixheight = vout->pix.height;
++ pixwidth = vout->pix.width;
++ }
++
++ ovl->get_overlay_info(ovl, &info);
++ info.paddr = addr;
++ info.vaddr = NULL;
++ info.width = cropwidth;
++ info.height = cropheight;
++ info.color_mode = vout->dss_mode;
++ info.mirror = mirror;
++ info.pos_x = posx;
++ info.pos_y = posy;
++ info.out_width = outw;
++ info.out_height = outh;
++ info.global_alpha = vout->win.global_alpha;
++ if (!rotation_enabled(vout)) {
++ info.rotation = 0;
++ info.rotation_type = OMAP_DSS_ROT_DMA;
++ info.screen_width = pixwidth;
++ } else {
++ info.rotation = vout->rotation;
++ info.rotation_type = OMAP_DSS_ROT_VRFB;
++ info.screen_width = 2048;
++ }
++
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ "%s info.enable=%d info.addr=%x info.width=%d\n info.height=%d "
++ "info.color_mode=%d info.rotation=%d info.mirror=%d\n "
++ "info.posx=%d info.posy=%d info.out_width = %d info.out_height=%d\n "
++ "info.rotation_type=%d info.screen_width=%d\n", __func__, info.enabled,
++ info.paddr, info.width, info.height, info.color_mode, info.rotation,
++ info.mirror, info.pos_x, info.pos_y, info.out_width, info.out_height,
++ info.rotation_type, info.screen_width);
++
++ r = ovl->set_overlay_info(ovl, &info);
++ if (r)
++ goto err;
++
++ return 0;
++err:
++ printk(KERN_WARNING VOUT_NAME "setup_overlay failed\n");
++ return r;
++}
++
++/* Initialize the overlay structure */
++int omapvid_init(struct omap_vout_device *vout, u32 addr)
++{
++ int r = 0;
++ struct omapvideo_info *ovid = &vout->vid_info;
++ struct omap_overlay *ovl;
++ int posx, posy;
++ int outw, outh, temp, rotation;
++ int i;
++ struct v4l2_window *win;
++ struct omap_video_timings *timing;
++
++ win = &vout->win;
++ rotation = vout->rotation;
++ for (i = 0; i < ovid->num_overlays; i++) {
++ ovl = ovid->overlays[i];
++ if (!ovl->manager || !ovl->manager->device)
++ return -EINVAL;
++
++ timing = &ovl->manager->device->panel.timings;
++
++ outw = win->w.width;
++ outh = win->w.height;
++ switch (rotation) {
++ case dss_rotation_90_degree:
++ /* Invert the height and width for 90
++ * and 270 degree rotation
++ */
++ temp = outw;
++ outw = outh;
++ outh = temp;
++ posy = (timing->y_res - win->w.width)-
++ win->w.left;
++ posx = win->w.top;
++ break;
++
++ case dss_rotation_180_degree:
++ posx = (timing->x_res - win->w.width) -
++ win->w.left;
++ posy = (timing->y_res - win->w.height) -
++ win->w.top;
++ break;
++
++ case dss_rotation_270_degree:
++ temp = outw;
++ outw = outh;
++ outh = temp;
++ posy = win->w.left;
++ posx = (timing->x_res - win->w.height)
++ - win->w.top;
++ break;
++
++ default:
++ posx = win->w.left;
++ posy = win->w.top;
++ break;
++ }
++
++ r = omapvid_setup_overlay(vout, ovl, posx, posy, outw,
++ outh, addr);
++ if (r)
++ goto err;
++ }
++ return 0;
++err:
++ printk(KERN_WARNING VOUT_NAME "apply_changes failed\n");
++ return r;
++}
++
++/* Apply the changes set the go bit of DSS */
++int omapvid_apply_changes(struct omap_vout_device *vout)
++{
++ struct omapvideo_info *ovid = &vout->vid_info;
++ struct omap_overlay *ovl;
++ int i;
++
++ for (i = 0; i < ovid->num_overlays; i++) {
++ ovl = ovid->overlays[i];
++ if (!ovl->manager || !ovl->manager->device)
++ return -EINVAL;
++ ovl->manager->apply(ovl->manager);
++ }
++ return 0;
++
++}
++
++/* Video buffer call backs */
++
++/* Buffer setup function is called by videobuf layer when REQBUF ioctl is
++ * called. This is used to setup buffers and return size and count of
++ * buffers allocated. After the call to this buffer, videobuf layer will
++ * setup buffer queue depending on the size and count of buffers
++ */
++static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
++ unsigned int *size)
++{
++ struct omap_vout_device *vout = q->priv_data;
++ int startindex = 0, i, j;
++ u32 phy_addr = 0, virt_addr = 0;
++
++ if (!vout)
++ return -EINVAL;
++
++ if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
++ return -EINVAL;
++
++ startindex = (vout->vid == OMAP_VIDEO1) ?
++ video1_numbuffers : video2_numbuffers;
++ if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
++ *count = startindex;
++
++ if ((rotation_enabled(vout))
++ && *count > 4)
++ *count = 4;
++
++ /* If rotation is enabled, allocate memory for VRFB space also */
++ if (rotation_enabled(vout)) {
++ if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
++ return -ENOMEM;
++ }
++
++ if (V4L2_MEMORY_MMAP != vout->memory)
++ return 0;
++
++ /* Now allocated the V4L2 buffers */
++ *size = vout->buffer_size;
++ startindex = (vout->vid == OMAP_VIDEO1) ?
++ video1_numbuffers : video2_numbuffers;
++ for (i = startindex; i < *count; i++) {
++ vout->buffer_size = *size;
++
++ virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
++ &phy_addr);
++ if (!virt_addr) {
++ if (!rotation_enabled(vout))
++ break;
++ /* Free the VRFB buffers if no space for V4L2 buffers */
++ for (j = i; j < *count; j++) {
++ omap_vout_free_buffer(
++ vout->smsshado_virt_addr[j],
++ vout->smsshado_phy_addr[j],
++ vout->smsshado_size);
++ vout->smsshado_virt_addr[j] = 0;
++ vout->smsshado_phy_addr[j] = 0;
++ }
++ }
++ vout->buf_virt_addr[i] = virt_addr;
++ vout->buf_phy_addr[i] = phy_addr;
++ }
++ *count = vout->buffer_allocated = i;
++ return 0;
++}
++
++/* Free the V4L2 buffers additionally allocated than default
++ * number of buffers and free all the VRFB buffers */
++static void omap_vout_free_allbuffers(struct omap_vout_device *vout)
++{
++ int num_buffers = 0, i;
++
++ num_buffers = (vout->vid == OMAP_VIDEO1) ?
++ video1_numbuffers : video2_numbuffers;
++ for (i = num_buffers; i < vout->buffer_allocated; i++) {
++ if (vout->buf_virt_addr[i]) {
++ omap_vout_free_buffer(vout->buf_virt_addr[i],
++ vout->buf_phy_addr[i], vout->buffer_size);
++ }
++ vout->buf_virt_addr[i] = 0;
++ vout->buf_phy_addr[i] = 0;
++ }
++ /* Free the VRFB buffers only if they are allocated
++ * during reqbufs. Don't free if init time allocated
++ */
++ if (!vout->vrfb_static_allocation) {
++ for (i = 0; i < 4; i++) {
++ if (vout->smsshado_virt_addr[i]) {
++ omap_vout_free_buffer(
++ vout->smsshado_virt_addr[i],
++ vout->smsshado_phy_addr[i],
++ vout->smsshado_size);
++ vout->smsshado_virt_addr[i] = 0;
++ vout->smsshado_phy_addr[i] = 0;
++ }
++ }
++ }
++ vout->buffer_allocated = num_buffers;
++}
++
++/* This function will be called when VIDIOC_QBUF ioctl is called.
++ * It prepare buffers before give out for the display. This function
++ * user space virtual address into physical address if userptr memory
++ * exchange mechanism is used. If rotation is enabled, it copies entire
++ * buffer into VRFB memory space before giving it to the DSS.
++ */
++static int omap_vout_buffer_prepare(struct videobuf_queue *q,
++ struct videobuf_buffer *vb,
++ enum v4l2_field field)
++{
++ struct omap_vout_device *vout = q->priv_data;
++ u32 dest_frame_index = 0, src_element_index = 0;
++ u32 dest_element_index = 0, src_frame_index = 0;
++ u32 elem_count = 0, frame_count = 0, pixsize = 2;
++ struct videobuf_dmabuf *dmabuf = NULL;
++ enum dss_rotation rotation;
++ struct vid_vrfb_dma *tx;
++
++ if (VIDEOBUF_NEEDS_INIT == vb->state) {
++ vb->width = vout->pix.width;
++ vb->height = vout->pix.height;
++ vb->size = vb->width * vb->height * vout->bpp;
++ vb->field = field;
++ }
++ vb->state = VIDEOBUF_PREPARED;
++ /* if user pointer memory mechanism is used, get the physical
++ * address of the buffer
++ */
++ if (V4L2_MEMORY_USERPTR == vb->memory) {
++ if (0 == vb->baddr)
++ return -EINVAL;
++ /* Virtual address */
++ /* priv points to struct videobuf_pci_sg_memory. But we went
++ * pointer to videobuf_dmabuf, which is member of
++ * videobuf_pci_sg_memory */
++ dmabuf = videobuf_to_dma(q->bufs[vb->i]);
++ dmabuf->vmalloc = (void *) vb->baddr;
++
++ /* Physical address */
++ dmabuf->bus_addr =
++ (dma_addr_t) omap_vout_uservirt_to_phys(vb->baddr);
++ }
++
++ if (!rotation_enabled(vout)) {
++ dmabuf = videobuf_to_dma(q->bufs[vb->i]);
++
++ vout->queued_buf_addr[vb->i] = (u8 *) dmabuf->bus_addr;
++ return 0;
++ }
++ dmabuf = videobuf_to_dma(q->bufs[vb->i]);
++ /* If rotation is enabled, copy input buffer into VRFB
++ * memory space using DMA. We are copying input buffer
++ * into VRFB memory space of desired angle and DSS will
++ * read image VRFB memory for 0 degree angle
++ */
++ pixsize = vout->bpp * vout->vrfb_bpp;
++ /*
++ * DMA transfer in double index mode
++ */
++
++ /* Frame index */
++ dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
++ (vout->pix.width * vout->bpp)) + 1;
++
++ /* Source and destination parameters */
++ src_element_index = 0;
++ src_frame_index = 0;
++ dest_element_index = 1;
++ /* Number of elements per frame */
++ elem_count = vout->pix.width * vout->bpp;
++ frame_count = vout->pix.height;
++ tx = &vout->vrfb_dma_tx;
++ tx->tx_status = 0;
++ omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
++ (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
++ tx->dev_id, 0x0);
++ /* src_port required only for OMAP1 */
++ omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
++ dmabuf->bus_addr, src_element_index, src_frame_index);
++ /*set dma source burst mode for VRFB */
++ omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
++ rotation = calc_rotation(vout);
++
++ /* dest_port required only for OMAP1 */
++ omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
++ vout->vrfb_context[vb->i].paddr[0], dest_element_index,
++ dest_frame_index);
++ /*set dma dest burst mode for VRFB */
++ omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
++ omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
++
++ omap_start_dma(tx->dma_ch);
++ interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
++
++ if (tx->tx_status == 0) {
++ omap_stop_dma(tx->dma_ch);
++ return -EINVAL;
++ }
++ /* Store buffers physical address into an array. Addresses
++ * from this array will be used to configure DSS */
++ vout->queued_buf_addr[vb->i] = (u8 *)
++ vout->vrfb_context[vb->i].paddr[rotation];
++ return 0;
++}
++
++/* Buffer queue funtion will be called from the videobuf layer when _QBUF
++ * ioctl is called. It is used to enqueue buffer, which is ready to be
++ * displayed. */
++static void omap_vout_buffer_queue(struct videobuf_queue *q,
++ struct videobuf_buffer *vb)
++{
++ struct omap_vout_device *vout = q->priv_data;
++
++ /* Driver is also maintainig a queue. So enqueue buffer in the driver
++ * queue */
++ list_add_tail(&vb->queue, &vout->dma_queue);
++
++ vb->state = VIDEOBUF_PREPARED;
++}
++
++/* Buffer release function is called from videobuf layer to release buffer
++ * which are already allocated */
++static void omap_vout_buffer_release(struct videobuf_queue *q,
++ struct videobuf_buffer *vb)
++{
++ struct omap_vout_device *vout = q->priv_data;
++
++ vb->state = VIDEOBUF_NEEDS_INIT;
++
++ if (V4L2_MEMORY_MMAP != vout->memory)
++ return;
++}
++
++/*
++ * File operations
++ */
++static void omap_vout_vm_open(struct vm_area_struct *vma)
++{
++ struct omap_vout_device *vout = vma->vm_private_data;
++
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
++ vout->mmap_count++;
++}
++
++static void omap_vout_vm_close(struct vm_area_struct *vma)
++{
++ struct omap_vout_device *vout = vma->vm_private_data;
++
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
++ vout->mmap_count--;
++}
++
++static struct vm_operations_struct omap_vout_vm_ops = {
++ .open = omap_vout_vm_open,
++ .close = omap_vout_vm_close,
++};
++
++static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct omap_vout_device *vout = file->private_data;
++ struct videobuf_queue *q = &vout->vbq;
++ unsigned long size = (vma->vm_end - vma->vm_start);
++ unsigned long start = vma->vm_start;
++ int i;
++ void *pos;
++ struct videobuf_dmabuf *dmabuf = NULL;
++
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
++ vma->vm_pgoff, vma->vm_start, vma->vm_end);
++
++ /* look for the buffer to map */
++ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
++ if (NULL == q->bufs[i])
++ continue;
++ if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
++ continue;
++ if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
++ break;
++ }
++
++ if (VIDEO_MAX_FRAME == i) {
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
++ "offset invalid [offset=0x%lx]\n",
++ (vma->vm_pgoff << PAGE_SHIFT));
++ return -EINVAL;
++ }
++ q->bufs[i]->baddr = vma->vm_start;
++
++ vma->vm_flags |= VM_RESERVED;
++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++ vma->vm_ops = &omap_vout_vm_ops;
++ vma->vm_private_data = (void *) vout;
++ dmabuf = videobuf_to_dma(q->bufs[i]);
++ pos = dmabuf->vmalloc;
++ vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
++ while (size > 0) {
++ unsigned long pfn;
++ pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
++ if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
++ return -EAGAIN;
++ start += PAGE_SIZE;
++ pos += PAGE_SIZE;
++ size -= PAGE_SIZE;
++ }
++ vout->mmap_count++;
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
++ return 0;
++}
++
++static int omap_vout_release(struct file *file)
++{
++
++ struct omap_vout_device *vout = file->private_data;
++ struct videobuf_queue *q;
++ unsigned int t;
++ struct omapvideo_info *ovid;
++ unsigned int r;
++
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
++ ovid = &vout->vid_info;
++
++ if (!vout)
++ return 0;
++ q = &vout->vbq;
++
++ /* Disable all the overlay managers connected with this interface */
++ for (t = 0; t < ovid->num_overlays; t++) {
++ struct omap_overlay *ovl = ovid->overlays[t];
++ if (ovl->manager && ovl->manager->device) {
++ struct omap_overlay_info info;
++ ovl->get_overlay_info(ovl, &info);
++ info.enabled = 0;
++ ovl->set_overlay_info(ovl, &info);
++ }
++
++ }
++ /* Turn off the pipeline */
++ r = omapvid_apply_changes(vout);
++ if (r)
++ printk(KERN_WARNING VOUT_NAME "Unable to apply changes\n");
++
++ /* Free all buffers */
++ omap_vout_free_allbuffers(vout);
++ videobuf_mmap_free(q);
++
++ /* Even if apply changes fails we should continue
++ freeing allocated memeory */
++ if (vout->streaming) {
++ u32 mask = 0;
++
++ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
++ DISPC_IRQ_EVSYNC_ODD;
++ omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
++ vout->streaming = 0;
++
++ videobuf_streamoff(q);
++ videobuf_queue_cancel(q);
++
++ }
++
++ if (vout->mmap_count != 0)
++ vout->mmap_count = 0;
++
++ vout->opened -= 1;
++ file->private_data = NULL;
++
++ if (vout->buffer_allocated)
++ videobuf_mmap_free(q);
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
++ return r;
++}
++
++static int omap_vout_open(struct file *file)
++{
++ struct omap_vout_device *vout = NULL;
++ struct videobuf_queue *q;
++
++ vout = video_drvdata(file);
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
++
++ if (vout == NULL)
++ return -ENODEV;
++
++ /* for now, we only support single open */
++ if (vout->opened)
++ return -EBUSY;
++
++ vout->opened += 1;
++
++ file->private_data = vout;
++ vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++
++ q = &vout->vbq;
++ video_vbq_ops.buf_setup = omap_vout_buffer_setup;
++ video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
++ video_vbq_ops.buf_release = omap_vout_buffer_release;
++ video_vbq_ops.buf_queue = omap_vout_buffer_queue;
++ spin_lock_init(&vout->vbq_lock);
++
++ videobuf_queue_sg_init(q, &video_vbq_ops, NULL, &vout->vbq_lock,
++ vout->type, V4L2_FIELD_NONE, sizeof
++ (struct videobuf_buffer), vout);
++ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
++ return 0;
++}
++
++/* V4L2 ioctls */
++static int vidioc_querycap(struct file *file, void *fh,
++ struct v4l2_capability *cap)
++{
++ struct omap_vout_device *vout = fh;
++
++ strlcpy(cap->driver, VOUT_NAME,
++ sizeof(cap->driver));
++ strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
++ cap->bus_info[0] = '\0';
++ cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
++ return 0;
++}
++
++static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
++ struct v4l2_fmtdesc *fmt)
++{
++ int index = fmt->index;
++ enum v4l2_buf_type type = fmt->type;
++
++ fmt->index = index;
++ fmt->type = type;
++ if (index >= NUM_OUTPUT_FORMATS)
++ return -EINVAL;
++
++ fmt->flags = omap_formats[index].flags;
++ strlcpy(fmt->description, omap_formats[index].description,
++ sizeof(fmt->description));
++ fmt->pixelformat = omap_formats[index].pixelformat;
++ return 0;
++}
++
++static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ struct omap_vout_device *vout = fh;
++
++ f->fmt.pix = vout->pix;
++ return 0;
++
++}
++
++static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ struct omap_vout_device *vout = fh;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ struct omap_video_timings *timing;
++
++ if (vout->streaming)
++ return -EBUSY;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ if (!ovl->manager || !ovl->manager->device)
++ return -EINVAL;
++ /* get the display device attached to the overlay */
++ timing = &ovl->manager->device->panel.timings;
++
++ vout->fbuf.fmt.height = timing->y_res;
++ vout->fbuf.fmt.width = timing->x_res;
++
++ omap_vout_try_format(&f->fmt.pix);
++ return 0;
++}
++
++static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ struct omap_vout_device *vout = fh;
++ int bpp;
++ int r;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ struct omap_video_timings *timing;
++
++ if (vout->streaming)
++ return -EBUSY;
++
++ mutex_lock(&vout->lock);
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ /* get the display device attached to the overlay */
++ if (!ovl->manager || !ovl->manager->device) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++ timing = &ovl->manager->device->panel.timings;
++
++ /* We dont support RGB24-packed mode if vrfb rotation
++ * is enabled*/
++ if ((rotation_enabled(vout)) &&
++ f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++
++ /* get the framebuffer parameters */
++
++ if (rotate_90_or_270(vout)) {
++ vout->fbuf.fmt.height = timing->x_res;
++ vout->fbuf.fmt.width = timing->y_res;
++ } else {
++ vout->fbuf.fmt.height = timing->y_res;
++ vout->fbuf.fmt.width = timing->x_res;
++ }
++
++ /* change to samller size is OK */
++
++ bpp = omap_vout_try_format(&f->fmt.pix);
++ f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
++
++ /* try & set the new output format */
++ vout->bpp = bpp;
++ vout->pix = f->fmt.pix;
++ vout->vrfb_bpp = 1;
++
++ /* If YUYV then vrfb bpp is 2, for others its 1 */
++ if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
++ V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
++ vout->vrfb_bpp = 2;
++
++ /* set default crop and win */
++ omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
++
++ /* Save the changes in the overlay strcuture */
++ r = omapvid_init(vout, 0);
++ if (r) {
++ printk(KERN_ERR VOUT_NAME "failed to change mode\n");
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++ mutex_unlock(&vout->lock);
++ return 0;
++}
++
++static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ int err = -EINVAL;
++ struct omap_vout_device *vout = fh;
++ struct v4l2_window *win = &f->fmt.win;
++
++ err = omap_vout_try_window(&vout->fbuf, win);
++
++ if (err)
++ return err;
++
++ if (vout->vid == OMAP_VIDEO1)
++ win->global_alpha = 255;
++ else
++ win->global_alpha = f->fmt.win.global_alpha;
++
++ return 0;
++}
++
++static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ struct omap_vout_device *vout = fh;
++ int err = -EINVAL;
++ struct omap_overlay *ovl;
++ struct omapvideo_info *ovid;
++ struct v4l2_window *win = &f->fmt.win;
++
++ mutex_lock(&vout->lock);
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ err = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
++ if (err) {
++ mutex_unlock(&vout->lock);
++ return err;
++ }
++ /* Video1 plane does not support global alpha */
++ if (ovl->id == OMAP_DSS_VIDEO1)
++ vout->win.global_alpha = 255;
++ else
++ vout->win.global_alpha = f->fmt.win.global_alpha;
++
++ vout->win.chromakey = f->fmt.win.chromakey;
++ mutex_unlock(&vout->lock);
++ return 0;
++}
++
++static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
++ struct v4l2_fmtdesc *fmt)
++{
++ int index = fmt->index;
++ enum v4l2_buf_type type = fmt->type;
++
++ fmt->index = index;
++ fmt->type = type;
++ if (index >= NUM_OUTPUT_FORMATS)
++ return -EINVAL;
++
++ fmt->flags = omap_formats[index].flags;
++ strlcpy(fmt->description, omap_formats[index].description,
++ sizeof(fmt->description));
++ fmt->pixelformat = omap_formats[index].pixelformat;
++ return 0;
++}
++
++static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
++ struct v4l2_format *f)
++{
++ struct omap_vout_device *vout = fh;
++ struct omap_overlay *ovl;
++ struct omapvideo_info *ovid;
++ struct omap_overlay_manager_info info;
++ struct v4l2_window *win = &f->fmt.win;
++ u32 key_value = 0;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ win->w = vout->win.w;
++ win->field = vout->win.field;
++ win->global_alpha = vout->win.global_alpha;
++
++ if (ovl->manager && ovl->manager->get_manager_info) {
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ key_value = info.trans_key;
++ }
++ win->chromakey = key_value;
++ return 0;
++}
++
++static int vidioc_cropcap(struct file *file, void *fh,
++ struct v4l2_cropcap *cropcap)
++{
++ struct omap_vout_device *vout = fh;
++ enum v4l2_buf_type type = cropcap->type;
++ struct v4l2_pix_format *pix = &vout->pix;
++
++ cropcap->type = type;
++ if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
++ return -EINVAL;
++
++ /* Width and height are always even */
++ cropcap->bounds.width = pix->width & ~1;
++ cropcap->bounds.height = pix->height & ~1;
++
++ omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
++ cropcap->pixelaspect.numerator = 1;
++ cropcap->pixelaspect.denominator = 1;
++ return 0;
++}
++
++static int vidioc_g_crop(struct file *file, void *fh,
++ struct v4l2_crop *crop)
++{
++ struct omap_vout_device *vout = fh;
++
++ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
++ return -EINVAL;
++ crop->c = vout->crop;
++ return 0;
++}
++
++static int vidioc_s_crop(struct file *file, void *fh,
++ struct v4l2_crop *crop)
++{
++ struct omap_vout_device *vout = fh;
++ int err = -EINVAL;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ struct omap_video_timings *timing;
++
++ if (vout->streaming)
++ return -EBUSY;
++
++ mutex_lock(&vout->lock);
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ if (!ovl->manager || !ovl->manager->device) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++ /* get the display device attached to the overlay */
++ timing = &ovl->manager->device->panel.timings;
++
++ if (rotate_90_or_270(vout)) {
++ vout->fbuf.fmt.height = timing->x_res;
++ vout->fbuf.fmt.width = timing->y_res;
++ } else {
++ vout->fbuf.fmt.height = timing->y_res;
++ vout->fbuf.fmt.width = timing->x_res;
++ }
++
++ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
++ err = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
++ &vout->fbuf, &crop->c);
++ mutex_unlock(&vout->lock);
++ return err;
++ } else {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++}
++
++static int vidioc_queryctrl(struct file *file, void *fh,
++ struct v4l2_queryctrl *ctrl)
++{
++ switch (ctrl->id) {
++ case V4L2_CID_ROTATE:
++ v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
++ break;
++ case V4L2_CID_BG_COLOR:
++ v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0);
++ break;
++ case V4L2_CID_VFLIP:
++ v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
++ default:
++ ctrl->name[0] = '\0';
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
++{
++ struct omap_vout_device *vout = fh;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ROTATE:
++ ctrl->value = vout->control[0].value;
++ return 0;
++ case V4L2_CID_BG_COLOR:
++ {
++ struct omap_overlay_manager_info info;
++ struct omap_overlay *ovl;
++ ovl = vout->vid_info.overlays[0];
++
++ if (!ovl->manager || !ovl->manager->get_manager_info)
++ return -EINVAL;
++
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ ctrl->value = info.default_color;
++ return 0;
++ }
++
++ case V4L2_CID_VFLIP:
++ ctrl->value = vout->control[2].value;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
++{
++ struct omap_vout_device *vout = fh;
++
++ switch (a->id) {
++ case V4L2_CID_ROTATE:
++ {
++ int rotation = a->value;
++
++ mutex_lock(&vout->lock);
++
++ if (rotation &&
++ vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++
++ if ((v4l2_rot_to_dss_rot(rotation, &vout->rotation,
++ vout->mirror))) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++
++ vout->control[0].value = rotation;
++ mutex_unlock(&vout->lock);
++ return 0;
++ }
++ case V4L2_CID_BG_COLOR:
++ {
++ unsigned int color = a->value;
++ struct omap_overlay_manager_info info;
++ struct omap_overlay *ovl;
++ ovl = vout->vid_info.overlays[0];
++
++ mutex_lock(&vout->lock);
++ if (!ovl->manager || !ovl->manager->get_manager_info) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ info.default_color = color;
++ if (ovl->manager->set_manager_info(ovl->manager, &info)) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++
++ vout->control[1].value = color;
++ mutex_unlock(&vout->lock);
++ return 0;
++ }
++ case V4L2_CID_VFLIP:
++ {
++ unsigned int mirror = a->value;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ mutex_lock(&vout->lock);
++
++ if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++ vout->mirror = mirror;
++ vout->control[2].value = mirror;
++ mutex_unlock(&vout->lock);
++ return 0;
++ }
++
++ default:
++ return -EINVAL;
++ }
++
++}
++
++static int vidioc_reqbufs(struct file *file, void *fh,
++ struct v4l2_requestbuffers *req)
++{
++ struct omap_vout_device *vout = fh;
++ struct videobuf_queue *q = &vout->vbq;
++ unsigned int i, num_buffers = 0;
++ int ret = 0;
++ struct videobuf_dmabuf *dmabuf = NULL;
++
++ if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
++ return -EINVAL;
++ /* if memory is not mmp or userptr
++ return error */
++ if ((V4L2_MEMORY_MMAP != req->memory) &&
++ (V4L2_MEMORY_USERPTR != req->memory))
++ return -EINVAL;
++
++ mutex_lock(&vout->lock);
++ /* Cannot be requested when streaming is on */
++ if (vout->streaming) {
++ mutex_unlock(&vout->lock);
++ return -EBUSY;
++ }
++
++ /* If buffers are already allocated free them */
++ if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
++ if (vout->mmap_count) {
++ mutex_unlock(&vout->lock);
++ return -EBUSY;
++ }
++ num_buffers = (vout->vid == OMAP_VIDEO1) ?
++ video1_numbuffers : video2_numbuffers;
++ for (i = num_buffers; i < vout->buffer_allocated; i++) {
++ dmabuf = videobuf_to_dma(q->bufs[i]);
++ omap_vout_free_buffer((u32)dmabuf->vmalloc,
++ dmabuf->bus_addr, vout->buffer_size);
++ vout->buf_virt_addr[i] = 0;
++ vout->buf_phy_addr[i] = 0;
++ }
++ vout->buffer_allocated = num_buffers;
++ videobuf_mmap_free(q);
++ } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
++ if (vout->buffer_allocated) {
++ videobuf_mmap_free(q);
++ for (i = 0; i < vout->buffer_allocated; i++) {
++ kfree(q->bufs[i]);
++ q->bufs[i] = NULL;
++ }
++ vout->buffer_allocated = 0;
++ }
++ }
++
++ /*store the memory type in data structure */
++ vout->memory = req->memory;
++
++ INIT_LIST_HEAD(&vout->dma_queue);
++
++ /* call videobuf_reqbufs api */
++ ret = videobuf_reqbufs(q, req);
++ if (ret < 0) {
++ mutex_unlock(&vout->lock);
++ return ret;
++ }
++
++ vout->buffer_allocated = req->count;
++ for (i = 0; i < req->count; i++) {
++ dmabuf = videobuf_to_dma(q->bufs[i]);
++ dmabuf->vmalloc = (void *) vout->buf_virt_addr[i];
++ dmabuf->bus_addr = (dma_addr_t) vout->buf_phy_addr[i];
++ dmabuf->sglen = 1;
++ }
++ mutex_unlock(&vout->lock);
++ return 0;
++}
++
++static int vidioc_querybuf(struct file *file, void *fh,
++ struct v4l2_buffer *b)
++{
++ struct omap_vout_device *vout = fh;
++
++ return videobuf_querybuf(&vout->vbq, b);
++}
++
++static int vidioc_qbuf(struct file *file, void *fh,
++ struct v4l2_buffer *buffer)
++{
++ struct omap_vout_device *vout = fh;
++ struct videobuf_queue *q = &vout->vbq;
++ int ret = 0;
++
++ if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
++ (buffer->index >= vout->buffer_allocated) ||
++ (q->bufs[buffer->index]->memory != buffer->memory)) {
++ return -EINVAL;
++ }
++ if (V4L2_MEMORY_USERPTR == buffer->memory) {
++ if ((buffer->length < vout->pix.sizeimage) ||
++ (0 == buffer->m.userptr)) {
++ return -EINVAL;
++ }
++ }
++
++ if ((rotation_enabled(vout)) &&
++ vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
++ printk(KERN_WARNING VOUT_NAME
++ "DMA Channel not allocated for Rotation\n");
++ return -EINVAL;
++ }
++
++ ret = videobuf_qbuf(q, buffer);
++ return ret;
++}
++
++static int vidioc_dqbuf(struct file *file, void *fh,
++ struct v4l2_buffer *b)
++{
++ struct omap_vout_device *vout = fh;
++ struct videobuf_queue *q = &vout->vbq;
++ int ret = 0;
++
++ if (!vout->streaming)
++ return -EINVAL;
++
++ if (file->f_flags & O_NONBLOCK)
++ /* Call videobuf_dqbuf for non blocking mode */
++ ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
++ else
++ /* Call videobuf_dqbuf for blocking mode */
++ ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
++ return ret;
++}
++
++static int vidioc_streamon(struct file *file, void *fh,
++ enum v4l2_buf_type i)
++{
++ struct omap_vout_device *vout = fh;
++ struct videobuf_queue *q = &vout->vbq;
++ u32 addr = 0;
++ int r = 0;
++ int t;
++ struct omapvideo_info *ovid = &vout->vid_info;
++ u32 mask = 0;
++
++ mutex_lock(&vout->lock);
++
++ if (vout->streaming) {
++ mutex_unlock(&vout->lock);
++ return -EBUSY;
++ }
++
++ r = videobuf_streamon(q);
++ if (r < 0) {
++ mutex_unlock(&vout->lock);
++ return r;
++ }
++
++ if (list_empty(&vout->dma_queue)) {
++ mutex_unlock(&vout->lock);
++ return -EIO;
++ }
++ /* Get the next frame from the buffer queue */
++ vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
++ struct videobuf_buffer, queue);
++ /* Remove buffer from the buffer queue */
++ list_del(&vout->cur_frm->queue);
++ /* Mark state of the current frame to active */
++ vout->cur_frm->state = VIDEOBUF_ACTIVE;
++ /* Initialize field_id and started member */
++ vout->field_id = 0;
++
++ /* set flag here. Next QBUF will start DMA */
++ vout->streaming = 1;
++
++ vout->first_int = 1;
++
++ if (omap_vout_calculate_offset(vout)) {
++ mutex_unlock(&vout->lock);
++ return -EINVAL;
++ }
++ addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
++ + vout->cropped_offset;
++
++ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
++ DISPC_IRQ_EVSYNC_ODD;
++
++ omap_dispc_register_isr(omap_vout_isr, vout, mask);
++
++ for (t = 0; t < ovid->num_overlays; t++) {
++ struct omap_overlay *ovl = ovid->overlays[t];
++ if (ovl->manager && ovl->manager->device) {
++ struct omap_overlay_info info;
++ ovl->get_overlay_info(ovl, &info);
++ info.enabled = 1;
++ info.paddr = addr;
++ if (ovl->set_overlay_info(ovl, &info))
++ return -EINVAL;
++ }
++ }
++
++ /* First save the configuration in ovelray structure */
++ r = omapvid_init(vout, addr);
++ if (r)
++ printk(KERN_ERR VOUT_NAME "failed to set overlay info\n");
++ /* Enable the pipeline and set the Go bit */
++ r = omapvid_apply_changes(vout);
++ if (r)
++ printk(KERN_ERR VOUT_NAME "failed to change mode\n");
++
++ mutex_unlock(&vout->lock);
++ return r;
++}
++
++static int vidioc_streamoff(struct file *file, void *fh,
++ enum v4l2_buf_type i)
++{
++ struct omap_vout_device *vout = fh;
++ int t, r = 0;
++ struct omapvideo_info *ovid = &vout->vid_info;
++ u32 mask = 0;
++
++ if (!vout->streaming)
++ return -EINVAL;
++
++ vout->streaming = 0;
++ mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
++ DISPC_IRQ_EVSYNC_ODD;
++
++ omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
++
++ for (t = 0; t < ovid->num_overlays; t++) {
++ struct omap_overlay *ovl = ovid->overlays[t];
++ if (ovl->manager && ovl->manager->device) {
++ struct omap_overlay_info info;
++
++ ovl->get_overlay_info(ovl, &info);
++ info.enabled = 0;
++ return ovl->set_overlay_info(ovl, &info);
++ }
++ }
++
++ /* Turn of the pipeline */
++ r = omapvid_apply_changes(vout);
++ if (r) {
++ printk(KERN_ERR VOUT_NAME "failed to change mode\n");
++ return r;
++ }
++ videobuf_streamoff(&vout->vbq);
++ videobuf_queue_cancel(&vout->vbq);
++ return 0;
++}
++
++static int vidioc_s_fbuf(struct file *file, void *fh,
++ struct v4l2_framebuffer *a)
++{
++ struct omap_vout_device *vout = fh;
++ struct omap_overlay_manager_info info;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
++ int enable = 0;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ /* OMAP DSS doesn't support Source and Destination color
++ key together */
++ if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
++ (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
++ return -EINVAL;
++ /* OMAP DSS Doesn't support the Destination color key
++ and alpha blending together */
++ if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
++ (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
++ return -EINVAL;
++
++ if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
++ vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
++ key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
++ } else
++ vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
++
++ if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
++ vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
++ key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
++ } else
++ vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
++
++ if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
++ V4L2_FBUF_FLAG_SRC_CHROMAKEY))
++ enable = 1;
++ else
++ enable = 0;
++ if (ovl->manager && ovl->manager->get_manager_info &&
++ ovl->manager->set_manager_info) {
++
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ info.trans_enabled = enable;
++ info.trans_key_type = key_type;
++ info.trans_key = vout->win.chromakey;
++
++ if (ovl->manager->set_manager_info(ovl->manager, &info))
++ return -EINVAL;
++ }
++ if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
++ vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
++ enable = 1;
++ } else {
++ vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
++ enable = 0;
++ }
++ if (ovl->manager && ovl->manager->get_manager_info &&
++ ovl->manager->set_manager_info) {
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ info.alpha_enabled = enable;
++ if (ovl->manager->set_manager_info(ovl->manager, &info))
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int vidioc_g_fbuf(struct file *file, void *fh,
++ struct v4l2_framebuffer *a)
++{
++ struct omap_vout_device *vout = fh;
++ struct omap_overlay_manager_info info;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++
++ a->flags = 0x0;
++
++ a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
++ | V4L2_FBUF_CAP_SRC_CHROMAKEY;
++
++ if (ovl->manager && ovl->manager->get_manager_info) {
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
++ a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
++ if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
++ a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
++ }
++ if (ovl->manager && ovl->manager->get_manager_info) {
++ ovl->manager->get_manager_info(ovl->manager, &info);
++ if (info.alpha_enabled)
++ a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
++ }
++
++ return 0;
++}
++
++static const struct v4l2_ioctl_ops vout_ioctl_ops = {
++ .vidioc_querycap = vidioc_querycap,
++ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
++ .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
++ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
++ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
++ .vidioc_queryctrl = vidioc_queryctrl,
++ .vidioc_g_ctrl = vidioc_g_ctrl,
++ .vidioc_s_fbuf = vidioc_s_fbuf,
++ .vidioc_g_fbuf = vidioc_g_fbuf,
++ .vidioc_s_ctrl = vidioc_s_ctrl,
++ .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
++ .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
++ .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
++ .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
++ .vidioc_cropcap = vidioc_cropcap,
++ .vidioc_g_crop = vidioc_g_crop,
++ .vidioc_s_crop = vidioc_s_crop,
++ .vidioc_reqbufs = vidioc_reqbufs,
++ .vidioc_querybuf = vidioc_querybuf,
++ .vidioc_qbuf = vidioc_qbuf,
++ .vidioc_dqbuf = vidioc_dqbuf,
++ .vidioc_streamon = vidioc_streamon,
++ .vidioc_streamoff = vidioc_streamoff,
++};
++
++static const struct v4l2_file_operations omap_vout_fops = {
++ .owner = THIS_MODULE,
++ .ioctl = video_ioctl2,
++ .mmap = omap_vout_mmap,
++ .open = omap_vout_open,
++ .release = omap_vout_release,
++};
++
++/* Init functions used during driver intitalization */
++/* Initial setup of video_data */
++static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
++{
++ struct v4l2_pix_format *pix;
++ struct video_device *vfd;
++ struct v4l2_control *control;
++ struct omap_dss_device *display =
++ vout->vid_info.overlays[0]->manager->device;
++
++ /* set the default pix */
++ pix = &vout->pix;
++
++ /* Set the default picture of QVGA */
++ pix->width = QQVGA_WIDTH;
++ pix->height = QQVGA_HEIGHT;
++
++ /* Default pixel format is RGB 5-6-5 */
++ pix->pixelformat = V4L2_PIX_FMT_RGB565;
++ pix->field = V4L2_FIELD_ANY;
++ pix->bytesperline = pix->width * 2;
++ pix->sizeimage = pix->bytesperline * pix->height;
++ pix->priv = 0;
++ pix->colorspace = V4L2_COLORSPACE_JPEG;
++
++ vout->bpp = RGB565_BPP;
++ vout->fbuf.fmt.width = display->panel.timings.x_res;
++ vout->fbuf.fmt.height = display->panel.timings.y_res;
++
++ /* Set the data structures for the overlay parameters*/
++ vout->win.global_alpha = 255;
++ vout->fbuf.flags = 0;
++ vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
++ V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
++ vout->win.chromakey = 0;
++
++ omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
++
++ /*Initialize the control variables for
++ rotation, flipping and background color. */
++ control = vout->control;
++ control[0].id = V4L2_CID_ROTATE;
++ control[0].value = 0;
++ vout->rotation = 0;
++ vout->mirror = 0;
++ vout->control[2].id = V4L2_CID_HFLIP;
++ vout->control[2].value = 0;
++ vout->vrfb_bpp = 2;
++
++ control[1].id = V4L2_CID_BG_COLOR;
++ control[1].value = 0;
++
++ /* initialize the video_device struct */
++ vfd = vout->vfd = video_device_alloc();
++
++ if (!vfd) {
++ printk(KERN_ERR VOUT_NAME ": could not allocate"
++ " video device struct\n");
++ return -ENOMEM;
++ }
++ vfd->release = video_device_release;
++ vfd->ioctl_ops = &vout_ioctl_ops;
++
++ strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
++ vfd->vfl_type = VFL_TYPE_GRABBER;
++
++ /* need to register for a VID_HARDWARE_* ID in videodev.h */
++ vfd->fops = &omap_vout_fops;
++ mutex_init(&vout->lock);
++
++ vfd->minor = -1;
++ return 0;
++
++}
++
++/* Setup video buffers */
++static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
++ int vid_num)
++{
++ struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
++ struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
++ omap2video_device, v4l2_dev);
++ struct omap_vout_device *vout;
++ int i, j, r = 0;
++ int image_width, image_height;
++ unsigned numbuffers;
++ struct video_device *vfd;
++ int static_vrfb_allocation = 0, vrfb_num_bufs = 4;
++
++ vout = vid_dev->vouts[vid_num];
++ vfd = vout->vfd;
++
++ numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
++ vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
++ printk(KERN_INFO VOUT_NAME "Buffer Size = %d\n", vout->buffer_size);
++ for (i = 0; i < numbuffers; i++) {
++ vout->buf_virt_addr[i] =
++ omap_vout_alloc_buffer(vout->buffer_size,
++ (u32 *) &vout->buf_phy_addr[i]);
++ if (!vout->buf_virt_addr[i]) {
++ numbuffers = i;
++ r = -ENOMEM;
++ goto free_buffers;
++ }
++ }
++
++ for (i = 0; i < 4; i++) {
++ if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
++ printk(KERN_INFO VOUT_NAME ": VRFB Region allocation "
++ "for rotation failed\n");
++ r = -ENOMEM;
++ break;
++ }
++ }
++ if (r == -ENOMEM) {
++ for (j = 0; j < i; j++)
++ omap_vrfb_release_ctx(&vout->vrfb_context[j]);
++
++ goto free_buffers;
++ }
++
++ vout->cropped_offset = 0;
++
++ /* Calculate VRFB memory size */
++ /* allocate for worst case size */
++ image_width = VID_MAX_WIDTH / TILE_SIZE;
++ if (VID_MAX_WIDTH % TILE_SIZE)
++ image_width++;
++
++ image_width = image_width * TILE_SIZE;
++ image_height = VID_MAX_HEIGHT / TILE_SIZE;
++
++ if (VID_MAX_HEIGHT % TILE_SIZE)
++ image_height++;
++
++ image_height = image_height * TILE_SIZE;
++ vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
++
++ /*
++ * Request and Initialize DMA, for DMA based VRFB transfer
++ */
++ vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
++ vout->vrfb_dma_tx.dma_ch = -1;
++ vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
++ r = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
++ omap_vout_vrfb_dma_tx_callback,
++ (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
++ if (r < 0) {
++ vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
++ printk(KERN_INFO VOUT_NAME ": DMA Channel not alloted "
++ "for video%d [v4l2]\n", vfd->minor);
++ }
++ init_waitqueue_head(&vout->vrfb_dma_tx.wait);
++
++ /* Allocate VRFB buffers if selected through bootargs */
++ static_vrfb_allocation = (vid_num == 0) ?
++ vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
++
++ /* statically allocated the VRFB buffer is done through
++ commands line aruments */
++ if (static_vrfb_allocation) {
++ if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
++ r = -ENOMEM;
++ goto free_buffers;
++ }
++ vout->vrfb_static_allocation = 1;
++ }
++ return 0;
++
++free_buffers:
++ for (i = 0; i < numbuffers; i++) {
++ omap_vout_free_buffer(vout->buf_virt_addr[i],
++ vout->buf_phy_addr[i], vout->buffer_size);
++ vout->buf_virt_addr[i] = 0;
++ vout->buf_phy_addr[i] = 0;
++ }
++ return r;
++
++}
++
++/* Create video out devices */
++static int __init omap_vout_create_video_devices(struct platform_device *pdev)
++{
++ int r = 0, k;
++ struct omap_vout_device *vout;
++ struct video_device *vfd = NULL;
++ struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
++
++ struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
++ omap2video_device, v4l2_dev);
++
++ for (k = 0; k < pdev->num_resources; k++) {
++
++ vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
++ if (!vout) {
++ printk(KERN_ERR VOUT_NAME
++ ": could not allocate memory\n");
++ return -ENOMEM;
++ }
++
++ memset(vout, 0, sizeof(struct omap_vout_device));
++
++ vout->vid = k;
++ vid_dev->vouts[k] = vout;
++ vout->vid_dev = vid_dev;
++ /* Select video2 if only 1 overlay is controlled by V4L2 */
++ if (pdev->num_resources == 1)
++ vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
++ else
++ /* Else select video1 and video2 one by one. */
++ vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
++ vout->vid_info.num_overlays = 1;
++ vout->vid_info.id = k + 1;
++ vid_dev->num_videos++;
++
++ /* Setup the default configuration for the video devices
++ */
++ if (omap_vout_setup_video_data(vout) != 0) {
++ r = -ENOMEM;
++ goto error;
++ }
++
++ /* Allocate default number of buffers for the video streaming
++ * and reserve the VRFB space for rotation
++ */
++ if (omap_vout_setup_video_bufs(pdev, k) != 0) {
++ r = -ENOMEM;
++ goto error1;
++ }
++
++ /* Register the Video device with V4L2
++ */
++ vfd = vout->vfd;
++ if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) {
++ printk(KERN_ERR VOUT_NAME ": could not register "
++ "Video for Linux device\n");
++ vfd->minor = -1;
++ r = -ENODEV;
++ goto error2;
++ }
++ video_set_drvdata(vfd, vout);
++
++ /* Configure the overlay structure */
++ r = omapvid_init(vid_dev->vouts[k], 0);
++
++ if (r)
++ goto error2;
++ else
++ goto success;
++error2:
++ omap_vout_release_vrfb(vout);
++ omap_vout_free_buffers(vout);
++error1:
++ video_device_release(vfd);
++error:
++ kfree(vout);
++ return r;
++
++success:
++ printk(KERN_INFO VOUT_NAME ": registered and initialized "
++ "video device %d [v4l2]\n", vfd->minor);
++ if (k == (pdev->num_resources - 1))
++ return 0;
++ }
++ return -ENODEV;
++
++}
++/* Driver functions */
++static int omap_vout_remove(struct platform_device *pdev)
++{
++ struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
++ struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
++ omap2video_device, v4l2_dev);
++ int k;
++
++ v4l2_device_unregister(v4l2_dev);
++ for (k = 0; k < pdev->num_resources; k++)
++ omap_vout_cleanup_device(vid_dev->vouts[k]);
++
++ for (k = 0; k < vid_dev->num_displays; k++) {
++ if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
++ vid_dev->displays[k]->disable(vid_dev->displays[k]);
++
++ omap_dss_put_device(vid_dev->displays[k]);
++ }
++ kfree(vid_dev);
++ return 0;
++}
++
++static int __init omap_vout_probe(struct platform_device *pdev)
++{
++ int r = 0, i;
++ struct omap2video_device *vid_dev = NULL;
++ struct omap_overlay *ovl;
++ struct omap_dss_device *def_display;
++ struct omap_dss_device *dssdev;
++
++ if (pdev->num_resources == 0) {
++ dev_err(&pdev->dev, "probed for an unknown device\n");
++ r = -ENODEV;
++ return r;
++ }
++
++ vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
++ if (vid_dev == NULL) {
++ r = -ENOMEM;
++ return r;
++ }
++
++ vid_dev->num_displays = 0;
++ dssdev = NULL;
++ for_each_dss_dev(dssdev) {
++ omap_dss_get_device(dssdev);
++ vid_dev->displays[vid_dev->num_displays++] = dssdev;
++ }
++
++ if (vid_dev->num_displays == 0) {
++ dev_err(&pdev->dev, "no displays\n");
++ r = -EINVAL;
++ goto error0;
++ }
++
++ vid_dev->num_overlays = omap_dss_get_num_overlays();
++ for (i = 0; i < vid_dev->num_overlays; i++)
++ vid_dev->overlays[i] = omap_dss_get_overlay(i);
++
++ vid_dev->num_managers = omap_dss_get_num_overlay_managers();
++ for (i = 0; i < vid_dev->num_managers; i++)
++ vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
++
++ /* Get the Video1 overlay and video2 overlay.
++ * Setup the Display attached to that overlays
++ */
++ for (i = 1; i < 3; i++) {
++ ovl = omap_dss_get_overlay(i);
++ if (ovl->manager && ovl->manager->device) {
++ def_display = ovl->manager->device;
++ } else {
++ dev_warn(&pdev->dev, "cannot find display\n");
++ def_display = NULL;
++ }
++ if (def_display) {
++ r = def_display->enable(def_display);
++ if (r) {
++ /* Here we are not considering a error
++ * as display may be enabled by frame
++ * buffer driver
++ */
++ dev_warn(&pdev->dev,
++ "'%s' Display already enabled\n",
++ def_display->name);
++ }
++ /* set the update mode */
++ if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
++#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
++ if (def_display->enable_te)
++ def_display->enable_te(def_display, 1);
++ if (def_display->set_update_mode)
++ def_display->set_update_mode(def_display,
++ OMAP_DSS_UPDATE_AUTO);
++#else /* MANUAL_UPDATE */
++ if (def_display->enable_te)
++ def_display->enable_te(def_display, 0);
++ if (def_display->set_update_mode)
++ def_display->set_update_mode(def_display,
++ OMAP_DSS_UPDATE_MANUAL);
++#endif
++ } else {
++ if (def_display->set_update_mode)
++ def_display->set_update_mode(def_display,
++ OMAP_DSS_UPDATE_AUTO);
++ }
++ }
++ }
++
++ if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
++ printk(KERN_ERR VOUT_NAME "v4l2_device_register failed\n");
++ return -ENODEV;
++ }
++
++ r = omap_vout_create_video_devices(pdev);
++ if (r)
++ goto error0;
++
++ for (i = 0; i < vid_dev->num_displays; i++) {
++ struct omap_dss_device *display = vid_dev->displays[i];
++
++ if (display->update)
++ display->update(display, 0, 0,
++ display->panel.timings.x_res,
++ display->panel.timings.y_res);
++ }
++ return 0;
++
++error0:
++ kfree(vid_dev);
++ return r;
++}
++
++static struct platform_driver omap_vout_driver = {
++ .driver = {
++ .name = VOUT_NAME,
++ },
++ .probe = omap_vout_probe,
++ .remove = omap_vout_remove,
++};
++
++void omap_vout_isr(void *arg, unsigned int irqstatus)
++{
++ int r;
++ struct timeval timevalue;
++ struct omap_vout_device *vout =
++ (struct omap_vout_device *) arg;
++ u32 addr, fid;
++ struct omapvideo_info *ovid;
++ struct omap_overlay *ovl;
++ struct omap_dss_device *cur_display;
++
++ if (!vout->streaming)
++ return;
++
++ ovid = &vout->vid_info;
++ ovl = ovid->overlays[0];
++ /* get the display device attached to the overlay */
++ if (!ovl->manager || !ovl->manager->device)
++ return;
++ cur_display = ovl->manager->device;
++
++ spin_lock(&vout->vbq_lock);
++ do_gettimeofday(&timevalue);
++ if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) {
++ if (!(irqstatus & DISPC_IRQ_VSYNC))
++ return;
++ if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
++ vout->cur_frm->ts = timevalue;
++ vout->cur_frm->state = VIDEOBUF_DONE;
++ wake_up_interruptible(&vout->cur_frm->done);
++ vout->cur_frm = vout->next_frm;
++ }
++ vout->first_int = 0;
++ if (list_empty(&vout->dma_queue)) {
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++
++ vout->next_frm = list_entry(vout->dma_queue.next,
++ struct videobuf_buffer, queue);
++ list_del(&vout->next_frm->queue);
++
++ vout->next_frm->state = VIDEOBUF_ACTIVE;
++
++ addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
++ + vout->cropped_offset;
++
++ /* First save the configuration in ovelray structure */
++ r = omapvid_init(vout, addr);
++ if (r)
++ printk(KERN_ERR VOUT_NAME "failed to set overlay info\n");
++ /* Enable the pipeline and set the Go bit */
++ r = omapvid_apply_changes(vout);
++ if (r)
++ printk(KERN_ERR VOUT_NAME "failed to change mode\n");
++ } else {
++
++ if (vout->first_int) {
++ vout->first_int = 0;
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++ if (irqstatus & DISPC_IRQ_EVSYNC_ODD) {
++ fid = 1;
++ } else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) {
++ fid = 0;
++ } else {
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++ vout->field_id ^= 1;
++ if (fid != vout->field_id) {
++ if (0 == fid)
++ vout->field_id = fid;
++
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++ if (0 == fid) {
++ if (vout->cur_frm == vout->next_frm) {
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++ vout->cur_frm->ts = timevalue;
++ vout->cur_frm->state = VIDEOBUF_DONE;
++ wake_up_interruptible(&vout->cur_frm->done);
++ vout->cur_frm = vout->next_frm;
++ } else if (1 == fid) {
++ if (list_empty(&vout->dma_queue) ||
++ (vout->cur_frm != vout->next_frm)) {
++ spin_unlock(&vout->vbq_lock);
++ return;
++ }
++ vout->next_frm = list_entry(vout->dma_queue.next,
++ struct videobuf_buffer, queue);
++ list_del(&vout->next_frm->queue);
++
++ vout->next_frm->state = VIDEOBUF_ACTIVE;
++ addr = (unsigned long)
++ vout->queued_buf_addr[vout->next_frm->i] +
++ vout->cropped_offset;
++ /* First save the configuration in ovelray structure */
++ r = omapvid_init(vout, addr);
++ if (r)
++ printk(KERN_ERR VOUT_NAME
++ "failed to set overlay info\n");
++ /* Enable the pipeline and set the Go bit */
++ r = omapvid_apply_changes(vout);
++ if (r)
++ printk(KERN_ERR VOUT_NAME
++ "failed to change mode\n");
++ }
++
++ }
++ spin_unlock(&vout->vbq_lock);
++}
++
++static void omap_vout_cleanup_device(struct omap_vout_device *vout)
++{
++ struct video_device *vfd;
++
++ if (!vout)
++ return;
++ vfd = vout->vfd;
++
++ if (vfd) {
++ if (vfd->minor == -1) {
++ /*
++ * The device was never registered, so release the
++ * video_device struct directly.
++ */
++ video_device_release(vfd);
++ } else {
++ /*
++ * The unregister function will release the video_device
++ * struct as well as unregistering it.
++ */
++ video_unregister_device(vfd);
++ }
++ }
++
++ omap_vout_release_vrfb(vout);
++
++ omap_vout_free_buffers(vout);
++ /* Free the VRFB buffer if allocated
++ * init time
++ */
++ if (vout->vrfb_static_allocation)
++ omap_vout_free_vrfb_buffers(vout);
++
++ kfree(vout);
++}
++
++static int __init omap_vout_init(void)
++{
++
++ if (platform_driver_register(&omap_vout_driver) != 0) {
++ printk(KERN_ERR VOUT_NAME ": could not register \
++ Video driver\n");
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static void omap_vout_cleanup(void)
++{
++ platform_driver_unregister(&omap_vout_driver);
++}
++
++late_initcall(omap_vout_init);
++module_exit(omap_vout_cleanup);
+diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h
+new file mode 100644
+index 0000000..57743e5
+--- /dev/null
++++ b/drivers/media/video/omap/omap_voutdef.h
+@@ -0,0 +1,148 @@
++/*
++ * drivers/media/video/omap/omap_voutdef.h
++ *
++ * Copyright (C) 2009 Texas Instruments.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#ifndef OMAP_VOUTDEF_H
++#define OMAP_VOUTDEF_H
++
++#include <mach/display.h>
++
++#define YUYV_BPP 2
++#define RGB565_BPP 2
++#define RGB24_BPP 3
++#define RGB32_BPP 4
++#define TILE_SIZE 32
++#define YUYV_VRFB_BPP 2
++#define RGB_VRFB_BPP 1
++#define MAX_CID 3
++#define MAC_VRFB_CTXS 4
++#define MAX_VOUT_DEV 2
++#define MAX_OVLS 3
++#define MAX_DISPLAYS 3
++#define MAX_MANAGERS 3
++
++/* Enum for Rotation
++ * DSS understands rotation in 0, 1, 2, 3 context
++ * while V4L2 driver understands it as 0, 90, 180, 270
++ */
++enum dss_rotation {
++ dss_rotation_0_degree = 0,
++ dss_rotation_90_degree = 1,
++ dss_rotation_180_degree = 2,
++ dss_rotation_270_degree = 3,
++};
++/*
++ * This structure is used to store the DMA transfer parameters
++ * for VRFB hidden buffer
++ */
++struct vid_vrfb_dma {
++ int dev_id;
++ int dma_ch;
++ int req_status;
++ int tx_status;
++ wait_queue_head_t wait;
++};
++
++struct omapvideo_info {
++ int id;
++ int num_overlays;
++ struct omap_overlay *overlays[MAX_OVLS];
++};
++
++struct omap2video_device {
++ struct mutex mtx;
++
++ int state;
++
++ struct v4l2_device v4l2_dev;
++ int num_videos;
++ struct omap_vout_device *vouts[MAX_VOUT_DEV];
++
++ int num_displays;
++ struct omap_dss_device *displays[MAX_DISPLAYS];
++ int num_overlays;
++ struct omap_overlay *overlays[MAX_OVLS];
++ int num_managers;
++ struct omap_overlay_manager *managers[MAX_MANAGERS];
++};
++
++/* per-device data structure */
++struct omap_vout_device {
++
++ struct omapvideo_info vid_info;
++ struct video_device *vfd;
++ struct omap2video_device *vid_dev;
++ int vid;
++ int opened;
++
++ /* we don't allow to change image fmt/size once buffer has
++ * been allocated
++ */
++ int buffer_allocated;
++ /* allow to reuse previously allocated buffer which is big enough */
++ int buffer_size;
++ /* keep buffer info across opens */
++ unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
++ unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
++ enum omap_color_mode dss_mode;
++
++ /* we don't allow to request new buffer when old buffers are
++ * still mmaped
++ */
++ int mmap_count;
++
++ spinlock_t vbq_lock; /* spinlock for videobuf queues */
++ unsigned long field_count; /* field counter for videobuf_buffer */
++
++ /* non-NULL means streaming is in progress. */
++ bool streaming;
++
++ struct v4l2_pix_format pix;
++ struct v4l2_rect crop;
++ struct v4l2_window win;
++ struct v4l2_framebuffer fbuf;
++
++ /* Lock to protect the shared data structures in ioctl */
++ struct mutex lock;
++
++ /* V4L2 control structure for different control id */
++ struct v4l2_control control[MAX_CID];
++ enum dss_rotation rotation;
++ bool mirror;
++ int flicker_filter;
++ /* V4L2 control structure for different control id */
++
++ int bpp; /* bytes per pixel */
++ int vrfb_bpp; /* bytes per pixel with respect to VRFB */
++
++ struct vid_vrfb_dma vrfb_dma_tx;
++ unsigned int smsshado_phy_addr[MAC_VRFB_CTXS];
++ unsigned int smsshado_virt_addr[MAC_VRFB_CTXS];
++ struct vrfb vrfb_context[MAC_VRFB_CTXS];
++ bool vrfb_static_allocation;
++ unsigned int smsshado_size;
++ unsigned char pos;
++
++ int ps, vr_ps, line_length, first_int, field_id;
++ enum v4l2_memory memory;
++ struct videobuf_buffer *cur_frm, *next_frm;
++ struct list_head dma_queue;
++ u8 *queued_buf_addr[VIDEO_MAX_FRAME];
++ u32 cropped_offset;
++ s32 tv_field1_offset;
++ void *isr_handle;
++
++ /* Buffer queue variables */
++ struct omap_vout_device *vout;
++ enum v4l2_buf_type type;
++ struct videobuf_queue vbq;
++ int io_allowed;
++
++};
++#endif /* ifndef OMAP_VOUTDEF_H */
+diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c
+new file mode 100644
+index 0000000..bce5072
+--- /dev/null
++++ b/drivers/media/video/omap/omap_voutlib.c
+@@ -0,0 +1,258 @@
++/*
++ * drivers/media/video/omap/omap_voutlib.c
++ *
++ * Copyright (C) 2005-2009 Texas Instruments.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ *
++ * Based on the OMAP2 camera driver
++ * Video-for-Linux (Version 2) camera capture driver for
++ * the OMAP24xx camera controller.
++ *
++ * Author: Andy Lowe (source@mvista.com)
++ *
++ * Copyright (C) 2004 MontaVista Software, Inc.
++ * Copyright (C) 2009 Texas Instruments.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/videodev2.h>
++
++MODULE_AUTHOR("Texas Instruments.");
++MODULE_DESCRIPTION("OMAP Video library");
++MODULE_LICENSE("GPL");
++
++/* Return the default overlay cropping rectangle in crop given the image
++ * size in pix and the video display size in fbuf. The default
++ * cropping rectangle is the largest rectangle no larger than the capture size
++ * that will fit on the display. The default cropping rectangle is centered in
++ * the image. All dimensions and offsets are rounded down to even numbers.
++ */
++void omap_vout_default_crop(struct v4l2_pix_format *pix,
++ struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop)
++{
++ crop->width = (pix->width < fbuf->fmt.width) ?
++ pix->width : fbuf->fmt.width;
++ crop->height = (pix->height < fbuf->fmt.height) ?
++ pix->height : fbuf->fmt.height;
++ crop->width &= ~1;
++ crop->height &= ~1;
++ crop->left = ((pix->width - crop->width) >> 1) & ~1;
++ crop->top = ((pix->height - crop->height) >> 1) & ~1;
++}
++EXPORT_SYMBOL_GPL(omap_vout_default_crop);
++
++/* Given a new render window in new_win, adjust the window to the
++ * nearest supported configuration. The adjusted window parameters are
++ * returned in new_win.
++ * Returns zero if succesful, or -EINVAL if the requested window is
++ * impossible and cannot reasonably be adjusted.
++ */
++int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
++ struct v4l2_window *new_win)
++{
++ struct v4l2_rect try_win;
++
++ /* make a working copy of the new_win rectangle */
++ try_win = new_win->w;
++
++ /* adjust the preview window so it fits on the display by clipping any
++ * offscreen areas
++ */
++ if (try_win.left < 0) {
++ try_win.width += try_win.left;
++ try_win.left = 0;
++ }
++ if (try_win.top < 0) {
++ try_win.height += try_win.top;
++ try_win.top = 0;
++ }
++ try_win.width = (try_win.width < fbuf->fmt.width) ?
++ try_win.width : fbuf->fmt.width;
++ try_win.height = (try_win.height < fbuf->fmt.height) ?
++ try_win.height : fbuf->fmt.height;
++ if (try_win.left + try_win.width > fbuf->fmt.width)
++ try_win.width = fbuf->fmt.width - try_win.left;
++ if (try_win.top + try_win.height > fbuf->fmt.height)
++ try_win.height = fbuf->fmt.height - try_win.top;
++ try_win.width &= ~1;
++ try_win.height &= ~1;
++
++ if (try_win.width <= 0 || try_win.height <= 0)
++ return -EINVAL;
++
++ /* We now have a valid preview window, so go with it */
++ new_win->w = try_win;
++ new_win->field = V4L2_FIELD_ANY;
++ return 0;
++}
++EXPORT_SYMBOL_GPL(omap_vout_try_window);
++
++/* Given a new render window in new_win, adjust the window to the
++ * nearest supported configuration. The image cropping window in crop
++ * will also be adjusted if necessary. Preference is given to keeping the
++ * the window as close to the requested configuration as possible. If
++ * successful, new_win, vout->win, and crop are updated.
++ * Returns zero if succesful, or -EINVAL if the requested preview window is
++ * impossible and cannot reasonably be adjusted.
++ */
++int omap_vout_new_window(struct v4l2_rect *crop,
++ struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
++ struct v4l2_window *new_win)
++{
++ int err;
++
++ err = omap_vout_try_window(fbuf, new_win);
++ if (err)
++ return err;
++
++ /* update our preview window */
++ win->w = new_win->w;
++ win->field = new_win->field;
++ win->chromakey = new_win->chromakey;
++
++ /* adjust the cropping window to allow for resizing limitations */
++ if ((crop->height/win->w.height) >= 4) {
++ /* The maximum vertical downsizing ratio is 4:1 */
++ crop->height = win->w.height * 4;
++ }
++ if ((crop->width/win->w.width) >= 4) {
++ /* The maximum horizontal downsizing ratio is 4:1 */
++ crop->width = win->w.width * 4;
++ }
++ return 0;
++}
++EXPORT_SYMBOL_GPL(omap_vout_new_window);
++
++/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to
++ * the nearest supported configuration. The image render window in win will
++ * also be adjusted if necessary. The preview window is adjusted such that the
++ * horizontal and vertical rescaling ratios stay constant. If the render
++ * window would fall outside the display boundaries, the cropping rectangle
++ * will also be adjusted to maintain the rescaling ratios. If successful, crop
++ * and win are updated.
++ * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is
++ * impossible and cannot reasonably be adjusted.
++ */
++int omap_vout_new_crop(struct v4l2_pix_format *pix,
++ struct v4l2_rect *crop, struct v4l2_window *win,
++ struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop)
++{
++ struct v4l2_rect try_crop;
++ unsigned long vresize, hresize;
++
++ /* make a working copy of the new_crop rectangle */
++ try_crop = *new_crop;
++
++ /* adjust the cropping rectangle so it fits in the image */
++ if (try_crop.left < 0) {
++ try_crop.width += try_crop.left;
++ try_crop.left = 0;
++ }
++ if (try_crop.top < 0) {
++ try_crop.height += try_crop.top;
++ try_crop.top = 0;
++ }
++ try_crop.width = (try_crop.width < pix->width) ?
++ try_crop.width : pix->width;
++ try_crop.height = (try_crop.height < pix->height) ?
++ try_crop.height : pix->height;
++ if (try_crop.left + try_crop.width > pix->width)
++ try_crop.width = pix->width - try_crop.left;
++ if (try_crop.top + try_crop.height > pix->height)
++ try_crop.height = pix->height - try_crop.top;
++ try_crop.width &= ~1;
++ try_crop.height &= ~1;
++ if (try_crop.width <= 0 || try_crop.height <= 0)
++ return -EINVAL;
++
++ if (crop->height != win->w.height) {
++ /* If we're resizing vertically, we can't support a crop width
++ * wider than 768 pixels.
++ */
++ if (try_crop.width > 768)
++ try_crop.width = 768;
++ }
++ /* vertical resizing */
++ vresize = (1024 * crop->height) / win->w.height;
++ if (vresize > 4096)
++ vresize = 4096;
++ else if (vresize == 0)
++ vresize = 1;
++ win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
++ if (win->w.height == 0)
++ win->w.height = 2;
++ if (win->w.height + win->w.top > fbuf->fmt.height) {
++ /* We made the preview window extend below the bottom of the
++ * display, so clip it to the display boundary and resize the
++ * cropping height to maintain the vertical resizing ratio.
++ */
++ win->w.height = (fbuf->fmt.height - win->w.top) & ~1;
++ if (try_crop.height == 0)
++ try_crop.height = 2;
++ }
++ /* horizontal resizing */
++ hresize = (1024 * crop->width) / win->w.width;
++ if (hresize > 4096)
++ hresize = 4096;
++ else if (hresize == 0)
++ hresize = 1;
++ win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
++ if (win->w.width == 0)
++ win->w.width = 2;
++ if (win->w.width + win->w.left > fbuf->fmt.width) {
++ /* We made the preview window extend past the right side of the
++ * display, so clip it to the display boundary and resize the
++ * cropping width to maintain the horizontal resizing ratio.
++ */
++ win->w.width = (fbuf->fmt.width - win->w.left) & ~1;
++ if (try_crop.width == 0)
++ try_crop.width = 2;
++ }
++
++ /* Check for resizing constraints */
++ if ((try_crop.height/win->w.height) >= 4) {
++ /* The maximum vertical downsizing ratio is 4:1 */
++ try_crop.height = win->w.height * 4;
++ }
++ if ((try_crop.width/win->w.width) >= 4) {
++ /* The maximum horizontal downsizing ratio is 4:1 */
++ try_crop.width = win->w.width * 4;
++ }
++
++ /* update our cropping rectangle and we're done */
++ *crop = try_crop;
++ return 0;
++}
++EXPORT_SYMBOL_GPL(omap_vout_new_crop);
++
++/* Given a new format in pix and fbuf, crop and win
++ * structures are initialized to default values. crop
++ * is initialized to the largest window size that will fit on the display. The
++ * crop window is centered in the image. win is initialized to
++ * the same size as crop and is centered on the display.
++ * All sizes and offsets are constrained to be even numbers.
++ */
++void omap_vout_new_format(struct v4l2_pix_format *pix,
++ struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
++ struct v4l2_window *win)
++{
++ /* crop defines the preview source window in the image capture
++ * buffer
++ */
++ omap_vout_default_crop(pix, fbuf, crop);
++
++ /* win defines the preview target window on the display */
++ win->w.width = crop->width;
++ win->w.height = crop->height;
++ win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;
++ win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;
++}
++EXPORT_SYMBOL_GPL(omap_vout_new_format);
++
+diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/video/omap/omap_voutlib.h
+new file mode 100644
+index 0000000..8ef6e25
+--- /dev/null
++++ b/drivers/media/video/omap/omap_voutlib.h
+@@ -0,0 +1,34 @@
++/*
++ * drivers/media/video/omap/omap_voutlib.h
++ *
++ * Copyright (C) 2009 Texas Instruments.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ *
++ */
++
++#ifndef OMAP_VOUTLIB_H
++#define OMAP_VOUTLIB_H
++
++extern void omap_vout_default_crop(struct v4l2_pix_format *pix,
++ struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop);
++
++extern int omap_vout_new_crop(struct v4l2_pix_format *pix,
++ struct v4l2_rect *crop, struct v4l2_window *win,
++ struct v4l2_framebuffer *fbuf,
++ const struct v4l2_rect *new_crop);
++
++extern int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
++ struct v4l2_window *new_win);
++
++extern int omap_vout_new_window(struct v4l2_rect *crop,
++ struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
++ struct v4l2_window *new_win);
++
++extern void omap_vout_new_format(struct v4l2_pix_format *pix,
++ struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
++ struct v4l2_window *win);
++#endif /* #ifndef OMAP_LIB_H */
++
+--
+1.6.2.4
+
diff --git a/recipes/linux/linux-omap-2.6.31/expansion-boards/tincantools-zippy.patch b/recipes/linux/linux-omap-2.6.31/expansion-boards/tincantools-zippy.patch
new file mode 100644
index 0000000000..71d96bcc86
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/expansion-boards/tincantools-zippy.patch
@@ -0,0 +1,122 @@
+diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
+index 55db61e..1172887 100644
+--- a/arch/arm/mach-omap2/board-omap3beagle.c
++++ b/arch/arm/mach-omap2/board-omap3beagle.c
+@@ -21,6 +21,7 @@
+ #include <linux/io.h>
+ #include <linux/leds.h>
+ #include <linux/gpio.h>
++#include <linux/irq.h>
+ #include <linux/input.h>
+ #include <linux/gpio_keys.h>
+
+@@ -56,6 +57,49 @@
+
+ #define NAND_BLOCK_SIZE SZ_128K
+
++#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
++
++#include <mach/mcspi.h>
++#include <linux/spi/spi.h>
++
++#define OMAP3BEAGLE_GPIO_ENC28J60_IRQ 157
++
++static struct omap2_mcspi_device_config enc28j60_spi_chip_info = {
++ .turbo_mode = 0,
++ .single_channel = 1, /* 0: slave, 1: master */
++};
++
++static struct spi_board_info omap3beagle_spi_board_info[] __initdata = {
++ {
++ .modalias = "enc28j60",
++ .bus_num = 4,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .controller_data = &enc28j60_spi_chip_info,
++ },
++};
++
++static void __init omap3beagle_enc28j60_init(void)
++{
++ if ((gpio_request(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, "ENC28J60_IRQ") == 0) &&
++ (gpio_direction_input(OMAP3BEAGLE_GPIO_ENC28J60_IRQ) == 0)) {
++ gpio_export(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, 0);
++ omap3beagle_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ);
++ set_irq_type(omap3beagle_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING);
++ } else {
++ printk(KERN_ERR "could not obtain gpio for ENC28J60_IRQ\n");
++ return;
++ }
++
++ spi_register_board_info(omap3beagle_spi_board_info,
++ ARRAY_SIZE(omap3beagle_spi_board_info));
++}
++
++#else
++static inline void __init omap3beagle_enc28j60_init(void) { return; }
++#endif
++
++
+ static struct mtd_partition omap3beagle_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+@@ -126,6 +170,14 @@ static struct twl4030_hsmmc_info mmc[] = {
+ .wires = 8,
+ .gpio_wp = 29,
+ },
++ {
++ .mmc = 2,
++ .wires = 4,
++ .gpio_wp = 141,
++ .gpio_cd = 162,
++ .transceiver = true,
++ .ocr_mask = 0x00100000, /* 3.3V */
++ },
+ {} /* Terminator */
+ };
+
+@@ -289,7 +341,7 @@ static struct twl4030_platform_data beagle_twldata = {
+ .vpll2 = &beagle_vpll2,
+ };
+
+-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
++static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("twl4030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+@@ -298,10 +350,24 @@ static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
+ },
+ };
+
++#if defined(CONFIG_RTC_DRV_DS1307) || \
++ defined(CONFIG_RTC_DRV_DS1307_MODULE)
++
++static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {
++ {
++ I2C_BOARD_INFO("ds1307", 0x68),
++ },
++};
++#else
++static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {};
++#endif
++
+ static int __init omap3_beagle_i2c_init(void)
+ {
+- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
+- ARRAY_SIZE(beagle_i2c_boardinfo));
++ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo,
++ ARRAY_SIZE(beagle_i2c1_boardinfo));
++ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo,
++ ARRAY_SIZE(beagle_i2c2_boardinfo));
+ /* Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz */
+ omap_register_i2c_bus(3, 100, NULL, 0);
+@@ -512,6 +578,8 @@ static void __init omap3_beagle_init(void)
+
+ omap_cfg_reg(J25_34XX_GPIO170);
+
++ omap3beagle_enc28j60_init();
++
+ usb_musb_init();
+ usb_ehci_init();
+ omap3beagle_flash_init();
diff --git a/recipes/linux/linux-omap-2.6.31/madc/madc-driver.patch b/recipes/linux/linux-omap-2.6.31/madc/madc-driver.patch
new file mode 100644
index 0000000000..63f742e3f9
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/madc/madc-driver.patch
@@ -0,0 +1,708 @@
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 491ac0f..3605b5d 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -108,6 +108,27 @@ config TWL4030_CORE
+ high speed USB OTG transceiver, an audio codec (on most
+ versions) and many other features.
+
++config TWL4030_MADC
++ tristate "TWL4030 MADC Driver"
++ depends on TWL4030_CORE
++ help
++ The TWL4030 Monitoring ADC driver enables the host
++ processor to monitor analog signals using analog-to-digital
++ conversions on the input source. TWL4030 MADC provides the
++ following features:
++ - Single 10-bit ADC with successive approximation register (SAR) conversion;
++ - Analog multiplexer for 16 inputs;
++ - Seven (of the 16) inputs are freely available;
++ - Battery voltage monitoring;
++ - Concurrent conversion request management;
++ - Interrupt signal to Primary Interrupt Handler;
++ - Averaging feature;
++ - Selective enable/disable of the averaging feature.
++
++ Say 'y' here to statically link this module into the kernel or 'm'
++ to build it as a dinamically loadable module. The module will be
++ called twl4030-madc.ko
++
+ config MFD_TMIO
+ bool
+ default n
+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
+index 6f8a9a1..e8d0ee6 100644
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -23,6 +23,7 @@ obj-$(CONFIG_TPS65010) += tps65010.o
+ obj-$(CONFIG_MENELAUS) += menelaus.o
+
+ obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o twl4030-irq.o
++obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
+
+ obj-$(CONFIG_MFD_CORE) += mfd-core.o
+
+diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
+new file mode 100644
+index 0000000..551c932
+--- /dev/null
++++ b/drivers/mfd/twl4030-madc.c
+@@ -0,0 +1,526 @@
++/*
++ * TWL4030 MADC module driver
++ *
++ * Copyright (C) 2008 Nokia Corporation
++ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++#include <linux/miscdevice.h>
++#include <linux/i2c/twl4030.h>
++#include <linux/i2c/twl4030-madc.h>
++
++#include <asm/uaccess.h>
++
++#define TWL4030_MADC_PFX "twl4030-madc: "
++
++struct twl4030_madc_data {
++ struct device *dev;
++ struct mutex lock;
++ struct work_struct ws;
++ struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
++ int imr;
++ int isr;
++};
++
++static struct twl4030_madc_data *the_madc;
++
++static
++const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
++ [TWL4030_MADC_RT] = {
++ .sel = TWL4030_MADC_RTSELECT_LSB,
++ .avg = TWL4030_MADC_RTAVERAGE_LSB,
++ .rbase = TWL4030_MADC_RTCH0_LSB,
++ },
++ [TWL4030_MADC_SW1] = {
++ .sel = TWL4030_MADC_SW1SELECT_LSB,
++ .avg = TWL4030_MADC_SW1AVERAGE_LSB,
++ .rbase = TWL4030_MADC_GPCH0_LSB,
++ .ctrl = TWL4030_MADC_CTRL_SW1,
++ },
++ [TWL4030_MADC_SW2] = {
++ .sel = TWL4030_MADC_SW2SELECT_LSB,
++ .avg = TWL4030_MADC_SW2AVERAGE_LSB,
++ .rbase = TWL4030_MADC_GPCH0_LSB,
++ .ctrl = TWL4030_MADC_CTRL_SW2,
++ },
++};
++
++static int twl4030_madc_read(struct twl4030_madc_data *madc, u8 reg)
++{
++ int ret;
++ u8 val;
++
++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MADC, &val, reg);
++ if (ret) {
++ dev_dbg(madc->dev, "unable to read register 0x%X\n", reg);
++ return ret;
++ }
++
++ return val;
++}
++
++static void twl4030_madc_write(struct twl4030_madc_data *madc, u8 reg, u8 val)
++{
++ int ret;
++
++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, val, reg);
++ if (ret)
++ dev_err(madc->dev, "unable to write register 0x%X\n", reg);
++}
++
++static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
++{
++ u8 msb, lsb;
++
++ /* For each ADC channel, we have MSB and LSB register pair. MSB address
++ * is always LSB address+1. reg parameter is the addr of LSB register */
++ msb = twl4030_madc_read(madc, reg + 1);
++ lsb = twl4030_madc_read(madc, reg);
++
++ return (int)(((msb << 8) | lsb) >> 6);
++}
++
++static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
++ u8 reg_base, u16 channels, int *buf)
++{
++ int count = 0;
++ u8 reg, i;
++
++ if (unlikely(!buf))
++ return 0;
++
++ for (i = 0; i < TWL4030_MADC_MAX_CHANNELS; i++) {
++ if (channels & (1<<i)) {
++ reg = reg_base + 2*i;
++ buf[i] = twl4030_madc_channel_raw_read(madc, reg);
++ count++;
++ }
++ }
++ return count;
++}
++
++static void twl4030_madc_enable_irq(struct twl4030_madc_data *madc, int id)
++{
++ u8 val;
++
++ val = twl4030_madc_read(madc, madc->imr);
++ val &= ~(1 << id);
++ twl4030_madc_write(madc, madc->imr, val);
++}
++
++static void twl4030_madc_disable_irq(struct twl4030_madc_data *madc, int id)
++{
++ u8 val;
++
++ val = twl4030_madc_read(madc, madc->imr);
++ val |= (1 << id);
++ twl4030_madc_write(madc, madc->imr, val);
++}
++
++static irqreturn_t twl4030_madc_irq_handler(int irq, void *_madc)
++{
++ struct twl4030_madc_data *madc = _madc;
++ u8 isr_val, imr_val;
++ int i;
++
++#ifdef CONFIG_LOCKDEP
++ /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
++ * we don't want and can't tolerate. Although it might be
++ * friendlier not to borrow this thread context...
++ */
++ local_irq_enable();
++#endif
++
++ /* Use COR to ack interrupts since we have no shared IRQs in ISRx */
++ isr_val = twl4030_madc_read(madc, madc->isr);
++ imr_val = twl4030_madc_read(madc, madc->imr);
++
++ isr_val &= ~imr_val;
++
++ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
++
++ if (!(isr_val & (1<<i)))
++ continue;
++
++ twl4030_madc_disable_irq(madc, i);
++ madc->requests[i].result_pending = 1;
++ }
++
++ schedule_work(&madc->ws);
++
++ return IRQ_HANDLED;
++}
++
++static void twl4030_madc_work(struct work_struct *ws)
++{
++ const struct twl4030_madc_conversion_method *method;
++ struct twl4030_madc_data *madc;
++ struct twl4030_madc_request *r;
++ int len, i;
++
++ madc = container_of(ws, struct twl4030_madc_data, ws);
++ mutex_lock(&madc->lock);
++
++ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
++
++ r = &madc->requests[i];
++
++ /* No pending results for this method, move to next one */
++ if (!r->result_pending)
++ continue;
++
++ method = &twl4030_conversion_methods[r->method];
++
++ /* Read results */
++ len = twl4030_madc_read_channels(madc, method->rbase,
++ r->channels, r->rbuf);
++
++ /* Return results to caller */
++ if (r->func_cb != NULL) {
++ r->func_cb(len, r->channels, r->rbuf);
++ r->func_cb = NULL;
++ }
++
++ /* Free request */
++ r->result_pending = 0;
++ r->active = 0;
++ }
++
++ mutex_unlock(&madc->lock);
++}
++
++static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
++ struct twl4030_madc_request *req)
++{
++ struct twl4030_madc_request *p;
++
++ p = &madc->requests[req->method];
++
++ memcpy(p, req, sizeof *req);
++
++ twl4030_madc_enable_irq(madc, req->method);
++
++ return 0;
++}
++
++static inline void twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
++ int conv_method)
++{
++ const struct twl4030_madc_conversion_method *method;
++
++ method = &twl4030_conversion_methods[conv_method];
++
++ switch (conv_method) {
++ case TWL4030_MADC_SW1:
++ case TWL4030_MADC_SW2:
++ twl4030_madc_write(madc, method->ctrl, TWL4030_MADC_SW_START);
++ break;
++ case TWL4030_MADC_RT:
++ default:
++ break;
++ }
++}
++
++static int twl4030_madc_wait_conversion_ready(
++ struct twl4030_madc_data *madc,
++ unsigned int timeout_ms, u8 status_reg)
++{
++ unsigned long timeout;
++
++ timeout = jiffies + msecs_to_jiffies(timeout_ms);
++ do {
++ u8 reg;
++
++ reg = twl4030_madc_read(madc, status_reg);
++ if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
++ return 0;
++ } while (!time_after(jiffies, timeout));
++
++ return -EAGAIN;
++}
++
++int twl4030_madc_conversion(struct twl4030_madc_request *req)
++{
++ const struct twl4030_madc_conversion_method *method;
++ u8 ch_msb, ch_lsb;
++ int ret;
++
++ if (unlikely(!req))
++ return -EINVAL;
++
++ mutex_lock(&the_madc->lock);
++
++ /* Do we have a conversion request ongoing */
++ if (the_madc->requests[req->method].active) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ch_msb = (req->channels >> 8) & 0xff;
++ ch_lsb = req->channels & 0xff;
++
++ method = &twl4030_conversion_methods[req->method];
++
++ /* Select channels to be converted */
++ twl4030_madc_write(the_madc, method->sel + 1, ch_msb);
++ twl4030_madc_write(the_madc, method->sel, ch_lsb);
++
++ /* Select averaging for all channels if do_avg is set */
++ if (req->do_avg) {
++ twl4030_madc_write(the_madc, method->avg + 1, ch_msb);
++ twl4030_madc_write(the_madc, method->avg, ch_lsb);
++ }
++
++ if ((req->type == TWL4030_MADC_IRQ_ONESHOT) && (req->func_cb != NULL)) {
++ twl4030_madc_set_irq(the_madc, req);
++ twl4030_madc_start_conversion(the_madc, req->method);
++ the_madc->requests[req->method].active = 1;
++ ret = 0;
++ goto out;
++ }
++
++ /* With RT method we should not be here anymore */
++ if (req->method == TWL4030_MADC_RT) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ twl4030_madc_start_conversion(the_madc, req->method);
++ the_madc->requests[req->method].active = 1;
++
++ /* Wait until conversion is ready (ctrl register returns EOC) */
++ ret = twl4030_madc_wait_conversion_ready(the_madc, 5, method->ctrl);
++ if (ret) {
++ dev_dbg(the_madc->dev, "conversion timeout!\n");
++ the_madc->requests[req->method].active = 0;
++ goto out;
++ }
++
++ ret = twl4030_madc_read_channels(the_madc, method->rbase, req->channels,
++ req->rbuf);
++
++ the_madc->requests[req->method].active = 0;
++
++out:
++ mutex_unlock(&the_madc->lock);
++
++ return ret;
++}
++EXPORT_SYMBOL(twl4030_madc_conversion);
++
++static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
++ int chan, int on)
++{
++ int ret;
++ u8 regval;
++
++ /* Current generator is only available for ADCIN0 and ADCIN1. NB:
++ * ADCIN1 current generator only works when AC or VBUS is present */
++ if (chan > 1)
++ return EINVAL;
++
++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
++ &regval, TWL4030_BCI_BCICTL1);
++ if (on)
++ regval |= (chan) ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
++ else
++ regval &= (chan) ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
++ regval, TWL4030_BCI_BCICTL1);
++
++ return ret;
++}
++
++static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
++{
++ u8 regval;
++
++ regval = twl4030_madc_read(madc, TWL4030_MADC_CTRL1);
++ if (on)
++ regval |= TWL4030_MADC_MADCON;
++ else
++ regval &= ~TWL4030_MADC_MADCON;
++ twl4030_madc_write(madc, TWL4030_MADC_CTRL1, regval);
++
++ return 0;
++}
++
++static long twl4030_madc_ioctl(struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ struct twl4030_madc_user_parms par;
++ int val, ret;
++
++ ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
++ if (ret) {
++ dev_dbg(the_madc->dev, "copy_from_user: %d\n", ret);
++ return -EACCES;
++ }
++
++ switch (cmd) {
++ case TWL4030_MADC_IOCX_ADC_RAW_READ: {
++ struct twl4030_madc_request req;
++ if (par.channel >= TWL4030_MADC_MAX_CHANNELS)
++ return -EINVAL;
++
++ req.channels = (1 << par.channel);
++ req.do_avg = par.average;
++ req.method = TWL4030_MADC_SW1;
++ req.func_cb = NULL;
++
++ val = twl4030_madc_conversion(&req);
++ if (val <= 0) {
++ par.status = -1;
++ } else {
++ par.status = 0;
++ par.result = (u16)req.rbuf[par.channel];
++ }
++ break;
++ }
++ default:
++ return -EINVAL;
++ }
++
++ ret = copy_to_user((void __user *) arg, &par, sizeof(par));
++ if (ret) {
++ dev_dbg(the_madc->dev, "copy_to_user: %d\n", ret);
++ return -EACCES;
++ }
++
++ return 0;
++}
++
++static struct file_operations twl4030_madc_fileops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = twl4030_madc_ioctl
++};
++
++static struct miscdevice twl4030_madc_device = {
++ .minor = MISC_DYNAMIC_MINOR,
++ .name = "twl4030-madc",
++ .fops = &twl4030_madc_fileops
++};
++
++static int __init twl4030_madc_probe(struct platform_device *pdev)
++{
++ struct twl4030_madc_data *madc;
++ struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
++ int ret;
++ u8 regval;
++
++ madc = kzalloc(sizeof *madc, GFP_KERNEL);
++ if (!madc)
++ return -ENOMEM;
++
++ if (!pdata) {
++ dev_dbg(&pdev->dev, "platform_data not available\n");
++ ret = -EINVAL;
++ goto err_pdata;
++ }
++
++ madc->imr = (pdata->irq_line == 1) ? TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
++ madc->isr = (pdata->irq_line == 1) ? TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
++
++ ret = misc_register(&twl4030_madc_device);
++ if (ret) {
++ dev_dbg(&pdev->dev, "could not register misc_device\n");
++ goto err_misc;
++ }
++ twl4030_madc_set_power(madc, 1);
++ twl4030_madc_set_current_generator(madc, 0, 1);
++
++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
++ &regval, TWL4030_BCI_BCICTL1);
++
++ regval |= TWL4030_BCI_MESBAT;
++
++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
++ regval, TWL4030_BCI_BCICTL1);
++
++ ret = request_irq(platform_get_irq(pdev, 0), twl4030_madc_irq_handler,
++ 0, "twl4030_madc", madc);
++ if (ret) {
++ dev_dbg(&pdev->dev, "could not request irq\n");
++ goto err_irq;
++ }
++
++ platform_set_drvdata(pdev, madc);
++ mutex_init(&madc->lock);
++ INIT_WORK(&madc->ws, twl4030_madc_work);
++
++ the_madc = madc;
++
++ return 0;
++
++err_irq:
++ misc_deregister(&twl4030_madc_device);
++
++err_misc:
++err_pdata:
++ kfree(madc);
++
++ return ret;
++}
++
++static int __exit twl4030_madc_remove(struct platform_device *pdev)
++{
++ struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
++
++ twl4030_madc_set_power(madc, 0);
++ twl4030_madc_set_current_generator(madc, 0, 0);
++ free_irq(platform_get_irq(pdev, 0), madc);
++ cancel_work_sync(&madc->ws);
++ misc_deregister(&twl4030_madc_device);
++
++ return 0;
++}
++
++static struct platform_driver twl4030_madc_driver = {
++ .probe = twl4030_madc_probe,
++ .remove = __exit_p(twl4030_madc_remove),
++ .driver = {
++ .name = "twl4030_madc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init twl4030_madc_init(void)
++{
++ return platform_driver_register(&twl4030_madc_driver);
++}
++module_init(twl4030_madc_init);
++
++static void __exit twl4030_madc_exit(void)
++{
++ platform_driver_unregister(&twl4030_madc_driver);
++}
++module_exit(twl4030_madc_exit);
++
++MODULE_ALIAS("platform:twl4030-madc");
++MODULE_AUTHOR("Nokia Corporation");
++MODULE_DESCRIPTION("twl4030 ADC driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h
+new file mode 100644
+index 0000000..24523b5
+--- /dev/null
++++ b/include/linux/i2c/twl4030-madc.h
+@@ -0,0 +1,126 @@
++/*
++ * include/linux/i2c/twl4030-madc.h
++ *
++ * TWL4030 MADC module driver header
++ *
++ * Copyright (C) 2008 Nokia Corporation
++ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#ifndef _TWL4030_MADC_H
++#define _TWL4030_MADC_H
++
++struct twl4030_madc_conversion_method {
++ u8 sel;
++ u8 avg;
++ u8 rbase;
++ u8 ctrl;
++};
++
++#define TWL4030_MADC_MAX_CHANNELS 16
++
++struct twl4030_madc_request {
++ u16 channels;
++ u16 do_avg;
++ u16 method;
++ u16 type;
++ int active;
++ int result_pending;
++ int rbuf[TWL4030_MADC_MAX_CHANNELS];
++ void (*func_cb)(int len, int channels, int *buf);
++};
++
++enum conversion_methods {
++ TWL4030_MADC_RT,
++ TWL4030_MADC_SW1,
++ TWL4030_MADC_SW2,
++ TWL4030_MADC_NUM_METHODS
++};
++
++enum sample_type {
++ TWL4030_MADC_WAIT,
++ TWL4030_MADC_IRQ_ONESHOT,
++ TWL4030_MADC_IRQ_REARM
++};
++
++#define TWL4030_MADC_CTRL1 0x00
++#define TWL4030_MADC_CTRL2 0x01
++
++#define TWL4030_MADC_RTSELECT_LSB 0x02
++#define TWL4030_MADC_SW1SELECT_LSB 0x06
++#define TWL4030_MADC_SW2SELECT_LSB 0x0A
++
++#define TWL4030_MADC_RTAVERAGE_LSB 0x04
++#define TWL4030_MADC_SW1AVERAGE_LSB 0x08
++#define TWL4030_MADC_SW2AVERAGE_LSB 0x0C
++
++#define TWL4030_MADC_CTRL_SW1 0x12
++#define TWL4030_MADC_CTRL_SW2 0x13
++
++#define TWL4030_MADC_RTCH0_LSB 0x17
++#define TWL4030_MADC_GPCH0_LSB 0x37
++
++#define TWL4030_MADC_MADCON (1<<0) /* MADC power on */
++#define TWL4030_MADC_BUSY (1<<0) /* MADC busy */
++#define TWL4030_MADC_EOC_SW (1<<1) /* MADC conversion completion */
++#define TWL4030_MADC_SW_START (1<<5) /* MADC SWx start conversion */
++
++#define TWL4030_MADC_ADCIN0 (1<<0)
++#define TWL4030_MADC_ADCIN1 (1<<1)
++#define TWL4030_MADC_ADCIN2 (1<<2)
++#define TWL4030_MADC_ADCIN3 (1<<3)
++#define TWL4030_MADC_ADCIN4 (1<<4)
++#define TWL4030_MADC_ADCIN5 (1<<5)
++#define TWL4030_MADC_ADCIN6 (1<<6)
++#define TWL4030_MADC_ADCIN7 (1<<7)
++#define TWL4030_MADC_ADCIN8 (1<<8)
++#define TWL4030_MADC_ADCIN9 (1<<9)
++#define TWL4030_MADC_ADCIN10 (1<<10)
++#define TWL4030_MADC_ADCIN11 (1<<11)
++#define TWL4030_MADC_ADCIN12 (1<<12)
++#define TWL4030_MADC_ADCIN13 (1<<13)
++#define TWL4030_MADC_ADCIN14 (1<<14)
++#define TWL4030_MADC_ADCIN15 (1<<15)
++
++/* Fixed channels */
++#define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1
++#define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8
++#define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9
++#define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10
++#define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11
++#define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12
++
++/* BCI related - XXX To be moved elsewhere */
++#define TWL4030_BCI_BCICTL1 0x23
++#define TWL4030_BCI_MESBAT (1<<1)
++#define TWL4030_BCI_TYPEN (1<<4)
++#define TWL4030_BCI_ITHEN (1<<3)
++
++#define TWL4030_MADC_IOC_MAGIC '`'
++#define TWL4030_MADC_IOCX_ADC_RAW_READ _IO(TWL4030_MADC_IOC_MAGIC, 0)
++
++struct twl4030_madc_user_parms {
++ int channel;
++ int average;
++ int status;
++ u16 result;
++};
++
++int twl4030_madc_conversion(struct twl4030_madc_request *conv);
++
++#endif
diff --git a/recipes/linux/linux-omap-2.6.31/madc/madc.patch b/recipes/linux/linux-omap-2.6.31/madc/madc.patch
new file mode 100644
index 0000000000..dbbd50f662
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.31/madc/madc.patch
@@ -0,0 +1,56 @@
+diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
+index 48f9932..ce84ee7 100644
+--- a/arch/arm/mach-omap2/board-overo.c
++++ b/arch/arm/mach-omap2/board-overo.c
+@@ -340,10 +340,15 @@ static struct regulator_init_data overo_vmmc1 = {
+
+ /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
+
++static struct twl4030_madc_platform_data overo_madc_data = {
++ .irq_line = 1,
++};
++
+ static struct twl4030_platform_data overo_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+ .gpio = &overo_gpio_data,
++ .madc = &overo_madc_data,
+ .usb = &overo_usb_data,
+ .power = GENERIC3430_T2SCRIPTS_DATA,
+ .vmmc1 = &overo_vmmc1,
+diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
+index 769b34b..c5ca36d 100644
+--- a/drivers/mfd/twl4030-core.c
++++ b/drivers/mfd/twl4030-core.c
+@@ -159,6 +159,7 @@
+
+ /* Few power values */
+ #define R_CFG_BOOT 0x05
++#define R_GPBR1 0x0C
+ #define R_PROTECT_KEY 0x0E
+
+ /* access control values for R_PROTECT_KEY */
+@@ -166,6 +167,10 @@
+ #define KEY_UNLOCK2 0xec
+ #define KEY_LOCK 0x00
+
++/* MADC clock values for R_GPBR1 */
++#define MADC_HFCLK_EN 0x80
++#define DEFAULT_MADC_CLK_EN 0x10
++
+ /* some fields in R_CFG_BOOT */
+ #define HFCLK_FREQ_19p2_MHZ (1 << 0)
+ #define HFCLK_FREQ_26_MHZ (2 << 0)
+@@ -717,6 +722,11 @@ static void __init clocks_init(struct device *dev)
+ ctrl |= HIGH_PERF_SQ;
+ e |= unprotect_pm_master();
+ /* effect->MADC+USB ck en */
++
++ if (twl_has_madc())
++ e |= twl4030_i2c_write_u8(TWL4030_MODULE_INTBR,
++ MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, R_GPBR1);
++
+ e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
+ e |= protect_pm_master();
+
+