diff options
author | Koen Kooi <koen@openembedded.org> | 2009-09-04 15:32:30 +0200 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-09-04 15:32:30 +0200 |
commit | 881f92e3409f67f70cffd5cfaca0de8248729145 (patch) | |
tree | 49f15add251b6ded5b2c5efc29f5603b76619e0e | |
parent | eff28b3b4ec8309ac1d51d98b8bfc9f5d48ed43f (diff) |
linux-omap git: another checkpoint
* add V4l2 interfaces to DSS2
* add back MADC driver
* add zippy support for beagleboard
* add DSS2 for omap3evm
9 files changed, 4953 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(¤t->mm->mmap_sem); ++ ++ res = get_user_pages(current, current->mm, virtp, nr_pages, ++ 1, 0, &pages, NULL); ++ up_read(¤t->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, ++ ®val, 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, ++ ®val, 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(); + + diff --git a/recipes/linux/linux-omap_git.bb b/recipes/linux/linux-omap_git.bb index 215f88a394..f19840d4f4 100644 --- a/recipes/linux/linux-omap_git.bb +++ b/recipes/linux/linux-omap_git.bb @@ -42,9 +42,17 @@ SRC_URI_append = " \ file://dss2/0015-OMAP-DSS2-omapfb-driver.patch;patch=1 \ file://dss2/0016-OMAP-DSS2-Add-DPI-panel-drivers.patch;patch=1 \ file://dss2/0017-OMAP-DSS2-Taal-DSI-command-mode-panel-driver.patch;patch=1 \ + file://dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch;patch=1 \ + file://dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch;patch=1 \ + file://dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch;patch=1 \ + file://dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch;patch=1 \ + file://expansion-boards/tincantools-zippy.patch;patch=1 \ + file://madc/madc-driver.patch;patch=1 \ + file://madc/madc.patch;patch=1 \ " SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ +" S = "${WORKDIR}/git" |