diff --git a/arch/arm/configs/mx51_efikasb_defconfig b/arch/arm/configs/mx51_efikasb_defconfig new file mode 100644 index 00000000000..1d8f794373a --- /dev/null +++ b/arch/arm/configs/mx51_efikasb_defconfig @@ -0,0 +1,1946 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31 +# Fri Apr 9 10:11:27 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 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=y +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_IRAM_ALLOC=y +CONFIG_DMA_ZONE_SIZE=64 +CONFIG_UTMI_MXC=y + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX1 is not set +# CONFIG_ARCH_MX2 is not set +# CONFIG_ARCH_MX3 is not set +# CONFIG_ARCH_MX25 is not set +# CONFIG_ARCH_MX35 is not set +# CONFIG_ARCH_MX37 is not set +# CONFIG_MXS_TIMER_WITH_MACH is not set +CONFIG_ARCH_MX5=y +CONFIG_ARCH_MX51=y +CONFIG_MXC_SDMA_API=y +CONFIG_SDMA_IRAM=y +CONFIG_SDMA_IRAM_SIZE=0x1000 +# CONFIG_I2C_MXC_SELECT1 is not set +CONFIG_I2C_MXC_SELECT2=y +# CONFIG_I2C_MXC_SELECT3 is not set +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_ARCH_MXC_HAS_NFC_V3=y +CONFIG_MX5_OPTIONS=y + +# +# MX51 Options +# +CONFIG_MX51_OPTIONS=y +# CONFIG_MACH_MX51_3DS is not set +# CONFIG_MACH_MX51_BABBAGE is not set +# CONFIG_MACH_MX51_LANGE51 is not set +CONFIG_MACH_MX51_EFIKASB=y +# CONFIG_EFIKASB_EXPERIMENTAL_OS is not set +# CONFIG_MACH_MX53_EVK is not set + +# +# MX5x Options: +# +CONFIG_ARCH_MXC_HAS_NFC_V3_2=y + +# +# SDMA options +# + +# +# Device options +# +CONFIG_MXC_TZIC=y +CONFIG_ISP1504_MXC=y +# CONFIG_MXC_IRQ_PRIOR is not set +# CONFIG_MXC_PWM is not set +# CONFIG_MXC_DVFS_PER is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_IMX=y +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIVHCI=m +CONFIG_BT_BRCM_BT=m + +# +# Broadcom Bluetooth device drivers +# +CONFIG_BT_BRCM_BTUSB=m +CONFIG_BT_BRCM_BTSCO=m +CONFIG_BT_BRCM_BTHID=m +CONFIG_BT_BRCM_BTA2DP=m +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_MXC is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_MXC_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +CONFIG_MTD_SST25VF=m +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_MX51_EFIKASB_DEBUG is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# 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 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# 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=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +# CONFIG_PATA_PLATFORM is not set +CONFIG_PATA_FSL=y +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_FEC is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +CONFIG_RT3070=m + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=y +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_CDCETHER is not set +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_DM9601 is not set +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_WAN is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_MPPE=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_POLLDEV=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# 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_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_MXC is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_MXC_IIM=y +CONFIG_IMX_SIM=m + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MXC=y +CONFIG_SERIAL_MXC_CONSOLE=y +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_IMX is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_IMX is not set +CONFIG_I2C_MXC=y +# CONFIG_I2C_MXC_HS is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_SLAVE is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_MXC=y +# CONFIG_SPI_MXC_TEST_LOOPBACK is not set +CONFIG_SPI_MXC_SELECT1=y +# CONFIG_SPI_MXC_SELECT2 is not set +# CONFIG_SPI_MXC_SELECT3 is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +CONFIG_BATTERY_EFIKASB=y +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_MXC_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_MXC_CAMERA is not set +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set +# CONFIG_VIDEO_MXC_OPL is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_MXC=y +CONFIG_FB_MXC_SYNC_PANEL=y +# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set +# CONFIG_FB_MXC_TVOUT_TVE is not set +# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set +# CONFIG_FB_MXC_CH7026 is not set +# CONFIG_FB_MXC_SII9022 is not set +# CONFIG_FB_MXC_CS8556 is not set +CONFIG_FB_MXC_MTL017=y +# CONFIG_FB_MXC_TVOUT is not set +# CONFIG_FB_MXC_TVOUT_CH7024 is not set +# CONFIG_FB_MXC_ASYNC_PANEL is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_MXC=y +# CONFIG_BACKLIGHT_MXC_MC13892 is not set +CONFIG_BACKLIGHT_MXC_EFIKASB=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +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 is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_MXC_SOC=y +CONFIG_SND_MXC_SOC_SSI=y +# CONFIG_SND_MXC_SOC_IRAM is not set +CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y +# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set +# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set +# CONFIG_SND_SOC_IMX_3STACK_AK5702 is not set +# CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_SGTL5000=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EZKEY=y +CONFIG_HID_KYE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=y +# CONFIG_HID_THRUSTMASTER 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 is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ARC=y +CONFIG_USB_EHCI_ARC_H1=y +CONFIG_USB_EHCI_ARC_H2=y +# CONFIG_USB_EHCI_ARC_OTG is not set +# CONFIG_USB_STATIC_IRAM is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_EZUSB is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_OPTION=m +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_MXC is not set +# CONFIG_MMC_SPI is not set +CONFIG_MMC_IMX_ESDHCI=y +# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_MC13892 is not set +CONFIG_LEDS_EFIKASB=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# 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 +# +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_MXC is not set +# CONFIG_RTC_DRV_MXC_V2 is not set +# CONFIG_RTC_DRV_IMXDI is not set +CONFIG_RTC_MC13892=y +# 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_LP3971 is not set +CONFIG_REGULATOR_MC13892=y +CONFIG_UIO=y +CONFIG_UIO_PDRV=y +CONFIG_UIO_PDRV_GENIRQ=y +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_STAGING is not set + +# +# MXC support drivers +# +CONFIG_MXC_IPU=y +CONFIG_MXC_IPU_V3=y + +# +# MXC SSI support +# +# CONFIG_MXC_SSI is not set + +# +# MXC Digital Audio Multiplexer support +# +# CONFIG_MXC_DAM is not set + +# +# MXC PMIC support +# +CONFIG_MXC_PMIC=y +# CONFIG_MXC_PMIC_MC13783 is not set +CONFIG_MXC_PMIC_MC13892=y +# CONFIG_MXC_PMIC_I2C is not set +CONFIG_MXC_PMIC_SPI=y +# CONFIG_MXC_PMIC_MC34704 is not set +# CONFIG_MXC_PMIC_MC9SDZ60 is not set +# CONFIG_MXC_PMIC_CHARDEV is not set + +# +# MXC PMIC Client Drivers +# +CONFIG_MXC_MC13892_ADC=y +CONFIG_MXC_MC13892_RTC=y +CONFIG_MXC_MC13892_LIGHT=y +# CONFIG_MXC_MC13892_BATTERY is not set +CONFIG_MXC_MC13892_CONNECTIVITY=y +CONFIG_MXC_MC13892_POWER=y +# CONFIG_MXC_PMIC_MC9S08DZ60 is not set + +# +# MXC Security Drivers +# +# CONFIG_MXC_SECURITY_SCC is not set +CONFIG_MXC_SECURITY_SCC2=y +CONFIG_SCC_DEBUG=y +# CONFIG_MXC_SECURITY_RNG is not set + +# +# SAHARA2 Security Hardware Support +# +# CONFIG_MXC_SAHARA is not set + +# +# MXC MPEG4 Encoder Kernel module support +# +# CONFIG_MXC_HMP4E is not set + +# +# MXC HARDWARE EVENT +# +# CONFIG_MXC_HWEVENT is not set + +# +# MXC VPU(Video Processing Unit) support +# +CONFIG_MXC_VPU=y +CONFIG_MXC_VPU_IRAM=y +# CONFIG_MXC_VPU_DEBUG is not set + +# +# MXC Asynchronous Sample Rate Converter support +# + +# +# MXC Bluetooth support +# + +# +# Broadcom GPS ioctrl support +# +CONFIG_GPS_IOCTRL=m + +# +# MXC Media Local Bus Driver +# + +# +# i.MX ADC support +# +# CONFIG_IMX_ADC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_JBD=y +CONFIG_JBD2=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=y +CONFIG_CUSE=y + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_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 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_CRYPTODEV is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 23eb5a3ce44..7c8c7c94193 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -47,6 +47,13 @@ config MACH_MX51_EFIKAMX help Include support for Genesi Efika MX platforms. +config MACH_MX51_EFIKASB + bool "Support Genesi Efika MX Smartbook" + select ARCH_MX51 + help + Include support for Genesi Efika MX Smartbook. This includes specific + configurations for the board and its peripherals. + config MACH_MX53_EVK bool "Support MX53 EVK platform" select ARCH_MX53 diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 629384692d1..6a00d914873 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -22,3 +22,6 @@ obj-$(CONFIG_MACH_MX51_EFIKAMX) += mx51_efikamx.o mx51_efikamx_io.o mx51_efikamx mx51_efikamx_spi.o mx51_efikamx_nor.o mx51_efikamx_pmic.o \ mx51_efikamx_mmc.o mx51_efikamx_ata.o mx51_efikamx_powerkey.o \ mx51_efikamx_audio.o mx51_efikamx_display.o early_setup.o +obj-$(CONFIG_MACH_MX51_EFIKASB) += mx51_efikasb.o mx51_efikasb_gpio.o mx51_efikasb_pmic.o \ + mx51_efikasb_idle_timer.o mx51_efikasb_input.o \ + mx51_efikasb_lid.o mx51_efikasb_powerkey.o diff --git a/arch/arm/mach-mx5/mx51_efikasb.c b/arch/arm/mach-mx5/mx51_efikasb.c new file mode 100644 index 00000000000..e58e955d228 --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb.c @@ -0,0 +1,833 @@ +/* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + * + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devices.h" +#include "mx51_efikasb.h" +#include "iomux.h" +#include "mx51_pins.h" +#include "crm_regs.h" +#include "usb.h" +#include + +/*! + * @file mach-mx51/mx51_efikasb.c + * + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX51 + */ +extern void __init mx51_efikasb_io_init(void); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +extern void (*set_num_cpu_wp)(int num); +static int num_cpu_wp = 3; +static int lvds_en_dir = 0; + +extern int mxc_get_battery_insertion_status(void); +extern int mxc_get_ac_adapter_insertion_status(void); +extern int mxc_get_batt_low_status(void); +/* extern void mxc_turn_on_batt_low_led(int); */ + +extern int mxc_get_memory_id(void); +extern unsigned int mxc_get_pcb_id(void); + +/* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */ +static struct cpu_wp cpu_wp_auto[] = { + { + .pll_rate = 1000000000, + .cpu_rate = 1000000000, + .pdf = 0, + .mfi = 10, + .mfd = 11, + .mfn = 5, + .cpu_podf = 0, + .cpu_voltage = 1175000,}, + { + .pll_rate = 800000000, + .cpu_rate = 800000000, + .pdf = 0, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 0, + .cpu_voltage = 1100000,}, + { + .pll_rate = 800000000, + .cpu_rate = 166250000, + .pdf = 4, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 4, + .cpu_voltage = 850000,}, + +}; + +struct cpu_wp *mx51_efikasb_get_cpu_wp(int *wp) +{ + *wp = num_cpu_wp; + return cpu_wp_auto; +} + +void mx51_efikasb_set_num_cpu_wp(int num) +{ + num_cpu_wp = num; + return; +} + +static struct mxc_w1_config mxc_w1_data = { + .search_rom_accelerator = 1, +}; + + +static struct platform_pwm_backlight_data mxc_pwm_backlight_data = { + .pwm_id = 0, + .max_brightness = 255, + .dft_brightness = 128, + .pwm_period_ns = 78770, +}; + +extern void mx5_ipu_reset(void); /* eric 20100521 */ +static struct mxc_ipu_config mxc_ipu_data = { + .rev = 2, + .reset = mx5_ipu_reset, /* eric 20100521*/ +}; + +extern void mx5_vpu_reset(void); +static struct mxc_vpu_platform_data mxc_vpu_data = { + .reset = mx5_vpu_reset, +}; + +extern void mx51_efikasb_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect); +extern void mx51_efikasb_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect); +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 4, + .spi_version = 23, + .chipselect_active = mx51_efikasb_gpio_spi_chipselect_active, + .chipselect_inactive = mx51_efikasb_gpio_spi_chipselect_inactive, +}; + +static struct mxc_i2c_platform_data mxci2c_data = { + .i2c_clk = 100000, +}; + +static struct mxc_srtc_platform_data srtc_data = { + .srtc_sec_mode_addr = 0x83F98840, +}; + +static struct tve_platform_data tve_data = { + .dac_reg = "VVIDEO", +}; + +static struct mxc_dvfs_platform_data dvfs_core_data = { + .reg_id = "SW1", + .clk1_id = "cpu_clk", + .clk2_id = "gpc_dvfs_clk", + .gpc_cntr_reg_addr = MXC_GPC_CNTR, + .gpc_vcr_reg_addr = MXC_GPC_VCR, + .ccm_cdcr_reg_addr = MXC_CCM_CDCR, + .ccm_cacrr_reg_addr = MXC_CCM_CACRR, + .ccm_cdhipr_reg_addr = MXC_CCM_CDHIPR, + // .dvfs_thrs_reg_addr = MXC_DVFSTHRS, + //.dvfs_coun_reg_addr = MXC_DVFSCOUN, + //.dvfs_emac_reg_addr = MXC_DVFSEMAC, + //.dvfs_cntr_reg_addr = MXC_DVFSCNTR, + .prediv_mask = 0x1F800, + .prediv_offset = 11, + .prediv_val = 3, + .div3ck_mask = 0xE0000000, + .div3ck_offset = 29, + .div3ck_val = 2, + .emac_val = 0x08, + .upthr_val = 25, + .dnthr_val = 9, + .pncthr_val = 33, + .upcnt_val = 10, + .dncnt_val = 10, + .delay_time = 30, + .num_wp = 3, +}; + +static struct mxc_dvfsper_data dvfs_per_data = { + .reg_id = "SW2", + .clk_id = "gpc_dvfs_clk", + .gpc_cntr_reg_addr = MXC_GPC_CNTR, + .gpc_vcr_reg_addr = MXC_GPC_VCR, + .gpc_adu = 0x0, + .vai_mask = MXC_DVFSPMCR0_FSVAI_MASK, + .vai_offset = MXC_DVFSPMCR0_FSVAI_OFFSET, + .dvfs_enable_bit = MXC_DVFSPMCR0_DVFEN, + .irq_mask = MXC_DVFSPMCR0_FSVAIM, + .div3_offset = 0, + .div3_mask = 0x7, + .div3_div = 2, + .lp_high = 1200000, + .lp_low = 1200000, +}; + +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* spdif_ext_clk source for 44.1KHz */ + .spdif_clk_48000 = 7, /* audio osc source */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \ + defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static struct resource mxcfb_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, +}; + +static struct mxc_fb_platform_data fb_data[] = { + { + .interface_pix_fmt = IPU_PIX_FMT_RGB24, + .mode_str = "1280x720MR-16@60", /* ron: TBD */ + }, + { + .interface_pix_fmt = IPU_PIX_FMT_RGB565, + .mode_str = "1024x768M-16@60", /* ron: TBD */ + }, + +}; + +static void __init mxc_init_fb(void) +{ + mxc_fb_devices[1].num_resources = ARRAY_SIZE(mxcfb_resources); + mxc_fb_devices[1].resource = mxcfb_resources; + mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); /* ron: LVDS LCD */ + mxc_register_device(&mxc_fb_devices[2], NULL); // Overlay for VPU +} +#endif + +static int __initdata enable_ddr2max = { 0 }; + +static void mxc_power_on_lcd(int on) +{ + if(on) { + gpio_set_value(IOMUX_TO_GPIO(LCD_PWRON_PIN), 1); /* LCD Power On */ + } else { + gpio_set_value(IOMUX_TO_GPIO(LCD_PWRON_PIN), 0); /* LCD Power Off */ + } + +} + + +static void mxc_lvds_enable(int on) +{ + if(on == -1) { + gpio_direction_input(IOMUX_TO_GPIO(LCD_LVDS_EN_PIN)); + lvds_en_dir = 1; + return; + } + + lvds_en_dir = 0; + if(on) { + gpio_set_value(IOMUX_TO_GPIO(LCD_LVDS_EN_PIN), 1); /* LVDS_EN On */ + } else { + gpio_set_value(IOMUX_TO_GPIO(LCD_LVDS_EN_PIN), 0); /* LVDS_EN Off */ + } +} + +static void mxc_turn_on_lcd_backlight(int on) +{ + if(on) { + mxc_free_iomux(LCD_BL_PWM_PIN, IOMUX_CONFIG_GPIO); + mxc_request_iomux(LCD_BL_PWM_PIN, IOMUX_CONFIG_ALT1); + + msleep(10); + + gpio_set_value(IOMUX_TO_GPIO(LCD_BL_PWRON_PIN), 0); /* Backlight Power On */ + } else { + gpio_set_value(IOMUX_TO_GPIO(LCD_BL_PWRON_PIN), 1); /* Backlight Power Off */ + + msleep(10); + + mxc_free_iomux(LCD_BL_PWM_PIN, IOMUX_CONFIG_ALT1); + mxc_request_iomux(LCD_BL_PWM_PIN, IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(LCD_BL_PWM_PIN), 0); + } +} + +static void mxc_reset_lvds(void) +{ + gpio_set_value(IOMUX_TO_GPIO(LVDS_RESET_PIN), 0); + msleep(50); + gpio_set_value(IOMUX_TO_GPIO(LVDS_RESET_PIN), 1); + msleep(10); + gpio_set_value(IOMUX_TO_GPIO(LVDS_RESET_PIN), 0); + +} + +static void mxc_power_on_lvds(int on) +{ + if(on) + gpio_set_value(IOMUX_TO_GPIO(LVDS_PWRCTL_PIN), 1); + else + gpio_set_value(IOMUX_TO_GPIO(LVDS_PWRCTL_PIN), 0); +} + +static struct mxc_lcd_platform_data lvds_data = { + .core_reg = "VCAM", + .io_reg = "VGEN3", + .analog_reg = "VAUDIO", + .reset = mxc_reset_lvds, + .power_on_lcd = mxc_power_on_lcd, + .turn_on_backlight = mxc_turn_on_lcd_backlight, + .power_on_lvds = mxc_power_on_lvds, + .lvds_enable = mxc_lvds_enable, +}; + +static struct platform_device mxcbl_device = { + .name = "mxc_efikasb_bl", +}; + +static struct platform_device mxc_led_device = { + .name = "efikasb_leds", + .id = 1, +}; + +static struct mxc_battery_platform_data efikasb_batt_data = { + .batt_in_irq = IOMUX_TO_IRQ(BATT_INS_PIN), + .ac_in_irq = IOMUX_TO_IRQ(AC_ADAP_INS_PIN), + .batt_low_irq = IOMUX_TO_IRQ(BATT_LOW_PIN), + .get_batt_in_status = mxc_get_battery_insertion_status, + .get_ac_in_status = mxc_get_ac_adapter_insertion_status, + .get_batt_low_status = mxc_get_batt_low_status, + .set_batt_low_led = NULL/* mxc_turn_on_batt_low_led */, +}; + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { + { + .type = "sgtl5000-i2c", + .addr = 0x0a, + }, + { /* ron: LVDS Controller */ + .type = "mtl017", + .addr = 0x3a, + .platform_data = &lvds_data, + }, + { + .type = "efikasb-battery", + .addr = 0x0b, + .platform_data = &efikasb_batt_data, + }, +}; +#endif + +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +static struct mtd_partition mxc_spi_flash_partitions[] = { + { + .name = "redboot", + .offset = 0, + .size = 0x00040000, + .mask_flags = MTD_CAP_ROM, + }, + { + .name = "fis-dir", + .offset = MTDPART_OFS_APPEND, + .size = 0x0000F000, + .mask_flags = MTD_CAP_ROM, + }, + { + .name = "rb-config", + .offset = MTDPART_OFS_APPEND, + .size = 0x00001000, + .mask_flags = MTD_CAP_ROM, + }, + { + .name = "kernel", + .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data mxc_spi_flash_data = { + .name = "mxc_spi_nor", + .parts = mxc_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(mxc_spi_flash_partitions), +/* .type = "sst25vf032b", */ + /* ron: also support MXIC MX25L3205D, use jedec_probe to detect */ + .type = NULL, +}; + +static struct spi_board_info mxc_spi_board_info[] __initdata = { + { + .modalias = "sst25vf", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .platform_data = &mxc_spi_flash_data, + }, +}; +#endif + +#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) +static int sdhc_write_protect(struct device *dev) +{ + unsigned short rc = 0; + + if (to_platform_device(dev)->id == 0) + rc = gpio_get_value(IOMUX_TO_GPIO(SDHC1_WP_PIN)); + else + rc = gpio_get_value(IOMUX_TO_GPIO(SDHC2_WP_PIN)); + + return rc; +} + +static unsigned int sdhc_get_card_det_status(struct device *dev) +{ + int ret; + + if (to_platform_device(dev)->id == 0) { + ret = gpio_get_value(IOMUX_TO_GPIO(SDHC1_CD_PIN)); + return ret; + } else { /* config the det pin for SDHC2 */ + //ron: SDHC2 CD gpio + ret = gpio_get_value(IOMUX_TO_GPIO(SDHC2_CD_PIN)); + return ret; + } +} + +static struct mxc_mmc_platform_data mmc1_data = { + .ocr_mask = MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA, + .min_clk = 400000, + .max_clk = 52000000, + .card_inserted_state = 1, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", + .power_mmc = NULL, +}; + +static struct mxc_mmc_platform_data mmc2_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | + MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA, + .min_clk = 150000, + .max_clk = 50000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", +}; +#endif + +#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \ + || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE) +static int mxc_sgtl5000_amp_enable(int enable) +{ + gpio_set_value(IOMUX_TO_GPIO(AUD_MUTE_PIN), enable ? 1 : 0); + return 0; +} + +static int headphone_det_status(void) +{ + return gpio_get_value(IOMUX_TO_GPIO(HPJACK_INS_PIN)); +} + +static struct mxc_audio_platform_data sgtl5000_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_irq = IOMUX_TO_IRQ(HPJACK_INS_PIN), + .hp_status = headphone_det_status, + .amp_enable = mxc_sgtl5000_amp_enable, + .sysclk = 12288000, +}; + +static struct platform_device mxc_sgtl5000_device = { + .name = "imx-3stack-sgtl5000", +}; +#endif + +/*! + * Board specific fixup function. It is called by \b setup_arch() in + * setup.c file very early on during kernel starts. It allows the user to + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + char *str; + int size = SZ_512M - SZ_32M; + struct tag *t; + + mxc_set_cpu_type(MXC_CPU_MX51); + + get_cpu_wp = mx51_efikasb_get_cpu_wp; + set_num_cpu_wp = mx51_efikasb_set_num_cpu_wp; + + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_CMDLINE) + continue; + str = t->u.cmdline.cmdline; + str = strstr(str, "mem="); + if (str != NULL) { + str += 4; + size = memparse(str, &str); + if (size == 0 || size == SZ_512M) + return; + } + } + + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_MEM) + continue; + + t->u.mem.size = size; +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \ + defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) + mxcfb_resources[0].start = t->u.mem.start + size; + mxcfb_resources[0].end = t->u.mem.start + SZ_512M - 1; +#endif + } +} + +#define PWGT1SPIEN (1<<15) +#define PWGT2SPIEN (1<<16) +#define USEROFFSPI (1<<3) + +static void mxc_power_off(void) +{ + mxc_turn_on_lcd_backlight(0); + + msleep(200); + + if(lvds_en_dir == 0) { + mxc_lvds_enable(0); + } + + mxc_power_on_lvds(0); + + msleep(5); + + mxc_power_on_lcd(0); + + /* We can do power down one of two ways: + Set the power gating + Set USEROFFSPI */ + gpio_set_value(IOMUX_TO_GPIO(USB_PHY_RESET_PIN), 0); + msleep(10); + /* Set the power gate bits to power down */ + pmic_write_reg(REG_POWER_MISC, (PWGT1SPIEN|PWGT2SPIEN), + (PWGT1SPIEN|PWGT2SPIEN)); + + mxc_wd_reset(); + + //robin: CLR_DFF + mxc_request_iomux(SYS_PWROFF_PIN, IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(SYS_PWROFF_PIN), 0); + gpio_set_value(IOMUX_TO_GPIO(SYS_PWROFF_PIN), 0); + msleep(10); + gpio_set_value(IOMUX_TO_GPIO(SYS_PWROFF_PIN), 1); +} + +static irqreturn_t wwan_wakeup_int(int irq, void *dev_id) +{ + if(gpio_get_value(IOMUX_TO_GPIO(WWAN_WAKEUP_PIN))) + set_irq_type(irq, IRQF_TRIGGER_FALLING); + else + set_irq_type(irq, IRQF_TRIGGER_RISING); + + pr_info("WWAN wakeup event\n"); + return IRQ_HANDLED; +} + +static int __init mxc_init_wwan_wakeup(void) +{ + int irq, ret; + + irq = IOMUX_TO_IRQ(WWAN_WAKEUP_PIN); + + if(gpio_get_value(IOMUX_TO_GPIO(WWAN_WAKEUP_PIN))) + set_irq_type(irq, IRQF_TRIGGER_FALLING); + else + set_irq_type(irq, IRQF_TRIGGER_RISING); + + ret = request_irq(irq, wwan_wakeup_int, 0, "wwan-wakeup", 0); + if(ret) + pr_info("register WWAN wakeup interrupt failed\n"); + else + enable_irq_wake(irq); + + return ret; + +} +late_initcall(mxc_init_wwan_wakeup); + +extern void gpio_ata_active(void); +extern void gpio_ata_inactive(void); + +static int ata_init(struct platform_device *pdev) +{ + /* Configure the pins */ + gpio_ata_active(); + return 0; +} + +static void ata_exit(void) +{ + /* Free the pins */ + gpio_ata_inactive(); +} + +static struct fsl_ata_platform_data ata_data = { + .udma_mask = ATA_UDMA3, + .mwdma_mask = ATA_MWDMA2, + .pio_mask = ATA_PIO4, + .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2, + .max_sg = MXC_IDE_DMA_BD_NR, + .init = ata_init, + .exit = ata_exit, + .core_reg = NULL, + .io_reg = NULL, +}; + +#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE) +static struct mxc_gps_platform_data gps_data = { + .core_reg = "VIOHI", + .analog_reg = "SW4", +}; + +static struct platform_device mxc_gps_device = { + .name = "gps_ioctrl", + .id = -1, + .dev = { + .platform_data = &gps_data, + }, +}; + +int gpio_gps_access(int para) +{ + iomux_pin_name_t pin; + pin = (para & 0x1) ? AGPS_PWRON_PIN : AGPS_RESET_PIN; + + if (para & 0x4) /* Read GPIO */ + return gpio_get_value(IOMUX_TO_GPIO(pin)); + else if (para & 0x2) /* Write GPIO */ + gpio_set_value(IOMUX_TO_GPIO(pin), 1); + else + gpio_set_value(IOMUX_TO_GPIO(pin), 0); + return 0; +} +EXPORT_SYMBOL(gpio_gps_access); +#endif + +static void __init mxc_board_init(void) +{ + struct clk *clk; + +// printk(" [VV] mxc_board_init.\n"); + + mxc_ipu_data.di_clk[0] = clk_get(NULL, "ipu_di0_clk"); + mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di1_clk"); + +#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) + /* SD card detect irqs */ + mxcsdhc2_device.resource[2].start = IOMUX_TO_IRQ(SDHC2_CD_PIN); + mxcsdhc2_device.resource[2].end = IOMUX_TO_IRQ(SDHC2_CD_PIN); + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(SDHC1_CD_PIN); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(SDHC1_CD_PIN); +#endif + + mxc_cpu_common_init(); + + mxc_register_gpios(); + mx51_efikasb_io_init(); + + clk = clk_get(&(mxc_fb_devices[0].dev), "axi_b_clk"); + clk_set_rate(clk, 133000000); + + mxc_register_device(&mxc_dma_device, NULL); + mxc_register_device(&mxc_wdt_device, NULL); + mxc_register_device(&mxcspi1_device, &mxcspi1_data); +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + mxc_register_device(&mxci2c_devices[1], &mxci2c_data); +#endif +#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) + mxc_register_device(&mxcsdhc1_device, &mmc1_data); + mxc_register_device(&mxcsdhc2_device, &mmc2_data); +#endif + mxc_register_device(&mxc_rtc_device, &srtc_data); + mxc_register_device(&mxc_w1_master_device, &mxc_w1_data); + mxc_register_device(&mxc_ipu_device, &mxc_ipu_data); + mxc_register_device(&mxc_tve_device, &tve_data); + mxc_register_device(&mxcvpu_device, &mxc_vpu_data); + mxc_register_device(&gpu_device, NULL); + mxc_register_device(&mxcscc_device, NULL); /* eric 20100521: SCC support */ + mxc_register_device(&mx51_lpmode_device, NULL); + mxc_register_device(&busfreq_device, NULL); + mxc_register_device(&sdram_autogating_device, NULL); + mxc_register_device(&mxc_dvfs_core_device, &dvfs_core_data); + mxc_register_device(&mxc_dvfs_per_device, &dvfs_per_data); + mxc_register_device(&mxc_iim_device, NULL); + mxc_register_device(&mxc_pwm1_device, NULL); + mxc_register_device(&mxc_pwm_backlight_device, &mxc_pwm_backlight_data); + mxc_register_device(&mxc_ssi1_device, NULL); + mxc_register_device(&mxc_ssi2_device, NULL); + mxc_register_device(&pata_fsl_device, &ata_data); + mxc_register_device(&mxc_alsa_spdif_device, &mxc_spdif_data); + mxc_register_device(&mxc_fec_device, NULL); + + mxc_init_fb(); + mxc_register_device(&mxcbl_device, NULL); + mxc_register_device(&mxc_led_device, NULL); +// printk(" [VV] invoking mx51_efikasb_init_mc13892.\n"); + mx51_efikasb_init_mc13892(); + +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) + spi_register_board_info(mxc_spi_board_info, + ARRAY_SIZE(mxc_spi_board_info)); +#endif + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + i2c_register_board_info(1, mxc_i2c1_board_info, + ARRAY_SIZE(mxc_i2c1_board_info)); +#endif + + pm_power_off = mxc_power_off; + +#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \ + || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE) + if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) { + sgtl5000_data.sysclk = 26000000; + } + + gpio_direction_output(IOMUX_TO_GPIO(AUD_MUTE_PIN), 0); + mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data); +#endif + + mx5_usb_dr_init(); + mx5_usbh1_init(); + mx51_usbh2_init(); + +#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE) + mxc_register_device(&mxc_gps_device, NULL); +#endif +} + +static void __init mx51_efikasb_timer_init(void) +{ + struct clk *uart_clk; + + /* Change the CPU voltages for TO2*/ + if (cpu_is_mx51_rev(CHIP_REV_2_0) <= 1) { + cpu_wp_auto[0].cpu_voltage = 1175000; + cpu_wp_auto[1].cpu_voltage = 1100000; + cpu_wp_auto[2].cpu_voltage = 1000000; + } + + mx51_clocks_init(32768, 24000000, 22579200, 24576000); + + uart_clk = clk_get(NULL, "uart_clk.0"); + early_console_setup(UART1_BASE_ADDR, uart_clk); +} + +static struct sys_timer mxc_timer = { + .init = mx51_efikasb_timer_init, +}; + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX51_EFIKASB data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX51_EFIKASB, "Freescale MX51 Efikasb Board") + /* Maintainer: Genesi, Inc. */ + .fixup = fixup_mxc_board, + .map_io = mx5_map_io, + .init_irq = mx5_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END + +static int __init ddr2max_setup(char *__unused) +{ + enable_ddr2max = 1; + return 1; +} + +__setup("ddr2max", ddr2max_setup); + +/* + * Workaround to solve the black screen on warm reboot aging test + * This requires to set DDR2 rate to 160MHz before booting kernel + */ +static int __init ddr2_set_max_rate(void) +{ + struct clk *tclk; + unsigned long rate; + + /*Change the DDR freq to 200MHz*/ + if (enable_ddr2max) { + tclk = clk_get(NULL, "ddr_hf_clk"); + rate = clk_round_rate(tclk, 200000000); + if (clk_get_rate(tclk) != rate) + clk_set_rate(tclk, rate); + } + + return 0; +} + +late_initcall(ddr2_set_max_rate); diff --git a/arch/arm/mach-mx5/mx51_efikasb.h b/arch/arm/mach-mx5/mx51_efikasb.h new file mode 100644 index 00000000000..99c15e79dda --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb.h @@ -0,0 +1,153 @@ +/* + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX51_EFIKASB_H__ +#define __ASM_ARCH_MXC_BOARD_MX51_EFIKASB_H__ + +/*! + * @defgroup BRDCFG_MX51 Board Configuration Options + * @ingroup MSL_MX51 + */ + +/*! + * @file mach-mx51/board-mx51_efikasb.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for Genesi MX51 Efikasb Platform. + * + * @ingroup BRDCFG_MX51 + */ + +/* + * Include Files + */ +#include + +/*! + * @name MXC UART board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 + +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR NO_IRDA +#define UART2_ENABLED 1 +/* UART 3 configuration */ +#define UART3_MODE MODE_DTE +#define UART3_IR NO_IRDA +#define UART3_ENABLED 1 +/* UART 4 configuration */ +#define UART4_MODE MODE_DCE +#define UART4_IR NO_IRDA +#define UART4_ENABLED 0 +/* UART 5 configuration */ +#define UART5_MODE MODE_DCE +#define UART5_IR NO_IRDA +#define UART5_ENABLED 0 + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +/* ron: Efikasb GPIO Pin Definition */ +#define SDHC1_CD_PIN MX51_PIN_EIM_CS2 /* MX51_PIN_GPIO1_0 */ +#define SDHC1_WP_PIN MX51_PIN_GPIO1_1 +#define SDHC2_CD_PIN MX51_PIN_GPIO1_8 +#define SDHC2_WP_PIN MX51_PIN_GPIO1_7 + +#define HUB_RESET_PIN MX51_PIN_GPIO1_5 +#define PMIC_INT_PIN MX51_PIN_GPIO1_6 +#define USB_PHY_RESET_PIN MX51_PIN_EIM_D27 + +#define WIRELESS_SW_PIN MX51_PIN_DI1_PIN12 +#define WLAN_PWRON_PIN MX51_PIN_EIM_A22 +#define WLAN_RESET_PIN MX51_PIN_EIM_A16 +#define BT_PWRON_PIN MX51_PIN_EIM_A17 +#define WWAN_PWRON_PIN MX51_PIN_CSI2_D13 + +#define LCD_LVDS_EN_PIN MX51_PIN_CSI1_D8 +#define LCD_PWRON_PIN MX51_PIN_CSI1_D9 +#define LCD_BL_PWM_PIN MX51_PIN_GPIO1_2 +#define LCD_BL_PWRON_PIN MX51_PIN_CSI2_D19 +#define LVDS_RESET_PIN MX51_PIN_DISPB2_SER_DIN +#define LVDS_PWRCTL_PIN MX51_PIN_DISPB2_SER_CLK + +#define CAM_PWRON_PIN MX51_PIN_NANDF_CS0 + +#define BATT_LOW_PIN MX51_PIN_DI1_PIN11 +#define BATT_INS_PIN MX51_PIN_DISPB2_SER_DIO +#define AC_ADAP_INS_PIN MX51_PIN_DI1_D0_CS /* MX51_PIN_CSI1_D8 */ + +#define AUD_MUTE_PIN MX51_PIN_EIM_A23 +#define HPJACK_INS_PIN MX51_PIN_DISPB2_SER_RS + +#define LID_SW_PIN MX51_PIN_CSI1_VSYNC /* Low: close, High: open */ + +#define POWER_BTN_PIN MX51_PIN_EIM_DTACK +#define SYS_PWROFF_PIN MX51_PIN_CSI2_VSYNC +#define SYS_PWRGD_PIN MX51_PIN_CSI2_PIXCLK + +/* ron: Efikasb LED Pin Definition */ +#define CAPS_LED_PIN MX51_PIN_EIM_CS0 +#define ALARM_LED_PIN MX51_PIN_GPIO1_3 + +/* ron: R1.2 borad GPIO definition */ +#define MEM_ID0_PIN MX51_PIN_EIM_LBA /* MX51_PIN_GPIO1_4 */ +#define MEM_ID1_PIN MX51_PIN_EIM_CRE + +#define SIM_CD_PIN MX51_PIN_EIM_CS1 +#define WWAN_WAKEUP_PIN MX51_PIN_CSI1_HSYNC +#define AGPS_PWRON_PIN MX51_PIN_CSI2_D12 +#define AGPS_RESET_PIN MX51_PIN_CSI2_D18 +#define AGPS_PWRSW_PIN MX51_PIN_NANDF_CS1 /* ron: R1.3 add AGPS_PWRSW */ + +/* ron: R1.3 board GPIO definition */ +#define PCB_ID0_PIN MX51_PIN_EIM_CS3 +#define PCB_ID1_PIN MX51_PIN_EIM_CS4 + +#define WDOG_PIN MX51_PIN_GPIO1_4 + +/* #define BATT_LOW_LED_PIN MX51_PIN_DI1_PIN13 */ + +extern int __init mx51_efikasb_init_mc13892(void); + +#endif /* __ASM_ARCH_MXC_BOARD_MX51_LANGE51_H__ */ diff --git a/arch/arm/mach-mx5/mx51_efikasb_gpio.c b/arch/arm/mach-mx5/mx51_efikasb_gpio.c new file mode 100644 index 00000000000..798815c7dea --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_gpio.c @@ -0,0 +1,1107 @@ +/* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "mx51_efikasb.h" +#include "iomux.h" +#include "mx51_pins.h" + +/*! + * @file mach-mx51/mx51_efikasb_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO + */ + +#define ATA_PAD_CONFIG (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH) + +void mxc_turn_on_caps_led(int); +void mxc_turn_on_num_led(int); +void mxc_turn_on_alarm_led(int); + +void mxc_power_on_wlan(int); +void mxc_power_on_wwan(int); +void mxc_power_on_bt(int); +void mxc_power_on_camera(int); +void mxc_power_on_agps(int); +void mxc_reset_wlan(void); +void mxc_reset_agps(void); +void mxc_reset_usb_hub(void); +void mxc_reset_usb_phy(void); + + +static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { + /* USBH2_DATA0 */ + { + MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | + PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA1 */ + { + MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA2 */ + { + MX51_PIN_EIM_D18, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA3 */ + { + MX51_PIN_EIM_D19, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA4 */ + { + MX51_PIN_EIM_D20, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA5 */ + { + MX51_PIN_EIM_D21, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA6 */ + { + MX51_PIN_EIM_D22, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA7 */ + { + MX51_PIN_EIM_D23, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* ron: GPIO2_10 WLAN Reset*/ + MX51_PIN_EIM_A16, IOMUX_CONFIG_GPIO, + }, + { /* ron: GPIO2_11 BT Power On */ + MX51_PIN_EIM_A17, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A18, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A19, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A20, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_EIM_A21, IOMUX_CONFIG_GPIO, + }, + { /* ron: GPIO2_16 WLAN Power On */ + MX51_PIN_EIM_A22, IOMUX_CONFIG_GPIO, + }, + { /* ron: GPIO2_17 Audio AMP mute */ + MX51_PIN_EIM_A23, IOMUX_CONFIG_GPIO, + }, + /* USBH2_CLK */ + { + MX51_PIN_EIM_A24, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DIR */ + { + MX51_PIN_EIM_A25, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_STP */ + { + MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_NXT */ + { + MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* ron: GPIO2_24 CPU 22.5792M OSC enable */ + MX51_PIN_EIM_OE, IOMUX_CONFIG_ALT1, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*ron: GPIO2_31 Power Button*/ + MX51_PIN_EIM_DTACK, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4, + }, + { /* ron: I2C1 */ + MX51_PIN_I2C1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { + MX51_PIN_I2C1_DAT, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { /* USBH1_STP */ + MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_CLK */ + MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DIR */ + MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_NXT */ + MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DATA0 */ + MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA1 */ + MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA2 */ + MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA3 */ + MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA4 */ + MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA5 */ + MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA6 */ + MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA7 */ + MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), + }, + { /*ron: GPIO1_0 SDHC1 CD*/ + MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_PKE_ENABLE | + PAD_CTL_SRE_FAST), + }, + { /*ron: GPIO1_1 SDHC1 WP */ + MX51_PIN_GPIO1_1, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_SRE_FAST), + }, + { /*ron: GPIO1_7 SDHC2 WP */ + MX51_PIN_GPIO1_7, IOMUX_CONFIG_ALT6 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_SRE_FAST), + }, + { /*ron: GPIO1_8 SDHC2 CD*/ + MX51_PIN_GPIO1_8, IOMUX_CONFIG_ALT6 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_PKE_ENABLE | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { /* ron: GPIO1_6 PMIC Interrupt */ + MX51_PIN_GPIO1_6, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_VOT_HIGH), + }, + { /* ron: UART1 */ + MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + }, + /* ron: UART 2 for AGPS */ + { + MX51_PIN_UART2_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH2, + }, + { + MX51_PIN_UART2_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_EIM_D26, IOMUX_CONFIG_ALT4, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH3, + }, + { + MX51_PIN_EIM_D25, IOMUX_CONFIG_ALT4, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { /* ron: AUD3 */ + MX51_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { /* ron: eCSPI1 */ + MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST ), + }, + { + MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST ), + }, + { /* ron: GPIO3_0 Battery Low */ + MX51_PIN_DI1_PIN11, IOMUX_CONFIG_ALT4, + }, + { /* ron: GPIO3_1 Wireless SW */ + MX51_PIN_DI1_PIN12, IOMUX_CONFIG_ALT4, + }, + { /* ron: GPIO3_2 Watchdog ? GPIO conflict with EIM_CRE*/ + MX51_PIN_DI1_PIN13, IOMUX_CONFIG_ALT4, + }, + { /* ron: GPIO4_10 WWAN Power On */ + MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT3, + }, + { /* ron: GPIO4_15 Power Good */ + MX51_PIN_CSI2_PIXCLK, IOMUX_CONFIG_ALT3, + }, + +}; + +static struct mxc_iomux_pin_cfg __initdata ata_iomux_pins[] = { + { + MX51_PIN_NANDF_ALE, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_CLE, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_RB0, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + /* TO 2.0 */ + { + MX51_PIN_GPIO_NAND, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + /* TO 1.0 */ + //{ + // MX51_PIN_NANDF_RB5, IOMUX_CONFIG_ALT1, + // ATA_PAD_CONFIG, + // }, + { + MX51_PIN_NANDF_RB1, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D0, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D1, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D2, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D3, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D4, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D5, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D6, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D7, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D8, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D9, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D10, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D11, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D13, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D14, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, + { + MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT1, + ATA_PAD_CONFIG, + }, +}; + +static void power_on_bt_handler(struct work_struct *work) +{ + mxc_power_on_bt(1); +} + +static DECLARE_DELAYED_WORK(power_on_bt_work, power_on_bt_handler); + +void __init mx51_efikasb_io_init(void) +{ + int i, num; + struct mxc_iomux_pin_cfg *pin_ptr; + + for (i = 0; i < ARRAY_SIZE(mxc_iomux_pins); i++) { + mxc_request_iomux(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].mux_mode); + if (mxc_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].pad_cfg); + if (mxc_iomux_pins[i].in_select) + mxc_iomux_set_input(mxc_iomux_pins[i].in_select, + mxc_iomux_pins[i].in_mode); + } + + // enable PATA + pin_ptr = ata_iomux_pins; + num = ARRAY_SIZE(ata_iomux_pins); + + for (i = 0; i < num; i++) { + mxc_request_iomux(pin_ptr[i].pin, + pin_ptr[i].mux_mode); + if (pin_ptr[i].pad_cfg) + mxc_iomux_set_pad(pin_ptr[i].pin, + pin_ptr[i].pad_cfg); + if (pin_ptr[i].in_select) + mxc_iomux_set_input(pin_ptr[i].in_select, + pin_ptr[i].in_mode); + } + + /* ron: USB Hub Reset*/ +/* mxc_request_iomux(HUB_RESET_PIN, IOMUX_CONFIG_ALT0); */ +/* mxc_iomux_set_pad(HUB_RESET_PIN, PAD_CTL_DRV_HIGH | */ +/* PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); */ +/* gpio_request(IOMUX_TO_GPIO(HUB_RESET_PIN), "hub_reset"); */ +/* gpio_direction_output(IOMUX_TO_GPIO(HUB_RESET_PIN), 0); */ +/* mxc_reset_usb_hub(); */ + + /* ron: USB Phy Reset */ + mxc_request_iomux(USB_PHY_RESET_PIN, IOMUX_CONFIG_ALT1); + mxc_iomux_set_pad(USB_PHY_RESET_PIN, PAD_CTL_DRV_HIGH | + PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + gpio_request(IOMUX_TO_GPIO(USB_PHY_RESET_PIN), "usb_phy_reset"); + mxc_reset_usb_phy(); + + /* ron: PMIC interrupt*/ + gpio_request(IOMUX_TO_GPIO(PMIC_INT_PIN), "pmic_int"); + gpio_direction_input(IOMUX_TO_GPIO(PMIC_INT_PIN)); + + /* ron: SDHC CD & WP */ + mxc_request_iomux(SDHC1_CD_PIN, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION); + gpio_request(IOMUX_TO_GPIO(SDHC1_CD_PIN), "sdhc1_cd"); + gpio_request(IOMUX_TO_GPIO(SDHC2_CD_PIN), "sdhc2_cd"); + gpio_direction_input(IOMUX_TO_GPIO(SDHC1_CD_PIN)); /* SD1 CD */ + gpio_direction_input(IOMUX_TO_GPIO(SDHC2_CD_PIN)); /*ron: SDHC2 CD*/ + + gpio_request(IOMUX_TO_GPIO(SDHC1_WP_PIN), "sdhc1_wp"); + gpio_request(IOMUX_TO_GPIO(SDHC2_WP_PIN), "sdhc2_wp"); + gpio_direction_input(IOMUX_TO_GPIO(SDHC1_WP_PIN)); /* SD1 WP */ + gpio_direction_input(IOMUX_TO_GPIO(SDHC2_WP_PIN)); /*ron: SDHC2 WP*/ + + /* i2c2 SDA */ + mxc_request_iomux(MX51_PIN_KEY_COL5, + IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, + INPUT_CTL_PATH1); + mxc_iomux_set_pad(MX51_PIN_KEY_COL5, + PAD_CTL_SRE_FAST | + PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE); + + /* i2c2 SCL */ + mxc_request_iomux(MX51_PIN_KEY_COL4, + IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, + INPUT_CTL_PATH1); + mxc_iomux_set_pad(MX51_PIN_KEY_COL4, + PAD_CTL_SRE_FAST | + PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE); + + /* hphone_det_b */ + mxc_request_iomux(HPJACK_INS_PIN, IOMUX_CONFIG_ALT4); + mxc_iomux_set_pad(HPJACK_INS_PIN, PAD_CTL_100K_PU); + gpio_request(IOMUX_TO_GPIO(HPJACK_INS_PIN), "hpjack_ins"); + gpio_direction_input(IOMUX_TO_GPIO(HPJACK_INS_PIN)); + + /* audio_clk_en_b */ + mxc_request_iomux(MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT3); + mxc_iomux_set_pad(MX51_PIN_CSPI1_RDY, PAD_CTL_DRV_HIGH | + PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + gpio_request(IOMUX_TO_GPIO(MX51_PIN_CSPI1_RDY), "cspi1_rdy"); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSPI1_RDY), 0); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_RDY), 0); + + /* Lid Switch */ + mxc_request_iomux(LID_SW_PIN, IOMUX_CONFIG_GPIO /* | IOMUX_CONFIG_SION */); + gpio_request(IOMUX_TO_GPIO(LID_SW_PIN), "lid_sw"); + gpio_direction_input(IOMUX_TO_GPIO(LID_SW_PIN)); + + /* Wireless*/ + mxc_power_on_wlan(1); + mxc_reset_wlan(); +/* mxc_power_on_bt(1); */ + /* ron: workaround the bluetooth detect fail */ + schedule_delayed_work(&power_on_bt_work, msecs_to_jiffies(500)); + mxc_power_on_wwan(1); + + /* Camera */ + mxc_request_iomux(CAM_PWRON_PIN, IOMUX_CONFIG_GPIO); + mxc_power_on_camera(1); + + /* LED */ + mxc_request_iomux(ALARM_LED_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(ALARM_LED_PIN), "alarm_led"); + mxc_request_iomux(CAPS_LED_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(CAPS_LED_PIN), "caps_led"); + mxc_turn_on_caps_led(0); + mxc_turn_on_alarm_led(0); + + /* LVDS & LCD Panel */ + mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK, /* ron: set driver strength to low to avoid EMI */ + PAD_CTL_PKE_ENABLE | + PAD_CTL_DRV_LOW | + PAD_CTL_SRE_FAST); + + mxc_request_iomux(LVDS_RESET_PIN, IOMUX_CONFIG_GPIO); + mxc_request_iomux(LVDS_PWRCTL_PIN, IOMUX_CONFIG_GPIO); + mxc_request_iomux(LCD_PWRON_PIN, IOMUX_CONFIG_GPIO); /* ron: LCD Power On */ + mxc_request_iomux(LCD_BL_PWRON_PIN, IOMUX_CONFIG_GPIO); /* ron: LCD Backlight Power On */ + gpio_request(IOMUX_TO_GPIO(LVDS_RESET_PIN), "lvds_reset"); + gpio_request(IOMUX_TO_GPIO(LVDS_PWRCTL_PIN), "lvds_pwrctl"); + gpio_request(IOMUX_TO_GPIO(LCD_PWRON_PIN), "lcd_pwron"); + gpio_request(IOMUX_TO_GPIO(LCD_BL_PWRON_PIN), "lcd_bl_pwron"); + gpio_direction_output(IOMUX_TO_GPIO(LVDS_RESET_PIN), 0); + gpio_direction_output(IOMUX_TO_GPIO(LVDS_PWRCTL_PIN), 0); + gpio_direction_output(IOMUX_TO_GPIO(LCD_PWRON_PIN), 0); + gpio_direction_output(IOMUX_TO_GPIO(LCD_BL_PWRON_PIN), 1); /* low active */ + + mxc_request_iomux(LCD_BL_PWM_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(LCD_BL_PWM_PIN), "lcd_bl_pwm"); + gpio_direction_output(IOMUX_TO_GPIO(LCD_BL_PWM_PIN), 0); + + mxc_request_iomux(LCD_LVDS_EN_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(LCD_LVDS_EN_PIN), "lcd_en"); + gpio_direction_output(IOMUX_TO_GPIO(LCD_LVDS_EN_PIN), 0); + + /* Battery & AC Adapter Insertion */ + mxc_request_iomux(BATT_INS_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(BATT_INS_PIN), "batt_ins"); + gpio_direction_input(IOMUX_TO_GPIO(BATT_INS_PIN)); + mxc_request_iomux(BATT_LOW_PIN, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION); + gpio_request(IOMUX_TO_GPIO(BATT_LOW_PIN), "batt_low"); + gpio_direction_input(IOMUX_TO_GPIO(BATT_LOW_PIN)); + + mxc_request_iomux(AC_ADAP_INS_PIN, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION); + /* ron: IOMUXC_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT: 1: Selecting Pad DI1_D0_CS for Mode:ALT4 */ + __raw_writel(0x01, IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x980); + gpio_request(IOMUX_TO_GPIO(AC_ADAP_INS_PIN), "ac_adap_ins"); + gpio_direction_input(IOMUX_TO_GPIO(AC_ADAP_INS_PIN)); + + /* ron: for R12 borad gpio */ + /* Memory ID pin */ + mxc_request_iomux(MEM_ID0_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MEM_ID0_PIN), "mem_id"); + gpio_direction_input(IOMUX_TO_GPIO(MEM_ID0_PIN)); + mxc_request_iomux(MEM_ID1_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MEM_ID1_PIN), "mem_id"); + gpio_direction_input(IOMUX_TO_GPIO(MEM_ID1_PIN)); + + /* SIM CD pin */ + mxc_request_iomux(SIM_CD_PIN, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION); + mxc_iomux_set_pad(SIM_CD_PIN, PAD_CTL_PKE_NONE); + gpio_request(IOMUX_TO_GPIO(SIM_CD_PIN), "sim_cd"); + gpio_direction_input(IOMUX_TO_GPIO(SIM_CD_PIN)); + + /* WWAN Wakeup event pin */ + mxc_request_iomux(WWAN_WAKEUP_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(WWAN_WAKEUP_PIN), "wwan_wakeup"); + gpio_direction_input(IOMUX_TO_GPIO(WWAN_WAKEUP_PIN)); + + /* AGPS Power & Reset */ + mxc_request_iomux(AGPS_PWRON_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(AGPS_PWRON_PIN), "agps_pwron"); + gpio_direction_output(IOMUX_TO_GPIO(AGPS_PWRON_PIN), 0); + mxc_request_iomux(AGPS_PWRSW_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(AGPS_PWRSW_PIN), "agps_pwrsw"); + gpio_direction_output(IOMUX_TO_GPIO(AGPS_PWRSW_PIN), 0); + + mxc_request_iomux(AGPS_RESET_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(AGPS_RESET_PIN), "agps_reset"); + gpio_direction_output(IOMUX_TO_GPIO(AGPS_RESET_PIN), 0); + mxc_power_on_agps(1); +/* mxc_reset_agps(); */ + + /* Watchdog */ + mxc_request_iomux(WDOG_PIN, IOMUX_CONFIG_ALT2); + + /* PCB ID */ + mxc_request_iomux(PCB_ID0_PIN, IOMUX_CONFIG_GPIO); + mxc_request_iomux(PCB_ID1_PIN, IOMUX_CONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(PCB_ID0_PIN), "pcb_id"); + gpio_request(IOMUX_TO_GPIO(PCB_ID1_PIN), "pcb_id"); + gpio_direction_input(IOMUX_TO_GPIO(PCB_ID0_PIN)); + gpio_direction_input(IOMUX_TO_GPIO(PCB_ID1_PIN)); + + /* microSD CD */ + + /* Battery Low LED */ +/* mxc_request_iomux(BATT_LOW_LED_PIN, IOMUX_CONFIG_GPIO); */ +/* gpio_request(IOMUX_TO_GPIO(BATT_LOW_LED_PIN), "batt_low_led"); */ +/* gpio_direction_output(IOMUX_TO_GPIO(BATT_LOW_LED_PIN), 0); */ + +} + +void mxc_turn_on_caps_led(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(CAPS_LED_PIN), 0); + if(on) + gpio_set_value(IOMUX_TO_GPIO(CAPS_LED_PIN), 1); + else + gpio_set_value(IOMUX_TO_GPIO(CAPS_LED_PIN), 0); + +} +EXPORT_SYMBOL(mxc_turn_on_caps_led); + +void mxc_turn_on_alarm_led(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(ALARM_LED_PIN), 0); + if(on) + gpio_set_value(IOMUX_TO_GPIO(ALARM_LED_PIN), 0); + else + gpio_set_value(IOMUX_TO_GPIO(ALARM_LED_PIN), 1); + +} +EXPORT_SYMBOL(mxc_turn_on_alarm_led); + +/* void mxc_turn_on_batt_low_led(int on) */ +/* { */ +/* gpio_direction_output(IOMUX_TO_GPIO(BATT_LOW_LED_PIN), 0); */ +/* if(on) */ +/* gpio_set_value(IOMUX_TO_GPIO(BATT_LOW_LED_PIN), 1); */ +/* else */ +/* gpio_set_value(IOMUX_TO_GPIO(BATT_LOW_LED_PIN), 0); */ +/* } */ +/* EXPORT_SYMBOL(mxc_turn_on_batt_low_led); */ + +struct mxc_power_switch_status { + int wlan_pwr_status; + int wwan_pwr_status; + int bt_pwr_status; + int camera_pwr_status; + int agps_pwr_status; +}; + +static struct mxc_power_switch_status pwr_sw_status = { + .wlan_pwr_status = 0, + .wwan_pwr_status = 0, + .bt_pwr_status = 0, + .camera_pwr_status = 0, + .agps_pwr_status = 0, +}; + +int mxc_get_power_status(iomux_pin_name_t pin) +{ + switch(pin) { + case WLAN_PWRON_PIN: + return pwr_sw_status.wlan_pwr_status; + case WWAN_PWRON_PIN: + return pwr_sw_status.wwan_pwr_status; + case BT_PWRON_PIN: + return pwr_sw_status.bt_pwr_status; + case CAM_PWRON_PIN: + return pwr_sw_status.camera_pwr_status; + case AGPS_PWRON_PIN: + return pwr_sw_status.agps_pwr_status; + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(mxc_get_power_status); + +void mxc_power_on_wlan(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(WLAN_PWRON_PIN), 0); + if (on) + gpio_set_value(IOMUX_TO_GPIO(WLAN_PWRON_PIN), 1); + else + gpio_set_value(IOMUX_TO_GPIO(WLAN_PWRON_PIN), 0); + + pwr_sw_status.wlan_pwr_status = on; + +} +EXPORT_SYMBOL(mxc_power_on_wlan); + +void mxc_power_on_wwan(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(WWAN_PWRON_PIN), 0); + if (on) + gpio_set_value(IOMUX_TO_GPIO(WWAN_PWRON_PIN), 0); /* low active */ + else + gpio_set_value(IOMUX_TO_GPIO(WWAN_PWRON_PIN), 1); + + pwr_sw_status.wwan_pwr_status = on; + +} +EXPORT_SYMBOL(mxc_power_on_wwan); + +void mxc_power_on_bt(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(BT_PWRON_PIN), 0); + if (on) + gpio_set_value(IOMUX_TO_GPIO(BT_PWRON_PIN), 1); + else + gpio_set_value(IOMUX_TO_GPIO(BT_PWRON_PIN), 0); + + pwr_sw_status.bt_pwr_status = on; + +} +EXPORT_SYMBOL(mxc_power_on_bt); + +void mxc_power_on_camera(int on) +{ + gpio_direction_output(IOMUX_TO_GPIO(CAM_PWRON_PIN), 0); + if(on) + gpio_set_value(IOMUX_TO_GPIO(CAM_PWRON_PIN), 0); /* low active */ + else + gpio_set_value(IOMUX_TO_GPIO(CAM_PWRON_PIN), 1); + + pwr_sw_status.camera_pwr_status = on; + +} +EXPORT_SYMBOL(mxc_power_on_camera); + +void mxc_power_on_agps(int on) +{ + if(on) { + gpio_set_value(IOMUX_TO_GPIO(AGPS_PWRSW_PIN), 0); /* active low */ + gpio_set_value(IOMUX_TO_GPIO(AGPS_RESET_PIN), 1); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(AGPS_PWRON_PIN), 1); + + } else { + gpio_set_value(IOMUX_TO_GPIO(AGPS_PWRON_PIN), 0); + gpio_set_value(IOMUX_TO_GPIO(AGPS_PWRSW_PIN), 1); + + } + pwr_sw_status.agps_pwr_status = on; + +} +EXPORT_SYMBOL(mxc_power_on_agps); + +void mxc_reset_wlan(void) +{ + gpio_direction_output(IOMUX_TO_GPIO(WLAN_RESET_PIN), 1); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(WLAN_RESET_PIN), 0); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(WLAN_RESET_PIN), 1); +} +EXPORT_SYMBOL(mxc_reset_wlan); + +void mxc_reset_usb_hub(void) +{ + gpio_direction_output(IOMUX_TO_GPIO(HUB_RESET_PIN), 1); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(HUB_RESET_PIN), 0); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(HUB_RESET_PIN), 1); +} +EXPORT_SYMBOL(mxc_reset_usb_hub); + + +void mxc_reset_usb_phy(void) +{ + gpio_direction_output(IOMUX_TO_GPIO(USB_PHY_RESET_PIN), 0); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(USB_PHY_RESET_PIN), 1); + +} +EXPORT_SYMBOL(mxc_reset_usb_phy); + +void mxc_reset_agps(void) +{ + gpio_direction_output(IOMUX_TO_GPIO(AGPS_RESET_PIN), 1); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(AGPS_RESET_PIN), 0); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(AGPS_RESET_PIN), 1); + +} +EXPORT_SYMBOL(mxc_reset_agps); + +int mxc_get_battery_insertion_status(void) +{ + return !gpio_get_value(IOMUX_TO_GPIO(BATT_INS_PIN)); +} +EXPORT_SYMBOL(mxc_get_battery_insertion_status); + +int mxc_get_batt_low_status(void) +{ + return !gpio_get_value(IOMUX_TO_GPIO(BATT_LOW_PIN)); +} +EXPORT_SYMBOL(mxc_get_batt_low_status); + +int mxc_get_ac_adapter_insertion_status(void) +{ + return !gpio_get_value(IOMUX_TO_GPIO(AC_ADAP_INS_PIN)); +} +EXPORT_SYMBOL(mxc_get_ac_adapter_insertion_status); + +int mxc_get_sim_card_status(void) +{ + return !gpio_get_value(IOMUX_TO_GPIO(SIM_CD_PIN)); +} +EXPORT_SYMBOL(mxc_get_sim_card_status); + + +/* ron: 00 Nanya DDR2 + 10 Micron DDR2 + 01 Hynix DDR2 */ +int mxc_get_memory_id(void) +{ + int id; + + id = gpio_get_value(IOMUX_TO_GPIO(MEM_ID0_PIN)); + id |= gpio_get_value(IOMUX_TO_GPIO(MEM_ID1_PIN)) << 1; + + return id; +} +EXPORT_SYMBOL(mxc_get_memory_id); + +int mxc_get_wireless_sw_status(void) +{ + return !gpio_get_value(IOMUX_TO_GPIO(WIRELESS_SW_PIN)); +} +EXPORT_SYMBOL(mxc_get_wireless_sw_status); + +int mxc_get_lid_sw_status(void) +{ + /* ron: 0:open 1:close */ + return !gpio_get_value(IOMUX_TO_GPIO(LID_SW_PIN)); +} +EXPORT_SYMBOL(mxc_get_lid_sw_status); + +/* ron: 01 R1.3 board + 10 R2.0 board */ +int mxc_get_pcb_id(void) +{ + int id; + + id = gpio_get_value(IOMUX_TO_GPIO(PCB_ID0_PIN)); + id |= gpio_get_value(IOMUX_TO_GPIO(PCB_ID1_PIN)) << 1; + + return id; +} +EXPORT_SYMBOL(mxc_get_pcb_id); + +/* workaround for ecspi chipselect pin may not keep correct level when idle */ +void mx51_efikasb_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + mxc_request_iomux(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0, + PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + mxc_request_iomux(MX51_PIN_CSPI1_SS1, + IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), 0); +/* gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), 2 & (~status)); */ + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), !(status & 0x02)); + break; + case 0x2: + mxc_request_iomux(MX51_PIN_CSPI1_SS1, + IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_CSPI1_SS1, + PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + mxc_request_iomux(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), 0); +/* gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), 1 & (~status)); */ + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), !(status & 0x01)); + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} +EXPORT_SYMBOL(mx51_efikasb_gpio_spi_chipselect_active); + +void mx51_efikasb_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0); + mxc_free_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_GPIO); + mxc_request_iomux(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO); + + break; + case 0x2: + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0); + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } + +} +EXPORT_SYMBOL(mx51_efikasb_gpio_spi_chipselect_inactive); + diff --git a/arch/arm/mach-mx5/mx51_efikasb_idle_timer.c b/arch/arm/mach-mx5/mx51_efikasb_idle_timer.c new file mode 100644 index 00000000000..b2898360eb7 --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_idle_timer.c @@ -0,0 +1,251 @@ +/* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mx51_efikasb.h" +#include "iomux.h" + +#define DEFAULT_PERIOD 60 +#define IDLE_EVENT 1 + +void mxc_reset_idle_timer(void); + +struct efikasb_idle_timer { + int enable; + int timeout; + spinlock_t lock; + struct timer_list timer; + unsigned long period; /* in second */ +}; + +static struct efikasb_idle_timer *idle_timer = NULL; + +static BLOCKING_NOTIFIER_HEAD(idle_notifier_list); + +int register_idle_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&idle_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(register_idle_notifier); + +int unregister_idle_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&idle_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_idle_notifier); + +static int key_event_call(struct notifier_block *blk, unsigned long code, void *_param) +{ + + switch (code) { + case KBD_KEYCODE: + mxc_reset_idle_timer(); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static struct notifier_block key_nb = { + .notifier_call = key_event_call, +}; + +static void idle_timeout_fn(unsigned long data) +{ + struct efikasb_idle_timer *efikasb_timer = (struct efikasb_idle_timer *)data; + unsigned long flags; + + spin_lock_irqsave(&efikasb_timer->lock, flags); + + efikasb_timer->timeout = 1; + efikasb_timer->enable = 0; + + spin_unlock_irqrestore(&efikasb_timer->lock, flags); + + blocking_notifier_call_chain(&idle_notifier_list, IDLE_EVENT, 1); + +} + +static void idle_timer_enable(void) +{ + unsigned long flags; + + if(idle_timer->enable && timer_pending(&idle_timer->timer)) + return; + + spin_lock_irqsave(&idle_timer->lock, flags); + + idle_timer->timer.data = (unsigned long)idle_timer; + idle_timer->timer.function = idle_timeout_fn; + if(idle_timer->period == 0) + idle_timer->period = DEFAULT_PERIOD; + + idle_timer->timer.expires = jiffies + idle_timer->period * HZ; + + add_timer(&idle_timer->timer); + idle_timer->enable = 1; + idle_timer->timeout = 0; + + spin_unlock_irqrestore(&idle_timer->lock, flags); +} + +static void idle_timer_disable(void) +{ + unsigned long flags; + + if(!idle_timer->enable && !timer_pending(&idle_timer->timer)) + return; + + spin_lock_irqsave(&idle_timer->lock, flags); + + del_timer(&idle_timer->timer); + idle_timer->enable = 0; + idle_timer->timeout = 0; + + spin_unlock_irqrestore(&idle_timer->lock, flags); +} + +static void idle_timer_reset(void) +{ + unsigned long flags; + + if(!idle_timer->enable && !timer_pending(&idle_timer->timer)) + return; + + spin_lock_irqsave(&idle_timer->lock, flags); + + mod_timer(&idle_timer->timer, jiffies + idle_timer->period * HZ); + idle_timer->timeout = 0; + + spin_unlock_irqrestore(&idle_timer->lock, flags); +} + +static ssize_t timer_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", idle_timer->enable); +} + +static ssize_t timer_enable_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + if(strncmp(buf, "1", 1) == 0) + idle_timer_enable(); + else if(strncmp(buf, "0", 1) == 0) + idle_timer_disable(); + + return count; + +} + +static ssize_t timer_period_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", (unsigned int) idle_timer->period); +} + +static ssize_t timer_period_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + int arg; + + arg = simple_strtoul(buf, &end, 10); + if(arg < 0) { + return -EINVAL; + } + + idle_timer->period = arg; + idle_timer_reset(); + + return count; + +} + +static ssize_t timer_timeout_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + + if (!idle_timer->enable) + return sprintf(buf, "0\n"); + else + return sprintf(buf, "%d\n", + jiffies_to_msecs(idle_timer->timer.expires - jiffies) / 1000); +} + + + +static struct kobj_attribute timer_enable_attribute = + __ATTR(enable, 0666, timer_enable_show, timer_enable_store); +static struct kobj_attribute timer_period_attribute = + __ATTR(period, 0666, timer_period_show, timer_period_store); +static struct kobj_attribute timer_timeout_attribute = + __ATTR(timeout, S_IFREG | S_IRUGO, timer_timeout_show, NULL); + +static struct attribute *idle_attrs[] = { + &timer_enable_attribute.attr, + &timer_period_attribute.attr, + &timer_timeout_attribute.attr, + NULL, +}; + +static struct attribute_group idle_attr_group = { + .attrs = idle_attrs, +}; + +static struct platform_device mxc_idle_timer_dev = { + .name = "mxc_idle_timer", +}; + +static int __init mxc_init_idle_timer(void) +{ + int retval; + static struct kobject *idle_timer_kobj; + + platform_device_register(&mxc_idle_timer_dev); + + idle_timer_kobj = kobject_create_and_add("setting", &mxc_idle_timer_dev.dev.kobj); + if(!idle_timer_kobj) + return -ENOMEM; + + retval = sysfs_create_group(idle_timer_kobj, &idle_attr_group); + if(retval) { + kobject_put(idle_timer_kobj); + return retval; + } + + idle_timer = kzalloc(sizeof(*idle_timer), GFP_KERNEL); + if(!idle_timer) { + sysfs_remove_group(idle_timer_kobj, &idle_attr_group); + kobject_put(idle_timer_kobj); + return -ENOMEM; + } + + init_timer(&idle_timer->timer); + idle_timer->lock = SPIN_LOCK_UNLOCKED; + + register_keyboard_notifier(&key_nb); + + return 0; +} +late_initcall(mxc_init_idle_timer); + +void mxc_reset_idle_timer(void) +{ + if(idle_timer->timeout) { + blocking_notifier_call_chain(&idle_notifier_list, IDLE_EVENT, 0); + } else { + idle_timer_reset(); + } +} +EXPORT_SYMBOL(mxc_reset_idle_timer); + diff --git a/arch/arm/mach-mx5/mx51_efikasb_input.c b/arch/arm/mach-mx5/mx51_efikasb_input.c new file mode 100644 index 00000000000..d7623604e82 --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_input.c @@ -0,0 +1,471 @@ +/* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + */ + + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mx51_efikasb.h" +#include "mx51_pins.h" +#include "iomux.h" + +int wireless_sw_state; + +extern int mxc_get_battery_insertion_status(void); +extern int mxc_get_batt_low_status(void); +extern int mxc_get_ac_adapter_insertion_status(void); +extern int mxc_get_wireless_sw_status(void); +extern int mxc_get_sim_card_status(void); + +extern void mxc_power_on_wlan(int on); +extern void efikasb_power_on_wwan(int val); +extern void efikasb_power_on_bt(int val); + +extern int register_idle_notifier(struct notifier_block *); +extern int unregister_idle_notifier(struct notifier_block *); +extern void mxc_reset_idle_timer(void); + +extern int lid_wake_enable; +extern int mxc_get_lid_sw_status(void); + +extern void kernel_power_off(void); + +static struct input_dev *efikasb_inputdev; +static int system_is_resuming = 0; + +#ifdef CONFIG_EFIKASB_EXPERIMENTAL_OS +static void power_off_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(power_off_work, power_off_worker); +#endif + +/*! + * Power Key interrupt handler. + */ +static irqreturn_t power_key_int(int irq, void *dev_id) +{ + static int key_pressed = 0; + int pk_pressed; + + /* ron: Don't report power key event if system is resuming */ + if(system_is_resuming) + return IRQ_HANDLED; + + pk_pressed = !gpio_get_value(IOMUX_TO_GPIO(POWER_BTN_PIN)); + if (pk_pressed) { + if (key_pressed) + return 0; + key_pressed = 1; + pr_info("PWR key pressed\n"); + /* ron: input_report_key(pk_dev, KEY_POWER, pk_pressed); */ + set_irq_type(irq, IRQF_TRIGGER_RISING); /* ron: detect falling edge */ + + if(lid_wake_enable) + enable_irq_wake(IOMUX_TO_IRQ(LID_SW_PIN)); + + input_report_key(efikasb_inputdev, KEY_POWER, 1); + input_sync(efikasb_inputdev); + } else { + if (!key_pressed) + return 0; + key_pressed = 0; + pr_info("PWR Key released\n"); + /* ron: input_report_key(pk_dev, KEY_POWER, pk_released); */ + set_irq_type(irq, IRQF_TRIGGER_FALLING); /* ron: detect falling edge */ + input_report_key(efikasb_inputdev, KEY_POWER, 0); + input_sync(efikasb_inputdev); + } + + return IRQ_HANDLED; +} + +static int mxc_init_power_key(void) +{ + int ret; + int irq; + + /* ron: set power key as wakeup source */ + gpio_request(IOMUX_TO_GPIO(POWER_BTN_PIN), "power_btn"); + gpio_direction_input(IOMUX_TO_GPIO(POWER_BTN_PIN)); + irq = IOMUX_TO_IRQ(POWER_BTN_PIN); + set_irq_type(irq, IRQF_TRIGGER_FALLING); /* ron: detect rising & falling edge */ + + ret = request_irq(irq, power_key_int, 0, "power_key", 0); + if (ret) + pr_info("register on-off key interrupt failed\n"); + else + enable_irq_wake(irq); + + return ret; + +} + +#define KEY_RESUME KEY_WAKEUP + +static int pm_notifier_call(struct notifier_block *nb, unsigned long event, void *dummy) +{ + switch (event) { + case PM_SUSPEND_PREPARE: + printk("System Suspending .....\n"); + system_is_resuming = 1; + return NOTIFY_OK; + + case PM_POST_SUSPEND: + printk("System Resumed\n"); + system_is_resuming = 0; + input_event(efikasb_inputdev, EV_PWR, KEY_RESUME, 1); + input_sync(efikasb_inputdev); + + return NOTIFY_OK; + + } + + return NOTIFY_DONE; +} + + +static struct notifier_block pm_nb = { + .notifier_call = pm_notifier_call, +}; + + +#define EVENT_IDLE 1 +static int idle_notifier_call(struct notifier_block *nb, unsigned long event, void *v) +{ + int value = (int) v; + + switch(event) { + case EVENT_IDLE: + input_event(efikasb_inputdev, EV_PWR, KEY_SUSPEND, value); + input_sync(efikasb_inputdev); + return NOTIFY_OK; + + } + + return NOTIFY_DONE; + +} + +static struct notifier_block idle_nb = { + .notifier_call = idle_notifier_call, +}; + + +static irqreturn_t wireless_sw_int(int irq, void *dev_id) +{ + wireless_sw_state = gpio_get_value(IOMUX_TO_GPIO(WIRELESS_SW_PIN)); + + if (wireless_sw_state) { + pr_info("Wireless SW Off\n"); + set_irq_type(irq, IRQF_TRIGGER_FALLING); + input_report_switch(efikasb_inputdev, SW_RFKILL_ALL, 0); + input_sync(efikasb_inputdev); + // power off WLAN, WWAN and BT by H/W + } else { + pr_info("Wireless SW On\n"); + set_irq_type(irq, IRQF_TRIGGER_RISING); + input_report_switch(efikasb_inputdev, SW_RFKILL_ALL, 1); + input_sync(efikasb_inputdev); + } + + return IRQ_HANDLED; +} + +static int mxc_init_wireless_sw(void) +{ + int irq, ret; + + gpio_request(IOMUX_TO_GPIO(WIRELESS_SW_PIN), "wireless_sw"); + gpio_direction_input(IOMUX_TO_GPIO(WIRELESS_SW_PIN)); + irq = IOMUX_TO_IRQ(WIRELESS_SW_PIN); + + if (gpio_get_value(IOMUX_TO_GPIO(WIRELESS_SW_PIN))) + set_irq_type(irq, IRQF_TRIGGER_FALLING); + else + set_irq_type(irq, IRQF_TRIGGER_RISING); + + ret = request_irq(irq, wireless_sw_int, 0, "wireless-sw", 0); + + if (ret) + pr_info("register wireless switch interrupt failed\n"); + + wireless_sw_state = gpio_get_value(IOMUX_TO_GPIO(WIRELESS_SW_PIN)); + + return ret; + +} + +static irqreturn_t sim_detect_int(int irq, void *dev_id) +{ + if(mxc_get_sim_card_status()) { /* ron: low active */ + set_irq_type(irq, IRQF_TRIGGER_RISING); + pr_info("SIM card inserted\n"); + } else { + set_irq_type(irq, IRQF_TRIGGER_FALLING); + pr_info("SIM card removed\n"); + } + + return IRQ_HANDLED; +} + +static int mxc_init_sim_detect(void) +{ + int irq, ret; + + irq = IOMUX_TO_IRQ(SIM_CD_PIN); + + if(mxc_get_sim_card_status()) /* ron: low active */ + set_irq_type(irq, IRQF_TRIGGER_RISING); + else + set_irq_type(irq, IRQF_TRIGGER_FALLING); + + ret = request_irq(irq, sim_detect_int, 0, "sim-detect", 0); + if(ret) + pr_info("register SIM card detect interrupt failed\n"); + + return ret; +} +/* late_initcall(mxc_init_sim_detect); */ + +#ifdef CONFIG_EFIKASB_EXPERIMENTAL_OS +static irqreturn_t efikasb_battery_detect_handler(int irq, void *data) +{ + int batt_in; + + batt_in = mxc_get_battery_insertion_status(); + printk("efikasb_battery: Battery %s\n", + batt_in ? "Inserted" : "Removed"); + + input_report_switch(efikasb_inputdev, SW_BATT_IN, batt_in); + input_sync(efikasb_inputdev); + + if (batt_in) + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + else + set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + + return IRQ_HANDLED; +} + + +static irqreturn_t efikasb_ac_charger_detect_handler(int irq, void *data) +{ + int ac_in; + + ac_in = mxc_get_ac_adapter_insertion_status(); + printk("efikasb_ac_charger: AC %s\n", + ac_in ? "Inserted" : "Removed"); + + input_report_switch(efikasb_inputdev, SW_AC_INSERT, ac_in); + input_sync(efikasb_inputdev); + + if (ac_in) + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + else + set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + + return IRQ_HANDLED; +} + +static void power_off_worker(struct work_struct *work) +{ + if(!mxc_get_ac_adapter_insertion_status() && + mxc_get_batt_low_status()) { + sys_sync(); + kernel_power_off(); + } +} + +static irqreturn_t efikasb_batt_low_handler(int irq, void *data) +{ + int batt_low; + + batt_low = mxc_get_batt_low_status(); + printk("efikasb_batter: Battery %s\n", + batt_low ? "Low" : "Normal"); + + input_event(efikasb_inputdev, EV_PWR, KEY_BATTERY, batt_low); + input_sync(efikasb_inputdev); + + if (batt_low) { + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH/* IRQ_TYPE_EDGE_RISING */); + printk("Battery critical low, shutdown now....\n"); + schedule_delayed_work(&power_off_work, msecs_to_jiffies(1000)); + } else { + set_irq_type(irq, IRQ_TYPE_LEVEL_LOW/* IRQ_TYPE_EDGE_FALLING */); + } + + return IRQ_HANDLED; +} + +static int mxc_init_battery(void) +{ + int ret; + int batt_low; + int batt_in, ac_in; + batt_in = mxc_get_battery_insertion_status(); + if(batt_in) { + ret = request_irq(IOMUX_TO_IRQ(BATT_INS_PIN), + efikasb_battery_detect_handler, + IRQ_TYPE_EDGE_RISING, "efikasb_battery", NULL); + } else { + ret = request_irq(IOMUX_TO_IRQ(BATT_INS_PIN), + efikasb_battery_detect_handler, + IRQ_TYPE_EDGE_FALLING, "efikasb_battery", NULL); + } + + ac_in = mxc_get_ac_adapter_insertion_status(); + if(ac_in) { + ret = request_irq(IOMUX_TO_IRQ(AC_ADAP_INS_PIN), + efikasb_ac_charger_detect_handler, + IRQ_TYPE_EDGE_RISING, "efikasb_ac_charger", NULL); + } else { + ret = request_irq(IOMUX_TO_IRQ(AC_ADAP_INS_PIN), + efikasb_ac_charger_detect_handler, + IRQ_TYPE_EDGE_FALLING, "efikasb_ac_charger", NULL); + } + + + batt_low = mxc_get_batt_low_status(); + if(batt_low) { + ret = request_irq(IOMUX_TO_IRQ(BATT_LOW_PIN), + efikasb_batt_low_handler, + IRQ_TYPE_LEVEL_HIGH, "efikasb_batt_low", NULL); + } else { + ret = request_irq(IOMUX_TO_IRQ(BATT_LOW_PIN), + efikasb_batt_low_handler, + IRQ_TYPE_LEVEL_LOW, "efikasb_batt_low", NULL); + } + enable_irq_wake(IOMUX_TO_IRQ(BATT_LOW_PIN)); + + /* ron: if battery critical low, shutdown immediately */ + if(!mxc_get_ac_adapter_insertion_status() && batt_low) { + printk("Battery critical low, shutdown now....\n"); + schedule_delayed_work(&power_off_work, msecs_to_jiffies(1000)); + } + + return ret; +} +#endif /* CONFIG_EFIKASB_EXPERIMENTAL_OS */ + +static ssize_t sim_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", mxc_get_sim_card_status()); +} + +static ssize_t wireless_sw_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", mxc_get_wireless_sw_status()); +} + +static ssize_t batt_low_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", mxc_get_batt_low_status()); +} + +static struct kobj_attribute sim_status_attribute = + __ATTR(sim, S_IFREG | S_IRUGO, sim_status_show, NULL); +static struct kobj_attribute wireless_sw_status_attribute = + __ATTR(wireless_sw, S_IFREG | S_IRUGO, wireless_sw_status_show, NULL); +static struct kobj_attribute batt_low_status_attribute = + __ATTR(battery_low, S_IFREG | S_IRUGO, batt_low_status_show, NULL); + +static struct attribute *status_attrs[] = { + &sim_status_attribute.attr, + &wireless_sw_status_attribute.attr, + &batt_low_status_attribute.attr, + NULL, +}; + +static struct attribute_group status_attr_group = { + .attrs = status_attrs, +}; + +static struct platform_device mxc_efikasb_input_dev = { + .name = "efikasb_input", +}; + +static int __init mxc_init_efikasb_inputdev(void) +{ + int ret; + struct kobject *efikasb_input_kobj; + + platform_device_register(&mxc_efikasb_input_dev); + + efikasb_input_kobj = kobject_create_and_add("status", &mxc_efikasb_input_dev.dev.kobj); + if(!efikasb_input_kobj) + return -ENOMEM; + + ret = sysfs_create_group(efikasb_input_kobj, &status_attr_group); + if(ret) { + kobject_put(efikasb_input_kobj); + return ret; + } + + efikasb_inputdev = input_allocate_device(); + if (!efikasb_inputdev) { + pr_err("Failed to allocate hotkey input device\n"); + return -ENOMEM; + } + efikasb_inputdev->name = "Genesi Efikasb Extra Buttons"; + efikasb_inputdev->phys = "genesi-efikasb/input0"; + efikasb_inputdev->uniq = "genesi-efikasb"; + efikasb_inputdev->id.bustype = BUS_HOST; + efikasb_inputdev->id.vendor = PCI_VENDOR_ID_FREESCALE; + set_bit(KEY_POWER, efikasb_inputdev->keybit); + set_bit(KEY_SLEEP, efikasb_inputdev->keybit); + set_bit(KEY_WAKEUP, efikasb_inputdev->keybit); + set_bit(EV_KEY, efikasb_inputdev->evbit); + set_bit(EV_PWR, efikasb_inputdev->evbit); + + set_bit(SW_RFKILL_ALL, efikasb_inputdev->swbit); + if(mxc_get_wireless_sw_status()) + set_bit(SW_RFKILL_ALL, efikasb_inputdev->sw); + + /* ron: I known this is not a regular approach, + but Lenovo requests, I can't resist*/ +#ifdef CONFIG_EFIKASB_EXPERIMENTAL_OS + set_bit(SW_AC_INSERT, efikasb_inputdev->swbit); + if(mxc_get_ac_adapter_insertion_status()) + set_bit(SW_AC_INSERT, efikasb_inputdev->sw); + + set_bit(SW_BATT_IN, efikasb_inputdev->swbit); + if(mxc_get_battery_insertion_status()) + set_bit(SW_BATT_IN, efikasb_inputdev->sw); +#endif + + ret = input_register_device(efikasb_inputdev); + if (ret) { + input_free_device(efikasb_inputdev); + pr_err("Failed to register hotkey input device\n"); + sysfs_remove_group(efikasb_input_kobj, &status_attr_group); + kobject_put(efikasb_input_kobj); + return -ENODEV; + } + + mxc_init_power_key(); + +#ifdef CONFIG_EFIKASB_EXPERIMENTAL_OS + mxc_init_battery(); +#endif + mxc_init_sim_detect(); + mxc_init_wireless_sw(); + + register_pm_notifier(&pm_nb); + register_idle_notifier(&idle_nb); + + return ret; +} + +late_initcall(mxc_init_efikasb_inputdev); + diff --git a/arch/arm/mach-mx5/mx51_efikasb_lid.c b/arch/arm/mach-mx5/mx51_efikasb_lid.c new file mode 100644 index 00000000000..e30e2a94ee3 --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_lid.c @@ -0,0 +1,195 @@ +/* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mx51_efikasb.h" +#include "mx51_pins.h" +#include "iomux.h" + +int lid_wake_enable = 0; +extern int mxc_get_lid_sw_status(void); +extern void mxc_reset_idle_timer(void); + +static struct input_dev *efikasb_lid_inputdev; + +static struct platform_device efikasb_lid_dev = { + .name = "efikasb_lid", +}; + +static irqreturn_t lid_sw_int(int irq, void *dev_id) +{ + int lid_close; + + mxc_reset_idle_timer(); + lid_close = mxc_get_lid_sw_status(); + if(lid_close) { + pr_info("Lid Switch Close\n"); + set_irq_type(irq, IRQF_TRIGGER_RISING); + + if(lid_wake_enable) + enable_irq_wake(irq); + + input_report_switch(efikasb_lid_inputdev, SW_LID, lid_close); + input_sync(efikasb_lid_inputdev); + + } else { + pr_info("Lid Switch Open\n"); + set_irq_type(irq, IRQF_TRIGGER_FALLING); + + input_report_switch(efikasb_lid_inputdev, SW_LID, lid_close); + input_sync(efikasb_lid_inputdev); + + if(lid_wake_enable) + disable_irq_wake(irq); + } + + return IRQ_HANDLED; +} + +static int mxc_init_lid_sw(void) +{ + int irq, ret; + + gpio_request(IOMUX_TO_GPIO(LID_SW_PIN), "lid_sw"); + gpio_direction_input(IOMUX_TO_GPIO(LID_SW_PIN)); + irq = IOMUX_TO_IRQ(LID_SW_PIN); + + if(mxc_get_lid_sw_status()) { + pr_info("Lid Switch Close\n"); + set_irq_type(irq, IRQF_TRIGGER_RISING); + } else { + pr_info("Lid Switch Open\n"); + set_irq_type(irq, IRQF_TRIGGER_FALLING); + } + + ret = request_irq(irq, lid_sw_int, 0, "lid-sw", 0); + if(ret) + pr_info("register lid switch interrupt failed\n"); + + return ret; +} + +static ssize_t lid_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", mxc_get_lid_sw_status()); +} + +static ssize_t lid_wake_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", lid_wake_enable ? "on": "off"); +} + +static ssize_t lid_wake_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + if(strncmp(buf, "on", 2) == 0) + lid_wake_enable = 1; + else if (strncmp(buf, "off", 3) == 0) + lid_wake_enable = 0; + else + return -EINVAL; + + return count; +} + +static struct kobj_attribute lid_status_attribute = + __ATTR(lid, S_IFREG | S_IRUGO, lid_status_show, NULL); +static struct kobj_attribute lid_wake_attribute = + __ATTR(lid_wake, 0666, lid_wake_show, lid_wake_store); + +static struct attribute *status_attrs[] = { + &lid_status_attribute.attr, + &lid_wake_attribute.attr, + NULL, +}; + +static struct attribute_group status_attr_group = { + .attrs = status_attrs, +}; + +static void __init lid_wake_setup(char **p) +{ + if(memcmp(*p, "on", 2) == 0) { + lid_wake_enable = 1; + *p += 2; + } else if(memcmp(*p, "off", 3) == 0) { + lid_wake_enable = 0; + *p += 3; + } +} + +__early_param("lid_wake=", lid_wake_setup); + +static int __init mxc_init_efikasb_lid(void) +{ + int ret ; + struct kobject *lid_kobj; + + platform_device_register(&efikasb_lid_dev); + + lid_kobj = kobject_create_and_add("status", &efikasb_lid_dev.dev.kobj); + if(!lid_kobj) { + ret = -ENOMEM; + goto err3; + } + + ret = sysfs_create_group(lid_kobj, &status_attr_group); + if(ret) { + goto err2; + } + + efikasb_lid_inputdev = input_allocate_device(); + if(!efikasb_lid_inputdev) { + pr_err("Failed to allocate lid input device\n"); + ret = -ENOMEM; + goto err2; + } + + efikasb_lid_inputdev->name = "Efikasb Lid Switch"; + efikasb_lid_inputdev->phys = "Efikasb/input1"; + efikasb_lid_inputdev->uniq = "Efikasb"; + efikasb_lid_inputdev->id.bustype = BUS_HOST; + efikasb_lid_inputdev->id.vendor = PCI_VENDOR_ID_FREESCALE; + + set_bit(EV_SW, efikasb_lid_inputdev->evbit); + set_bit(SW_LID, efikasb_lid_inputdev->swbit); + + /* ron: 0:open 1:close */ + if(mxc_get_lid_sw_status()) + set_bit(SW_LID, efikasb_lid_inputdev->sw); + + ret = input_register_device(efikasb_lid_inputdev); + if(ret) { + pr_err("Failed to register Efikasb lid input device\n"); + ret = -ENODEV; + goto err1; + } + + mxc_init_lid_sw(); + + return ret; + + err1: + input_free_device(efikasb_lid_inputdev); + err2: + kobject_put(lid_kobj); + err3: + platform_device_unregister(&efikasb_lid_dev); + + return ret; + + +} + +late_initcall(mxc_init_efikasb_lid); diff --git a/arch/arm/mach-mx5/mx51_efikasb_pmic.c b/arch/arm/mach-mx5/mx51_efikasb_pmic.c new file mode 100644 index 00000000000..2e5286c017c --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_pmic.c @@ -0,0 +1,419 @@ +/* + * mx51-efikasb-pmic-mc13892.c -- i.MX51 Efikasb Driver for Atlas MC13892 PMIC + */ + /* + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + */ + + /* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iomux.h" +#include "mx51_pins.h" + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +/* Coin cell charger enable */ +#define COINCHEN_LSH 23 +#define COINCHEN_WID 1 +/* Coin cell charger voltage setting */ +#define VCOIN_LSH 20 +#define VCOIN_WID 3 + +/* Coin Charger voltage */ +#define VCOIN_2_5V 0x0 +#define VCOIN_2_7V 0x1 +#define VCOIN_2_8V 0x2 +#define VCOIN_2_9V 0x3 +#define VCOIN_3_0V 0x4 +#define VCOIN_3_1V 0x5 +#define VCOIN_3_2V 0x6 +#define VCOIN_3_3V 0x7 + +/* regulator standby mask */ +#define GEN1_STBY_MASK (1 << 1) +#define IOHI_STBY_MASK (1 << 4) +#define DIG_STBY_MASK (1 << 10) +#define GEN2_STBY_MASK (1 << 13) +#define PLL_STBY_MASK (1 << 16) +#define USB2_STBY_MASK (1 << 19) + +#define GEN3_STBY_MASK (1 << 1) +#define CAM_STBY_MASK (1 << 7) +#define VIDEO_STBY_MASK (1 << 13) +#define AUDIO_STBY_MASK (1 << 16) +#define SD_STBY_MASK (1 << 19) + +/* 0x92412 */ +#define REG_MODE_0_ALL_MASK (GEN1_STBY_MASK |\ + DIG_STBY_MASK | GEN2_STBY_MASK |\ + PLL_STBY_MASK) +/* 0x92082 */ +#define REG_MODE_1_ALL_MASK (CAM_STBY_MASK | VIDEO_STBY_MASK |\ + AUDIO_STBY_MASK | SD_STBY_MASK) + +/* switch mode setting */ +#define SW1MODE_LSB 0 +#define SW2MODE_LSB 10 +#define SW3MODE_LSB 0 +#define SW4MODE_LSB 8 + +#define SWMODE_MASK 0xF +#define SWMODE_AUTO 0x8 + +#define PWGT1SPIEN (1 << 15) +#define PWGT2SPIEN (1 << 16) + +/* CPU */ +static struct regulator_consumer_supply sw1_consumers[] = { + { + .supply = "cpu_vcc", + } +}; + +static struct regulator_consumer_supply vdig_consumers[] = { + { + /* sgtl5000 */ + .supply = "VDDA", + .dev_name = "1-000a", + }, +}; + +static struct regulator_consumer_supply vvideo_consumers[] = { + { + /* sgtl5000 */ + .supply = "VDDIO", + .dev_name = "1-000a", + }, +}; + +struct mc13892; + +static struct regulator_init_data sw1_init = { + .constraints = { + .name = "SW1", + .min_uV = mV_to_uV(600), + .max_uV = mV_to_uV(1375), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 850000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), + .consumer_supplies = sw1_consumers, +}; + +static struct regulator_init_data sw2_init = { + .constraints = { + .name = "SW2", + .min_uV = mV_to_uV(900), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 950000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + } +}; + +static struct regulator_init_data sw3_init = { + .constraints = { + .name = "SW3", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data sw4_init = { + .constraints = { + .name = "SW4", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data viohi_init = { + .constraints = { + .name = "VIOHI", + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb_init = { + .constraints = { + .name = "VUSB", + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data swbst_init = { + .constraints = { + .name = "SWBST", + } +}; + +static struct regulator_init_data vdig_init = { + .constraints = { + .name = "VDIG", + .min_uV = mV_to_uV(1650), + .max_uV = mV_to_uV(1650), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(vdig_consumers), + .consumer_supplies = vdig_consumers, +}; + +static struct regulator_init_data vpll_init = { + .constraints = { + .name = "VPLL", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data vusb2_init = { + .constraints = { + .name = "VUSB2", + .min_uV = mV_to_uV(2400), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data vvideo_init = { + .constraints = { + .name = "VVIDEO", + .min_uV = mV_to_uV(2775), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .apply_uV =1, + }, + .num_consumer_supplies = ARRAY_SIZE(vvideo_consumers), + .consumer_supplies = vvideo_consumers, +}; + +static struct regulator_init_data vaudio_init = { + .constraints = { + .name = "VAUDIO", + .min_uV = mV_to_uV(2300), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vsd_init = { + .constraints = { + .name = "VSD", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vcam_init = { + .constraints = { + .name = "VCAM", + .min_uV = mV_to_uV(2500), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL, + } +}; + +static struct regulator_init_data vgen1_init = { + .constraints = { + .name = "VGEN1", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(1200), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vgen2_init = { + .constraints = { + .name = "VGEN2", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + } +}; + +static struct regulator_init_data vgen3_init = { + .constraints = { + .name = "VGEN3", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(2900), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + } +}; + +static struct regulator_init_data gpo1_init = { + .constraints = { + .name = "GPO1", + } +}; + +static struct regulator_init_data gpo2_init = { + .constraints = { + .name = "GPO2", + } +}; + +static struct regulator_init_data gpo3_init = { + .constraints = { + .name = "GPO3", + } +}; + +static struct regulator_init_data gpo4_init = { + .constraints = { + .name = "GPO4", + } +}; + +static int mc13892_regulator_init(struct mc13892 *mc13892) +{ + unsigned int value, register_mask; + + printk("Initializing regulators for Efikasb 5.1.\n"); + if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0) + sw2_init.constraints.state_mem.uV = 1100000; + else if (mxc_cpu_is_rev(CHIP_REV_2_0) == 1) { + sw2_init.constraints.state_mem.uV = 1250000; + sw1_init.constraints.state_mem.uV = 1000000; + } + + /* enable standby controll for all regulators */ + pmic_read_reg(REG_MODE_0, &value, 0xffffff); + value |= REG_MODE_0_ALL_MASK; + pmic_write_reg(REG_MODE_0, value, 0xffffff); + + pmic_read_reg(REG_MODE_1, &value, 0xffffff); + value |= REG_MODE_1_ALL_MASK; + pmic_write_reg(REG_MODE_1, value, 0xffffff); + + /* enable switch audo mode */ + pmic_read_reg(REG_IDENTIFICATION, &value, 0xffffff); + /* only for mc13892 2.0A */ + if ((value & 0x0000FFFF) == 0x45d0) { + pmic_read_reg(REG_SW_4, &value, 0xffffff); + register_mask = (SWMODE_MASK << SW1MODE_LSB) | + (SWMODE_MASK << SW2MODE_LSB); + value &= ~register_mask; + value |= (SWMODE_AUTO << SW1MODE_LSB) | + (SWMODE_AUTO << SW2MODE_LSB); + pmic_write_reg(REG_SW_4, value, 0xffffff); + + pmic_read_reg(REG_SW_5, &value, 0xffffff); + register_mask = (SWMODE_MASK << SW3MODE_LSB) | + (SWMODE_MASK << SW4MODE_LSB); + value &= ~register_mask; + value |= (SWMODE_AUTO << SW3MODE_LSB) | + (SWMODE_AUTO << SW4MODE_LSB); + pmic_write_reg(REG_SW_5, value, 0xffffff); + } + + mc13892_register_regulator(mc13892, MC13892_SW1, &sw1_init); + mc13892_register_regulator(mc13892, MC13892_SW2, &sw2_init); + mc13892_register_regulator(mc13892, MC13892_SW3, &sw3_init); + mc13892_register_regulator(mc13892, MC13892_SW4, &sw4_init); + mc13892_register_regulator(mc13892, MC13892_SWBST, &swbst_init); + mc13892_register_regulator(mc13892, MC13892_VIOHI, &viohi_init); + mc13892_register_regulator(mc13892, MC13892_VPLL, &vpll_init); + mc13892_register_regulator(mc13892, MC13892_VDIG, &vdig_init); + mc13892_register_regulator(mc13892, MC13892_VSD, &vsd_init); + mc13892_register_regulator(mc13892, MC13892_VUSB2, &vusb2_init); + mc13892_register_regulator(mc13892, MC13892_VVIDEO, &vvideo_init); + mc13892_register_regulator(mc13892, MC13892_VAUDIO, &vaudio_init); + mc13892_register_regulator(mc13892, MC13892_VCAM, &vcam_init); + mc13892_register_regulator(mc13892, MC13892_VGEN1, &vgen1_init); + mc13892_register_regulator(mc13892, MC13892_VGEN2, &vgen2_init); + mc13892_register_regulator(mc13892, MC13892_VGEN3, &vgen3_init); + mc13892_register_regulator(mc13892, MC13892_VUSB, &vusb_init); + mc13892_register_regulator(mc13892, MC13892_GPO1, &gpo1_init); + mc13892_register_regulator(mc13892, MC13892_GPO2, &gpo2_init); + mc13892_register_regulator(mc13892, MC13892_GPO3, &gpo3_init); + mc13892_register_regulator(mc13892, MC13892_GPO4, &gpo4_init); + + regulator_has_full_constraints(); + + return 0; +} + +static struct mc13892_platform_data mc13892_plat = { + .init = mc13892_regulator_init, +}; + +static struct spi_board_info __initdata mc13892_spi_device = { + .modalias = "pmic_spi", + /* + .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_8), + */ + .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_6), + .max_speed_hz = 1000000, /* max spi SCK clock speed in HZ */ + .bus_num = 1, + .chip_select = 0, + .platform_data = &mc13892_plat, +}; + + +int __init mx51_efikasb_init_mc13892(void) +{ + /* ron: disable power gate */ + printk(" [VV] mx51_efikasb_init_mc13892.\n"); + pmic_write_reg(REG_POWER_MISC, ~(PWGT1SPIEN|PWGT2SPIEN), + (PWGT1SPIEN|PWGT2SPIEN)); + + return spi_register_board_info(&mc13892_spi_device, 1); +} + diff --git a/arch/arm/mach-mx5/mx51_efikasb_powerkey.c b/arch/arm/mach-mx5/mx51_efikasb_powerkey.c new file mode 100644 index 00000000000..0fb4262e68d --- /dev/null +++ b/arch/arm/mach-mx5/mx51_efikasb_powerkey.c @@ -0,0 +1,352 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mx51_efikasb.h" +#include "mx51_pins.h" +#include "iomux.h" + +extern int mxc_get_power_status(iomux_pin_name_t pin); +extern void mxc_power_on_wlan(int on); +extern void mxc_power_on_wwan(int on); +extern void mxc_power_on_bt(int on); +extern void mxc_power_on_camera(int on); +extern void mxc_power_on_agps(int on); +extern void mxc_reset_agps(void); + +extern int suspend_device_by_name(char *dev_name, pm_message_t state); +extern int resume_device_by_name(char *dev_name, pm_message_t state); + +static void suspend_usbh2_wq_handler(struct work_struct *work); + +static DECLARE_MUTEX(usbh2_mx); +static DECLARE_DELAYED_WORK(suspend_usbh2_work, suspend_usbh2_wq_handler); + +#define BIT_BT_PWRON 1 +#define BIT_WWAN_PWRON 2 +#define BIT_CAM_PWRON 3 + +extern int wireless_sw_state; + +static int usbh2_dev_power = 0; +static int usbh2_is_suspend = 0; + +static void suspend_usbh2_wq_handler(struct work_struct *work) +{ + int error; + + down(&usbh2_mx); + + if (usbh2_dev_power == 0) { + error = suspend_device_by_name("fsl-ehci.1", PMSG_SUSPEND); + if (error == 0) + usbh2_is_suspend = 1; + }; + + up(&usbh2_mx); +} + +static ssize_t wlan_pwr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int val; + + val = mxc_get_power_status(WLAN_PWRON_PIN); + return sprintf(buf, "%s\n", val ? "on" : "off"); +} + +static ssize_t wlan_pwr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int val; + + if (strncmp(buf, "on", 2) == 0) { + val = 1; + } else if (strncmp(buf, "off", 3) == 0) + val = 0; + else + return -EINVAL; + + mxc_power_on_wlan(val); + + return count; +} + +static ssize_t wwan_pwr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int val; + + val = mxc_get_power_status(WWAN_PWRON_PIN); + return sprintf(buf, "%s\n", val ? "on" : "off"); +} + +static ssize_t wwan_pwr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int old_usbh2_dev_power = usbh2_dev_power; + int error; + int val; + + if (strncmp(buf, "on", 2) == 0) { + val = 1; + } else if (strncmp(buf, "off", 3) == 0) + val = 0; + else + return -EINVAL; + + down(&usbh2_mx); + + if (usbh2_dev_power == 0 && val == 1 && usbh2_is_suspend == 1) { + error = resume_device_by_name("fsl-ehci.1", PMSG_RESUME); + if (error == 0) + usbh2_is_suspend = 0; + } + + mxc_power_on_wwan(val); + + if (val) + usbh2_dev_power |= (1 << BIT_WWAN_PWRON); + else + usbh2_dev_power &= ~(1 << BIT_WWAN_PWRON); + + up(&usbh2_mx); + + printk("usbh2_dev_power=%x\n", usbh2_dev_power); + + if (old_usbh2_dev_power != 0 && usbh2_dev_power == 0) + schedule_delayed_work(&suspend_usbh2_work, msecs_to_jiffies(4000)); + + return count; +} + +static ssize_t bt_pwr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int val; + + val = mxc_get_power_status(BT_PWRON_PIN); + return sprintf(buf, "%s\n", val ? "on" : "off"); +} + +static ssize_t bt_pwr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int old_usbh2_dev_power = usbh2_dev_power; + int error; + int val; + + if (strncmp(buf, "on", 2) == 0) { + val = 1; + } else if (strncmp(buf, "off", 3) == 0) + val = 0; + else + return -EINVAL; + + down(&usbh2_mx); + + if (usbh2_dev_power == 0 && val == 1 && usbh2_is_suspend == 1) { + error = resume_device_by_name("fsl-ehci.1", PMSG_RESUME); + if (error == 0) + usbh2_is_suspend = 0; + } + + mxc_power_on_bt(val); + + if (val) + usbh2_dev_power |= (1 << BIT_BT_PWRON); + else + usbh2_dev_power &= ~(1 << BIT_BT_PWRON); + + up(&usbh2_mx); + + printk("usbh2_dev_power=%x\n", usbh2_dev_power); + + if (old_usbh2_dev_power != 0 && usbh2_dev_power == 0) + schedule_delayed_work(&suspend_usbh2_work, msecs_to_jiffies(4000)); + + return count; +} + +static ssize_t camera_pwr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int val; + + val = mxc_get_power_status(CAM_PWRON_PIN); + return sprintf(buf, "%s\n", val ? "on" : "off"); +} + +static ssize_t camera_pwr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int val; + int old_usbh2_dev_power = usbh2_dev_power; + int error; + + if (strncmp(buf, "on", 2) == 0) + val = 1; + else if (strncmp(buf, "off", 3) == 0) + val = 0; + else + return -EINVAL; + + down(&usbh2_mx); + + if (usbh2_dev_power == 0 && val == 1 && usbh2_is_suspend == 1) { + error = resume_device_by_name("fsl-ehci.1", PMSG_RESUME); + if (error == 0) + usbh2_is_suspend = 0; + } + + mxc_power_on_camera(val); + + if (val) + usbh2_dev_power |= (1 << BIT_CAM_PWRON); + else + usbh2_dev_power &= ~(1 << BIT_CAM_PWRON); + + up(&usbh2_mx); + + printk("usbh2_dev_power=%x\n", usbh2_dev_power); + + if (old_usbh2_dev_power != 0 && usbh2_dev_power == 0) + schedule_delayed_work(&suspend_usbh2_work, msecs_to_jiffies(4000)); + + return count; +} + +static ssize_t agps_pwr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int val; + + val = mxc_get_power_status(AGPS_PWRON_PIN); + return sprintf(buf, "%s\n", val ? "on" : "off"); +} + +static ssize_t agps_pwr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int val; + + if (strncmp(buf, "on", 2) == 0) + val = 1; + else if (strncmp(buf, "off", 3) == 0) + val = 0; + else + return -EINVAL; + + mxc_power_on_agps(val); + if (val == 1) + mxc_reset_agps(); + + return count; +} + +#define DISABLE_POWER_DOWN 0 +#define PRECHARGE_POWER_DOWN 1 +#define ACTIVE_POWER_DOWN_64 2 +#define ACTIVE_POWER_DOWN_128 3 + +static void mxc_set_ddr2_power_down(int arg) +{ + u32 value; + + value = __raw_readl(IO_ADDRESS(ESDCTL_BASE_ADDR + 0x08)); + value |= (arg & 0x03) << 12; + __raw_writel(value, IO_ADDRESS(ESDCTL_BASE_ADDR + 0x08)); + + value = __raw_readl(IO_ADDRESS(ESDCTL_BASE_ADDR + 0x00)); + value |= (arg & 0x03) << 12; + __raw_writel(value, IO_ADDRESS(ESDCTL_BASE_ADDR + 0x00)); +} + +static ssize_t ddr2_pd_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + u32 value; + + value = __raw_readl(IO_ADDRESS(ESDCTL_BASE_ADDR + 0x08)); + value = (value & 0x3000) >> 12; + + return sprintf(buf, "%d\n", value); +} +static ssize_t ddr2_pd_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + int arg; + + arg = simple_strtoul(buf, &end, 10); + if (arg >= 4 || arg < 0) { + return -EINVAL; + } + + mxc_set_ddr2_power_down(arg); + + return count; +} + +static struct kobj_attribute wlan_pwr_attribute = + __ATTR(wlan_power, 0666, wlan_pwr_show, wlan_pwr_store); +static struct kobj_attribute wwan_pwr_attribute = + __ATTR(wwan_power, 0666, wwan_pwr_show, wwan_pwr_store); +static struct kobj_attribute bt_pwr_attribute = + __ATTR(bt_power, 0666, bt_pwr_show, bt_pwr_store); +static struct kobj_attribute camera_pwr_attribute = + __ATTR(camera_power, 0666, camera_pwr_show, camera_pwr_store); +static struct kobj_attribute agps_pwr_attribute = + __ATTR(agps_power, 0666, agps_pwr_show, agps_pwr_store); +static struct kobj_attribute ddr2_pd_attribute = + __ATTR(ddr2_pd, 0666, ddr2_pd_show, ddr2_pd_store); + +static struct attribute *pwr_attrs[] = { + &wlan_pwr_attribute.attr, + &wwan_pwr_attribute.attr, + &bt_pwr_attribute.attr, + &camera_pwr_attribute.attr, + &agps_pwr_attribute.attr, + &ddr2_pd_attribute.attr, + NULL, +}; + +static struct attribute_group pwr_attr_group = { + .attrs = pwr_attrs, +}; + +static struct platform_device mxc_pwr_sw_device = { + .name = "mxc_pwr_sw", +}; + +static int __init mxc_init_pwr_sw(void) +{ + int retval; + static struct kobject *pwr_sw_kobj; + + init_MUTEX(&usbh2_mx); + + usbh2_dev_power |= mxc_get_power_status(BT_PWRON_PIN) << BIT_BT_PWRON; + usbh2_dev_power |= mxc_get_power_status(WWAN_PWRON_PIN) << BIT_WWAN_PWRON; + usbh2_dev_power |= mxc_get_power_status(CAM_PWRON_PIN) << BIT_CAM_PWRON; + if (usbh2_dev_power == 0) + suspend_device_by_name("fsl-ehci.1", PMSG_SUSPEND); + + mxc_set_ddr2_power_down(ACTIVE_POWER_DOWN_64); /* ron: set DDR2 power down */ + + platform_device_register(&mxc_pwr_sw_device); + + pwr_sw_kobj = kobject_create_and_add("power_control", + &mxc_pwr_sw_device.dev.kobj); + if (!pwr_sw_kobj) + return -ENOMEM; + + retval = sysfs_create_group(pwr_sw_kobj, &pwr_attr_group); + if (retval) { + kobject_put(pwr_sw_kobj); + return retval; + } + + return 0; +} + +late_initcall(mxc_init_pwr_sw); diff --git a/arch/arm/mach-mx5/serial.c b/arch/arm/mach-mx5/serial.c index 123db39fd84..c07b3a62fc9 100644 --- a/arch/arm/mach-mx5/serial.c +++ b/arch/arm/mach-mx5/serial.c @@ -23,6 +23,7 @@ #include #include #include "serial.h" +#include "mx51_efikasb.h" #if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) @@ -36,16 +37,22 @@ static uart_mxc_port mxc_ports[] = { [0] = { .port = { + .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR), + .mapbase = UART1_BASE_ADDR, .iotype = SERIAL_IO_MEM, + .irq = UART1_INT1, .fifosize = 32, .flags = ASYNC_BOOT_AUTOCONF, .line = 0, }, - .ints_muxed = 1, - .mode = MODE_DCE, - .ir_mode = NO_IRDA, - .enabled = 1, + .ints_muxed = UART1_MUX_INTS, + .irqs = {UART1_INT2, UART1_INT3}, + .mode = UART1_MODE, + .ir_mode = UART1_IR, + .enabled = UART1_ENABLED, + .hardware_flow = UART1_HW_FLOW, .cts_threshold = UART1_UCR4_CTSTL, + .dma_enabled = UART1_DMA_ENABLE, .dma_rxbuf_size = UART1_DMA_RXBUFSIZE, .rx_threshold = UART1_UFCR_RXTL, .tx_threshold = UART1_UFCR_TXTL, @@ -55,16 +62,22 @@ static uart_mxc_port mxc_ports[] = { }, [1] = { .port = { + .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR), + .mapbase = UART2_BASE_ADDR, .iotype = SERIAL_IO_MEM, + .irq = UART2_INT1, .fifosize = 32, .flags = ASYNC_BOOT_AUTOCONF, .line = 1, }, - .ints_muxed = 1, - .mode = MODE_DCE, - .ir_mode = NO_IRDA, - .enabled = 1, + .ints_muxed = UART2_MUX_INTS, + .irqs = {UART2_INT2, UART2_INT3}, + .mode = UART2_MODE, + .ir_mode = UART2_IR, + .enabled = UART2_ENABLED, + .hardware_flow = UART2_HW_FLOW, .cts_threshold = UART2_UCR4_CTSTL, + .dma_enabled = UART2_DMA_ENABLE, .dma_rxbuf_size = UART2_DMA_RXBUFSIZE, .rx_threshold = UART2_UFCR_RXTL, .tx_threshold = UART2_UFCR_TXTL, @@ -74,17 +87,22 @@ static uart_mxc_port mxc_ports[] = { }, [2] = { .port = { + .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR), + .mapbase = UART3_BASE_ADDR, .iotype = SERIAL_IO_MEM, + .irq = UART3_INT1, .fifosize = 32, .flags = ASYNC_BOOT_AUTOCONF, .line = 2, }, - .ints_muxed = 1, - .mode = MODE_DCE, - .ir_mode = NO_IRDA, - .enabled = 1, + .ints_muxed = UART3_MUX_INTS, + .irqs = {UART3_INT2, UART3_INT3}, + .mode = UART3_MODE, + .ir_mode = UART3_IR, + .enabled = UART3_ENABLED, + .hardware_flow = UART3_HW_FLOW, .cts_threshold = UART3_UCR4_CTSTL, - .dma_enabled = 1, + .dma_enabled = UART3_DMA_ENABLE, .dma_rxbuf_size = UART3_DMA_RXBUFSIZE, .rx_threshold = UART3_UFCR_RXTL, .tx_threshold = UART3_UFCR_TXTL, @@ -94,16 +112,22 @@ static uart_mxc_port mxc_ports[] = { }, [3] = { .port = { + .membase = (void *)IO_ADDRESS(UART4_BASE_ADDR), + .mapbase = UART4_BASE_ADDR, .iotype = SERIAL_IO_MEM, + .irq = UART4_INT1, .fifosize = 32, .flags = ASYNC_BOOT_AUTOCONF, .line = 3, }, - .ints_muxed = 1, - .mode = MODE_DCE, - .ir_mode = NO_IRDA, - .enabled = 1, + .ints_muxed = UART4_MUX_INTS, + .irqs = {UART4_INT2, UART4_INT3}, + .mode = UART4_MODE, + .ir_mode = UART4_IR, + .enabled = UART4_ENABLED, + .hardware_flow = UART4_HW_FLOW, .cts_threshold = UART4_UCR4_CTSTL, + .dma_enabled = UART4_DMA_ENABLE, .dma_rxbuf_size = UART4_DMA_RXBUFSIZE, .rx_threshold = UART4_UFCR_RXTL, .tx_threshold = UART4_UFCR_TXTL, @@ -113,16 +137,22 @@ static uart_mxc_port mxc_ports[] = { }, [4] = { .port = { + .membase = (void *)IO_ADDRESS(UART5_BASE_ADDR), + .mapbase = UART5_BASE_ADDR, .iotype = SERIAL_IO_MEM, + .irq = UART5_INT1, .fifosize = 32, .flags = ASYNC_BOOT_AUTOCONF, .line = 4, }, - .ints_muxed = 1, - .mode = MODE_DCE, - .ir_mode = NO_IRDA, - .enabled = 1, + .ints_muxed = UART5_MUX_INTS, + .irqs = {UART5_INT2, UART5_INT3}, + .mode = UART5_MODE, + .ir_mode = UART5_IR, + .enabled = UART5_ENABLED, + .hardware_flow = UART5_HW_FLOW, .cts_threshold = UART5_UCR4_CTSTL, + .dma_enabled = UART5_DMA_ENABLE, .dma_rxbuf_size = UART5_DMA_RXBUFSIZE, .rx_threshold = UART5_UFCR_RXTL, .tx_threshold = UART5_UFCR_TXTL, @@ -132,111 +162,41 @@ static uart_mxc_port mxc_ports[] = { }, }; -static struct resource mxc_uart_resources1[] = { - { - .start = UART1_BASE_ADDR, - .end = UART1_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_UART1, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device mxc_uart_device1 = { .name = "mxcintuart", .id = 0, - .num_resources = ARRAY_SIZE(mxc_uart_resources1), - .resource = mxc_uart_resources1, .dev = { .platform_data = &mxc_ports[0], }, }; -static struct resource mxc_uart_resources2[] = { - { - .start = UART2_BASE_ADDR, - .end = UART2_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_UART2, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device mxc_uart_device2 = { .name = "mxcintuart", .id = 1, - .num_resources = ARRAY_SIZE(mxc_uart_resources2), - .resource = mxc_uart_resources2, .dev = { .platform_data = &mxc_ports[1], }, }; -static struct resource mxc_uart_resources3[] = { - { - .start = UART3_BASE_ADDR, - .end = UART3_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_UART3, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device mxc_uart_device3 = { .name = "mxcintuart", .id = 2, - .num_resources = ARRAY_SIZE(mxc_uart_resources3), - .resource = mxc_uart_resources3, .dev = { .platform_data = &mxc_ports[2], }, }; -static struct resource mxc_uart_resources4[] = { - { - .start = UART4_BASE_ADDR, - .end = UART4_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_UART4, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device mxc_uart_device4 = { .name = "mxcintuart", .id = 3, - .num_resources = ARRAY_SIZE(mxc_uart_resources4), - .resource = mxc_uart_resources4, .dev = { .platform_data = &mxc_ports[3], }, }; -static struct resource mxc_uart_resources5[] = { - { - .start = UART5_BASE_ADDR, - .end = UART5_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_UART5, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device mxc_uart_device5 = { .name = "mxcintuart", .id = 4, - .num_resources = ARRAY_SIZE(mxc_uart_resources5), - .resource = mxc_uart_resources5, .dev = { .platform_data = &mxc_ports[4], }, @@ -244,26 +204,27 @@ static struct platform_device mxc_uart_device5 = { static int __init mxc_init_uart(void) { - if (cpu_is_mx53() || cpu_is_mx50()) { - mxc_uart_resources1[0].start -= 0x20000000; - mxc_uart_resources1[0].end -= 0x20000000; - mxc_uart_resources2[0].start -= 0x20000000; - mxc_uart_resources2[0].end -= 0x20000000; - mxc_uart_resources3[0].start -= 0x20000000; - mxc_uart_resources3[0].end -= 0x20000000; - mxc_uart_resources4[0].start -= 0x20000000; - mxc_uart_resources4[0].end -= 0x20000000; - mxc_uart_resources5[0].start -= 0x20000000; - mxc_uart_resources5[0].end -= 0x20000000; + int i; + + if (cpu_is_mx53()) { + for (i = 0; i < ARRAY_SIZE(mxc_ports); i++) { + mxc_ports[i].port.mapbase -= 0x20000000; + } } /* Register all the MXC UART platform device structures */ platform_device_register(&mxc_uart_device1); platform_device_register(&mxc_uart_device2); +#if UART3_ENABLED == 1 platform_device_register(&mxc_uart_device3); +#endif /* UART3_ENABLED */ if (cpu_is_mx53()) { +#if UART4_ENABLED == 1 platform_device_register(&mxc_uart_device4); +#endif /* UART4_ENABLED */ +#if UART5_ENABLED == 1 platform_device_register(&mxc_uart_device5); +#endif /* UART5_ENABLED */ } return 0; } diff --git a/arch/arm/mach-mx5/serial.h b/arch/arm/mach-mx5/serial.h index d487a96027a..5cc4cd5a759 100644 --- a/arch/arm/mach-mx5/serial.h +++ b/arch/arm/mach-mx5/serial.h @@ -14,7 +14,16 @@ #ifndef __ARCH_ARM_MACH_MX51_SERIAL_H__ #define __ARCH_ARM_MACH_MX51_SERIAL_H__ +#include + /* UART 1 configuration */ +/*! + * This option allows to choose either an interrupt-driven software controlled + * hardware flow control (set this option to 0) or hardware-driven hardware + * flow control (set this option to 1). + */ +/* UART used as wakeup source */ +#define UART1_HW_FLOW 0 /*! * This specifies the threshold at which the CTS pin is deasserted by the * RXFIFO. Set this value in Decimal to anything from 0 to 32 for @@ -23,6 +32,10 @@ * flow control set this option to -1. */ #define UART1_UCR4_CTSTL 16 +/*! + * This is option to enable (set this option to 1) or disable DMA data transfer + */ +#define UART1_DMA_ENABLE 0 /*! * Specify the size of the DMA receive buffer. The minimum buffer size is 512 * bytes. The buffer size should be a multiple of 256. @@ -43,24 +56,88 @@ */ #define UART1_UFCR_TXTL 16 /* UART 2 configuration */ -#define UART2_UCR4_CTSTL -1 +#define UART2_HW_FLOW 1 /* 0 */ /*ron: Enable H/W flow control for AGPS */ +#define UART2_UCR4_CTSTL 16 /* -1 */ +#define UART2_DMA_ENABLE 1 /* 0 */ #define UART2_DMA_RXBUFSIZE 512 #define UART2_UFCR_RXTL 16 #define UART2_UFCR_TXTL 16 /* UART 3 configuration */ +#define UART3_HW_FLOW 1 #define UART3_UCR4_CTSTL 16 +#define UART3_DMA_ENABLE 1 #define UART3_DMA_RXBUFSIZE 1024 #define UART3_UFCR_RXTL 16 #define UART3_UFCR_TXTL 16 /* UART 4 configuration */ +#define UART4_HW_FLOW 0 #define UART4_UCR4_CTSTL -1 +#define UART4_DMA_ENABLE 0 #define UART4_DMA_RXBUFSIZE 512 #define UART4_UFCR_RXTL 16 #define UART4_UFCR_TXTL 16 /* UART 5 configuration */ +#define UART5_HW_FLOW 0 #define UART5_UCR4_CTSTL -1 +#define UART5_DMA_ENABLE 0 #define UART5_DMA_RXBUFSIZE 512 #define UART5_UFCR_RXTL 16 #define UART5_UFCR_TXTL 16 +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +/* + * Is the MUXED interrupt output sent to the ARM core + */ +#define INTS_NOTMUXED 0 +#define INTS_MUXED 1 +/* UART 1 configuration */ +/*! + * This define specifies whether the muxed ANDed interrupt line or the + * individual interrupts from the UART port is integrated with the ARM core. + * There exists a define like this for each UART port. Valid values that can + * be used are \b INTS_NOTMUXED or \b INTS_MUXED. + */ +#define UART1_MUX_INTS INTS_MUXED +/*! + * This define specifies the transmitter interrupt number or the interrupt + * number of the ANDed interrupt in case the interrupts are muxed. There exists + * a define like this for each UART port. + */ +#define UART1_INT1 MXC_INT_UART1 +/*! + * This define specifies the receiver interrupt number. If the interrupts of + * the UART are muxed, then we specify here a dummy value -1. There exists a + * define like this for each UART port. + */ +#define UART1_INT2 -1 +/*! + * This specifies the master interrupt number. If the interrupts of the UART + * are muxed, then we specify here a dummy value of -1. There exists a define + * like this for each UART port. + */ +#define UART1_INT3 -1 +/* UART 2 configuration */ +#define UART2_MUX_INTS INTS_MUXED +#define UART2_INT1 MXC_INT_UART2 +#define UART2_INT2 -1 +#define UART2_INT3 -1 +/* UART 3 configuration */ +#define UART3_MUX_INTS INTS_MUXED +#define UART3_INT1 MXC_INT_UART3 +#define UART3_INT2 -1 +#define UART3_INT3 -1 +/* UART 4 configuration */ +#define UART4_MUX_INTS INTS_MUXED +#define UART4_INT1 MXC_INT_UART4 +#define UART4_INT2 -1 +#define UART4_INT3 -1 +/* UART 5 configuration */ +#define UART5_MUX_INTS INTS_MUXED +#define UART5_INT1 MXC_INT_UART5 +#define UART5_INT2 -1 +#define UART5_INT3 -1 #endif /* __ARCH_ARM_MACH_MX51_SERIAL_H__ */ diff --git a/arch/arm/mach-mx5/usb.h b/arch/arm/mach-mx5/usb.h index 6115d3375c0..e24fd9aedbc 100644 --- a/arch/arm/mach-mx5/usb.h +++ b/arch/arm/mach-mx5/usb.h @@ -29,7 +29,8 @@ extern void gpio_usbotg_utmi_inactive(void); extern void __init mx5_usb_dr_init(void); extern void __init mx5_usbh1_init(void); extern void __init mx5_usbh2_init(void); - +// micken: name clash with efikamx mainline ? +extern void __init mx51_usbh2_init(void); typedef void (*driver_vbus_func)(bool); extern void mx5_set_host1_vbus_func(driver_vbus_func); extern void mx5_set_otghost_vbus_func(driver_vbus_func); diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index c2262f55b61..8997abdb3f5 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -209,6 +209,24 @@ struct mxc_w1_config { * data. It includes the SPI bus number and the maximum number of * slaves/chips it supports. */ + + +/* micken: added battery support */ + +struct mxc_battery_platform_data { + int batt_in_irq; + int ac_in_irq; + int batt_low_irq; + int (*get_batt_in_status) (void); + int (*get_ac_in_status) (void); + int (*get_batt_low_status) (void); + void (*set_batt_low_led) (int); +}; + + + + + struct mxc_spi_master { /*! * SPI Master's bus number. @@ -314,6 +332,11 @@ struct mxc_lcd_platform_data { char *io_reg; char *core_reg; char *analog_reg; + // micken: backlight etc for efikasb + void (*power_on_lcd) (int); + void (*power_on_lvds) (int); + void (*turn_on_backlight) (int); + void (*lvds_enable) (int); void (*reset) (void); }; diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 58a3e572f2c..7e8a4fc3398 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -696,6 +696,98 @@ static int dpm_suspend(pm_message_t state) return error; } + +/* ron: suspend the USB Host if all device are disconnected */ +// Inherited Ron's added, Byron 2010.03.10 // micken : added to efikasb kernel 2010.09.03 +int suspend_device_by_name(char *dev_name, pm_message_t state) +{ + struct list_head list; + int error = 0; + + INIT_LIST_HEAD(&list); + mutex_lock(&dpm_list_mtx); + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.prev); + + get_device(dev); + mutex_unlock(&dpm_list_mtx); + + if(strcmp(dev_name, dev->kobj.name) == 0) { + + //error = suspend_device(dev, state); + error= device_suspend(dev,state);//2010.03.10 ,Byron + + mutex_lock(&dpm_list_mtx); + if (error) { + pm_dev_err(dev, state, "", error); + put_device(dev); + break; + } + + dev->power.status = DPM_OFF; + break; + } + + + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &list); + put_device(dev); + + } + list_splice(&list, dpm_list.prev); + mutex_unlock(&dpm_list_mtx); + return error; +} +EXPORT_SYMBOL(suspend_device_by_name); + + +// inheriated V28 Byron 2010.03.10 // micken: added to efikasb 2010.09.03 +int resume_device_by_name(char *dev_name, pm_message_t state) +{ + struct list_head list; + int error = 0; + + INIT_LIST_HEAD(&list); + mutex_lock(&dpm_list_mtx); + transition_started = false; + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.next); + + get_device(dev); + + if(strcmp(dev_name, dev->kobj.name) == 0) { + + if (dev->power.status >= DPM_OFF) { + + dev->power.status = DPM_RESUMING; + mutex_unlock(&dpm_list_mtx); + + //error = resume_device(dev, state); + error=device_resume(dev,state); //2010.03.10 Byron + + mutex_lock(&dpm_list_mtx); + if (error) + pm_dev_err(dev, state, "", error); + } else if (dev->power.status == DPM_SUSPENDING) { + /* Allow new children of the device to be registered */ + dev->power.status = DPM_RESUMING; + } + break; + } + + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &list); + put_device(dev); + } + list_splice(&list, &dpm_list); + mutex_unlock(&dpm_list_mtx); + + return error; +} +EXPORT_SYMBOL(resume_device_by_name); + + + /** * device_prepare - Execute the ->prepare() callback(s) for given device. * @dev: Device. diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c0537218d9c..a72fb3bdfea 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -51,6 +51,13 @@ MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data EXPORT_SYMBOL_GPL(hid_debug); #endif + + +//inherited V28 ,2010.03.10 Byron +#ifdef CONFIG_MACH_MX51_EFIKASB +extern void mxc_reset_idle_timer(void); +#endif + /* * Register a new report for a device. */ @@ -917,6 +924,11 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, continue; } + /* ron: add kunlun custom Fn + XX key */ + //inherited Ron's code, Byron 2010.03.10 + if((field->usage[n].hid & HID_USAGE_PAGE) == HID_UP_CUSTOM) + hid_process_event(hid, field, &field->usage[n], value[n], interrupt); + if (field->value[n] >= min && field->value[n] <= max && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index bee718f8714..860a951b607 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -296,6 +296,8 @@ #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 +//micken: #define USB_DEVICE_ID_LOGITECH_G15_GAMEPANEL 0xc227 define +#define USB_DEVICE_ID_LOGITECH_G15_GAMEPANEL 0xc227 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 3c1fcb7640a..96f56c6e50e 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -36,7 +36,7 @@ #include #include #include "usbhid.h" - +#include "../hid-ids.h" // micken: for logitech id /* * Version Information */ @@ -552,6 +552,12 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns } EXPORT_SYMBOL_GPL(usbhid_submit_report); + +#ifdef CONFIG_MACH_MX51_EFIKASB +extern void mxc_turn_on_caps_led(int on); +#endif + + static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct hid_device *hid = input_get_drvdata(dev); @@ -583,6 +589,14 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un } usbhid_submit_report(hid, field->report, USB_DIR_OUT); +#ifdef CONFIG_MACH_MX51_EFIKASB + /* ron: Caps Lock LED */ + if(code == 0x01) { + mxc_turn_on_caps_led(value); + } +#endif + + return 0; } @@ -1130,6 +1144,18 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) hid->bus = BUS_USB; hid->vendor = le16_to_cpu(dev->descriptor.idVendor); hid->product = le16_to_cpu(dev->descriptor.idProduct); + +#ifdef CONFIG_MACH_MX51_EFIKASB + /* ron: skip the Logitech G15 GamePanel LCD */ + // inherited Ron's code , Byron 2010.03.10 + if(hid->vendor == USB_VENDOR_ID_LOGITECH && + hid->product == USB_DEVICE_ID_LOGITECH_G15_GAMEPANEL) { + ret = -ENODEV; + goto err; + } +#endif + + hid->name[0] = 0; if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 8fe5ede1343..d5e64d853ed 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -36,6 +36,15 @@ config LEDS_MC13892 tristate "LED Support for mc13892 pmic" depends on LEDS_CLASS && MXC_MC13892_LIGHT + +config LEDS_EFIKASB + tristate "LED Support for Efikasb Platform" + depends on LEDS_CLASS && MACH_MX51_EFIKASB + help + This option enable support for the LEDs on Efikasb Platform. + + + config LEDS_LOCOMO tristate "LED Support for Locomo device" depends on LEDS_CLASS && SHARP_LOCOMO diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 46a0f9a90f5..1a3aa593698 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o obj-$(CONFIG_LEDS_MC13892) += leds-mc13892.o +obj-$(CONFIG_LEDS_EFIKASB) += leds-efikasb.o obj-$(CONFIG_LEDS_STMP378X) += leds-stmp378x-pwm.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o diff --git a/drivers/leds/leds-efikasb.c b/drivers/leds/leds-efikasb.c new file mode 100644 index 00000000000..5ee8d11b9d4 --- /dev/null +++ b/drivers/leds/leds-efikasb.c @@ -0,0 +1,102 @@ +/* + * Copyright 2009 Pegatron Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include + +extern void mxc_turn_on_alarm_led(int on); + +static void msg_alarm_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + mxc_turn_on_alarm_led(value ? 1 : 0); +} + +static struct led_classdev msg_alarm_led = { + .name = "msg-alarm-led", + .brightness_set = msg_alarm_led_set, +}; + +static int efikasb_led_remove(struct platform_device *dev) +{ + + led_classdev_unregister(&msg_alarm_led); + + return 0; +} + +static int efikasb_led_probe(struct platform_device *dev) +{ + int ret; + + ret = led_classdev_register(&dev->dev, &msg_alarm_led); + if (ret < 0) { + dev_err(&dev->dev, "Register Message Alarm LED failed\n"); + return -ENODEV; + + } + + printk(KERN_INFO "Registered Efikasb Message Alarm LED\n"); + + return 0; + +} + +#ifdef CONFIG_PM +static int efikasb_led_suspend(struct platform_device *dev, pm_message_t state) +{ + + led_classdev_suspend(&msg_alarm_led); + return 0; +} + +static int efikasb_led_resume(struct platform_device *dev) +{ + + led_classdev_resume(&msg_alarm_led); + return 0; +} +#else +#define efikasb_led_suspend NULL +#define efikasb_led_resume NULL +#endif + +static struct platform_driver efikasb_led_driver = { + .probe = efikasb_led_probe, + .remove = efikasb_led_remove, + .suspend = efikasb_led_suspend, + .resume = efikasb_led_resume, + .driver = { + .name = "efikasb_leds", + .owner = THIS_MODULE, + }, +}; + +static int __init efikasb_led_init(void) +{ + return platform_driver_register(&efikasb_led_driver); +} + +static void __exit efikasb_led_exit(void) +{ + platform_driver_unregister(&efikasb_led_driver); +} + +module_init(efikasb_led_init); +module_exit(efikasb_led_exit); + +MODULE_DESCRIPTION("Led driver for Efikasb LEDs"); +MODULE_AUTHOR("Ron Lee Pegatron Inc."); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 281b61b3b5f..93d9b23890e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -238,6 +238,15 @@ config MXS_PERSISTENT depends on ARCH_MXS default y + +config MX51_EFIKASB_DEBUG + tristate "MX51 Efikasb Debug Driver" + depends on MACH_MX51_EFIKASB + default n + ---help--- + MX51 debug driver of Efikasb board for Engineer. + + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 03dd5ee05ce..226f2495eb0 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -21,5 +21,6 @@ obj-$(CONFIG_HP_ILO) += hpilo.o obj-$(CONFIG_ISL29003) += isl29003.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_MXS_PERSISTENT) += mxs-persistent.o +obj-$(CONFIG_MX51_EFIKASB_DEBUG) += mx51_efikasb_debug.o obj-y += eeprom/ obj-y += cb710/ diff --git a/drivers/misc/mx51_efikasb_debug.c b/drivers/misc/mx51_efikasb_debug.c new file mode 100644 index 00000000000..754c3fd100d --- /dev/null +++ b/drivers/misc/mx51_efikasb_debug.c @@ -0,0 +1,657 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t reg_dump_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return 0; +} + +static ssize_t reg_dump_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + char *token; + char *running; + const char delimiters[] = " "; + u32 addr, value; + int len = 1; + int i; + + running = (char *)buf; + + token = strsep(&running, delimiters); + addr = simple_strtoul(token, &end, 16); + token = strsep(&running, delimiters); + if(token != NULL) + len = simple_strtoul(token, &end, 10); + + if(len <= 1) + len = 1; + + for (i = 0; i < len; i ++) { + value = __raw_readl(IO_ADDRESS(addr)); + printk("[0x%08x] = 0x%08x\n", addr, value); + addr += 4; + } + + return count; +} + +static ssize_t reg_write_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return 0; +} + +static ssize_t reg_write_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + char *token; + char *running; + const char delimiters[] = "="; + u32 addr, value; + + running = (char *)buf; + + token = strsep(&running, delimiters); + addr = simple_strtoul(token, &end, 16); + token = strsep(&running, delimiters); + if(token != NULL) { + value = simple_strtoul(token, &end, 16); + } else { + value = __raw_readl(IO_ADDRESS(addr)); + printk("[0x%08x] = 0x%08x\n", addr, value); + return -EINVAL; + } + + __raw_writel(value, IO_ADDRESS(addr)); + value = __raw_readl(IO_ADDRESS(addr)); + + printk("[0x%08x] = 0x%08x\n", addr, value); + + return count; +} + +struct pmic_reg_tbl { + char *name; + int reg_addr; +}; + +struct pmic_reg_tbl pmic_reg_tbl[] = { + {"INT_STATUS0",REG_INT_STATUS0}, + {"INT_MASK0",REG_INT_MASK0}, + {"INT_SENSE0",REG_INT_SENSE0}, + {"INT_STATUS1",REG_INT_STATUS1}, + {"INT_MASK1",REG_INT_MASK1}, + {"INT_SENSE1",REG_INT_SENSE1}, + {"PU_MODE_S",REG_PU_MODE_S}, + {"ID",REG_IDENTIFICATION}, + {"UNUSED0",REG_UNUSED0}, + {"ACC0",REG_ACC0}, + {"ACC1",REG_ACC1}, + {"UNUSED1",REG_UNUSED1}, + {"UNUSED2",REG_UNUSED2}, + {"POWER_CTL0",REG_POWER_CTL0}, + {"POWER_CTL1",REG_POWER_CTL1}, + {"POWER_CTL2",REG_POWER_CTL2}, + {"REGEN_ASSIGN",REG_REGEN_ASSIGN}, + {"UNUSED3",REG_UNUSED3}, + {"MEM_A",REG_MEM_A}, + {"MEM_B",REG_MEM_B}, + {"RTC_TIME",REG_RTC_TIME}, + {"RTC_ALARM",REG_RTC_ALARM}, + {"RTC_DAY",REG_RTC_DAY}, + {"RTC_DAY_ALARM",REG_RTC_DAY_ALARM}, + {"SW0",REG_SW_0}, + {"SW1",REG_SW_1}, + {"SW2",REG_SW_2}, + {"SW3",REG_SW_3}, + {"SW4",REG_SW_4}, + {"SW5",REG_SW_5}, + {"SETTING0",REG_SETTING_0}, + {"SETTING1",REG_SETTING_1}, + {"MODE_0",REG_MODE_0}, + {"MODE_1",REG_MODE_1}, + {"POWER_MISC",REG_POWER_MISC}, + {"UNUSED4",REG_UNUSED4}, + {"UNUSED5",REG_UNUSED5}, + {"UNUSED6",REG_UNUSED6}, + {"UNUSED7",REG_UNUSED7}, + {"UNUSED8",REG_UNUSED8}, + {"UNUSED9",REG_UNUSED9}, + {"UNUSED10",REG_UNUSED10}, + {"UNUSED11",REG_UNUSED11}, + {"ADC0",REG_ADC0}, + {"ADC1",REG_ADC1}, + {"ADC2",REG_ADC2}, + {"ADC3",REG_ADC3}, + {"ADC4",REG_ADC4}, + {"CHARGE",REG_CHARGE}, + {"USB0",REG_USB0}, + {"USB1",REG_USB1}, + {"LED_CTL0",REG_LED_CTL0}, + {"LED_CTL1",REG_LED_CTL1}, + {"LED_CTL2",REG_LED_CTL2}, + {"LED_CTL3",REG_LED_CTL3}, + {"UNUSED12",REG_UNUSED12}, + {"UNUSED13",REG_UNUSED13}, + {"TRIM0",REG_TRIM0}, + {"TRIM1",REG_TRIM1}, + {"TEST0",REG_TEST0}, + {"TEST1",REG_TEST1}, + {"TEST2",REG_TEST2}, + {"TEST3",REG_TEST3}, + {"TEST4",REG_TEST4}, + +}; + +static ssize_t pmic_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + u32 value; + int i; + + for(i = 0; i < ARRAY_SIZE(pmic_reg_tbl); i++) { + pmic_read(i, &value); + printk("%s: [%d] = 0x%08x\n", pmic_reg_tbl[i].name, i, value); + }; + + return 0/* strlen(buf) */; + +} + +static ssize_t pmic_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + char *token; + char *running; + const char delimiters[] = "="; + u32 addr, value; + + running = (char *)buf; + + token = strsep(&running, delimiters); + addr = simple_strtoul(token, &end, 10); + if(addr > 63) { + return -EINVAL; + } + + token = strsep(&running, delimiters); + if(token != NULL) { + value = simple_strtoul(token, &end, 16); + } else { + value = pmic_read(addr, &value); + printk("[%d] = 0x%08x\n", addr, value); + return -EINVAL; + } + + pmic_write(addr, value); + pmic_read(addr, &value); + + printk("[%d] = 0x%08x\n", addr, value); + + return count; +} + +static ssize_t edid_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + u8 buf0[2] = {0, 0}; + int data = 0; + u16 addr = 0x50; + u8 edid[128]; + int i; + struct i2c_adapter *adp; + struct i2c_msg msg[2] = { + { + .addr = addr, + .flags = 0, + .len = 1, + .buf = buf0, + }, { + .addr = addr, + .flags = I2C_M_RD, + .len = 128, + .buf = edid, + }, + }; + + adp = i2c_get_adapter(1); + + data = i2c_transfer(adp, msg, 2); + if(data <= 0) + return -ENODEV; + + for (i = 0; i < 128; i ++) { + printk("[%x]=%x\n", i, edid[i]); + } + + return 0; +} + +#define SBS_MFG_ACCESS 0x00 +#define SBS_REMAIN_CAPACITY_ALARM 0x01 +#define SBS_REMNAIN_TIME_ALARM 0x02 +#define SBS_BATTERY_MODE 0x03 +#define SBS_AT_RATE 0x04 +#define SBS_AT_RATE_TIME_TO_FULL 0x05 +#define SBS_AT_RATE_TIME_TO_EMPTY 0x06 +#define SBS_AT_RATE_OK 0x07 +#define SBS_TEMP 0x08 +#define SBS_VOLTAGE 0x09 +#define SBS_CURRENT 0x0A +#define SBS_AVG_CURRENT 0x0B +#define SBS_MAX_ERROR 0x0C +#define SBS_REL_STATE_OF_CHARGE 0x0D +#define SBS_ABS_STATE_OF_CHARGE 0x0E +#define SBS_REMAIN_CAPABILITY 0x0F +#define SBS_FULL_CHARGE_CAPACITY 0x10 +#define SBS_RUN_TIME_TO_EMPTY 0x11 +#define SBS_AVG_TIME_TO_EMPTY 0x12 +#define SBS_AVG_TIME_TO_FULL 0x13 +#define SBS_CHARGE_CURRENT 0x14 +#define SBS_CHARGE_VOLTAGE 0x15 +#define SBS_BATTERY_STATUS 0x16 +#define SBS_CYCLE_COUNT 0x17 +#define SBS_DESIGN_CAPACITY 0x18 +#define SBS_DESIGN_VOLTAGE 0x19 +#define SBS_SPEC_INFO 0x1A +#define SBS_MFG_DATE 0x1B +#define SBS_SERIAL_NO 0x1C +#define SBS_MFG_NAME 0x20 +#define SBS_DEV_NAME 0x21 +#define SBS_DEV_CHEMISTRY 0x22 +#define SBS_MFG_DATA 0x23 +#define SBS_BATTERY_USAGE 0x30 +#define SBS_PERMANENT_FAILURE 0x31 +#define SBS_BATTERY_LOG1 0x32 +#define SBS_BATTERY_LOG2 0x33 +#define SBS_FET_TEMP 0x3B +#define SBS_OPTION_MFG_FUNC5 0x2F +#define SBS_OPTION_MFG_FUNC4 0x3C +#define SBS_OPTION_MFG_FUNC3 0x3D +#define SBS_OPTION_MFG_FUNC2 0x3E +#define SBS_OPTION_MFG_FUNC1 0x3F + +struct sbs_reg_tbl { + char *name; + unsigned char reg_offset; +}; + +static struct sbs_reg_tbl reg_tbl[] = { + {"Manufacture Access", SBS_MFG_ACCESS}, + {"Remain Capacity Alarm", SBS_REMAIN_CAPACITY_ALARM }, + {"Remain Time Alarm", SBS_REMNAIN_TIME_ALARM}, + {"Battery Mode", SBS_BATTERY_MODE}, + {"AT Rate", SBS_AT_RATE}, + {"AT Rate Time To Full", SBS_AT_RATE_TIME_TO_FULL}, + {"AT Rate Time To Empty", SBS_AT_RATE_TIME_TO_EMPTY}, + {"AT Rate OK", SBS_AT_RATE_OK}, + {"Temperature", SBS_TEMP}, + {"Voltage", SBS_VOLTAGE}, + {"Current", SBS_CURRENT}, + {"Average Current", SBS_AVG_CURRENT}, + {"Maximum Error", SBS_MAX_ERROR}, + {"Relative State of Charge", SBS_REL_STATE_OF_CHARGE}, + {"Absolute State of Charge", SBS_ABS_STATE_OF_CHARGE}, + {"Remain Capacity", SBS_REMAIN_CAPABILITY}, + {"Full Charge Capacity", SBS_FULL_CHARGE_CAPACITY}, + {"Run Time To Empty", SBS_RUN_TIME_TO_EMPTY}, + {"Average Time To Empty", SBS_AVG_TIME_TO_EMPTY}, + {"Average Time To Full", SBS_AVG_TIME_TO_FULL}, + {"Charge Current", SBS_CHARGE_CURRENT}, + {"Charge Voltage", SBS_CHARGE_VOLTAGE}, + {"Battery Status", SBS_BATTERY_STATUS}, + {"Cycle Count", SBS_CYCLE_COUNT}, + {"Design Capacity", SBS_DESIGN_CAPACITY}, + {"Design Voltage", SBS_DESIGN_VOLTAGE}, + {"Spec Info", SBS_SPEC_INFO}, + {"Manufacture Date", SBS_MFG_DATE}, + {"Serial Number", SBS_SERIAL_NO}, + {"Manufacture Name", SBS_MFG_NAME}, + {"Device Name", SBS_DEV_NAME}, + {"Device Chemistry", SBS_DEV_CHEMISTRY}, + {"Manufacture Date", SBS_MFG_DATA}, + {"Battery Usage", SBS_BATTERY_USAGE}, + {"Permanent Failure", SBS_PERMANENT_FAILURE}, + {"Battery Log1", SBS_BATTERY_LOG1}, + {"Battery Log2", SBS_BATTERY_LOG2}, + {"FET Temperature", SBS_FET_TEMP}, + {"Optional Mfg Func5", SBS_OPTION_MFG_FUNC5}, + {"Optional Mfg Func4", SBS_OPTION_MFG_FUNC4}, + {"Optional Mfg Func3", SBS_OPTION_MFG_FUNC3}, + {"Optional Mfg Func2", SBS_OPTION_MFG_FUNC2}, + {"Optional Mfg Func1", SBS_OPTION_MFG_FUNC1}, + +}; + +static ssize_t battery_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct i2c_adapter *adp; + union i2c_smbus_data data; + int status; + int i; + + adp = i2c_get_adapter(1); + + for (i = 0; i < ARRAY_SIZE(reg_tbl); i++) { + status = i2c_smbus_xfer(adp, 0x0b, 0, + I2C_SMBUS_READ, reg_tbl[i].reg_offset, + I2C_SMBUS_WORD_DATA, &data); + if(status < 0) + return -ENODEV; + printk("%s: 0x%04x\n", reg_tbl[i].name, data.word); + } + + return 0; +} + +static ssize_t mtl017_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct i2c_adapter *adp; + union i2c_smbus_data data; + int status; + int i; + + adp = i2c_get_adapter(1); + + for (i = 0; i < 0xff; i++) { + status = i2c_smbus_xfer(adp, 0x3a, 0, + I2C_SMBUS_READ, i, + I2C_SMBUS_BYTE_DATA, &data); + if(status < 0) + return -ENODEV; + printk("[0x%x]: 0x%02x\n", i, data.byte); + } + return 0; + +} + +static ssize_t mtl017_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +#define SGTL5000_CHIP_ID 0x0000 +#define SGTL5000_CHIP_DIG_POWER 0x0002 +#define SGTL5000_CHIP_CLK_CTRL 0x0004 +#define SGTL5000_CHIP_I2S_CTRL 0x0006 +#define SGTL5000_CHIP_SSS_CTRL 0x000a +#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e +#define SGTL5000_CHIP_DAC_VOL 0x0010 +#define SGTL5000_CHIP_PAD_STRENGTH 0x0014 +#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020 +#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022 +#define SGTL5000_CHIP_ANA_CTRL 0x0024 +#define SGTL5000_CHIP_LINREG_CTRL 0x0026 +#define SGTL5000_CHIP_REF_CTRL 0x0028 +#define SGTL5000_CHIP_MIC_CTRL 0x002a +#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c +#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e +#define SGTL5000_CHIP_ANA_POWER 0x0030 +#define SGTL5000_CHIP_PLL_CTRL 0x0032 +#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034 +#define SGTL5000_CHIP_ANA_STATUS 0x0036 +#define SGTL5000_CHIP_SHORT_CTRL 0x003c +#define SGTL5000_CHIP_ANA_TEST2 0x003a +#define SGTL5000_DAP_CTRL 0x0100 +#define SGTL5000_DAP_PEQ 0x0102 +#define SGTL5000_DAP_BASS_ENHANCE 0x0104 +#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106 +#define SGTL5000_DAP_AUDIO_EQ 0x0108 +#define SGTL5000_DAP_SURROUND 0x010a +#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c +#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e +#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110 +#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116 +#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118 +#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a +#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c +#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e +#define SGTL5000_DAP_MAIN_CHAN 0x0120 +#define SGTL5000_DAP_MIX_CHAN 0x0122 +#define SGTL5000_DAP_AVC_CTRL 0x0124 +#define SGTL5000_DAP_AVC_THRESHOLD 0x0126 +#define SGTL5000_DAP_AVC_ATTACK 0x0128 +#define SGTL5000_DAP_AVC_DECAY 0x012a +#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c +#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e +#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130 +#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132 +#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134 +#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136 +#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138 +#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a + +struct sgtl_reg_tbl { + char *name; + unsigned int reg_addr; +}; + +struct sgtl_reg_tbl sgtl_tbl[] = { + {"ID", SGTL5000_CHIP_ID}, + {"POWER", SGTL5000_CHIP_DIG_POWER}, + {"CLK_CTRL", SGTL5000_CHIP_CLK_CTRL}, + {"I2S_CTRL", SGTL5000_CHIP_I2S_CTRL}, + {"SSS_CTRL", SGTL5000_CHIP_SSS_CTRL}, + {"ADCDAC_CTRL", SGTL5000_CHIP_ADCDAC_CTRL}, + {"DAC_VOL", SGTL5000_CHIP_DAC_VOL}, + {"PAD_STRENGTH", SGTL5000_CHIP_PAD_STRENGTH}, + {"ANA_ADC_CTRL", SGTL5000_CHIP_ANA_ADC_CTRL}, + {"ANA_HP_CTRL", SGTL5000_CHIP_ANA_HP_CTRL}, + {"ANA_CTRL", SGTL5000_CHIP_ANA_CTRL}, + {"LINREG_CTRL", SGTL5000_CHIP_LINREG_CTRL}, + {"REF_CTRL", SGTL5000_CHIP_REF_CTRL}, + {"MIC_CTRL", SGTL5000_CHIP_MIC_CTRL}, + {"LINE_OUT_CTRL", SGTL5000_CHIP_LINE_OUT_CTRL}, + {"LINE_OUT_VOL", SGTL5000_CHIP_LINE_OUT_VOL}, + {"ANA_POWER", SGTL5000_CHIP_ANA_POWER}, + {"PLL_CTRL", SGTL5000_CHIP_PLL_CTRL}, + {"CLK_TOP_CTRL", SGTL5000_CHIP_CLK_TOP_CTRL}, + {"ANA_STATUS", SGTL5000_CHIP_ANA_STATUS}, + {"SHORT_CTRL", SGTL5000_CHIP_SHORT_CTRL}, + {"ANA_TEST2", SGTL5000_CHIP_ANA_TEST2}, + {"DAP_CTRL", SGTL5000_DAP_CTRL}, + {"DAP_PEQ", SGTL5000_DAP_PEQ}, + {"DAP_BASS_ENHANCE", SGTL5000_DAP_BASS_ENHANCE}, + {"DAP_BASS_ENHANCE_CTRL", SGTL5000_DAP_BASS_ENHANCE_CTRL}, + {"DAP_AUDIO_EQ", SGTL5000_DAP_AUDIO_EQ}, + {"DAP_SURROUND", SGTL5000_DAP_SURROUND}, + {"DAP_FLT_COEF_ACCESS", SGTL5000_DAP_FLT_COEF_ACCESS}, + {"DAP_COEF_WR_B0_MSB", SGTL5000_DAP_COEF_WR_B0_MSB}, + {"DAP_COEF_WR_B0_LSB", SGTL5000_DAP_COEF_WR_B0_LSB}, + {"DAP_EQ_BASS_BAND0", SGTL5000_DAP_EQ_BASS_BAND0}, + {"DAP_EQ_BASS_BAND1", SGTL5000_DAP_EQ_BASS_BAND1}, + {"DAP_EQ_BASS_BAND2", SGTL5000_DAP_EQ_BASS_BAND2}, + {"DPA_EQ_BASS_BAND3", SGTL5000_DAP_EQ_BASS_BAND3}, + {"DAP_EQ_BASS_BAND4", SGTL5000_DAP_EQ_BASS_BAND4}, + {"DAP_MAIN_CHAIN", SGTL5000_DAP_MAIN_CHAN}, + {"DAP_MIX_CHAN", SGTL5000_DAP_MIX_CHAN}, + {"DAP_AVC_CTRL", SGTL5000_DAP_AVC_CTRL}, + {"DAP_AVC_THRESHOLD", SGTL5000_DAP_AVC_THRESHOLD}, + {"DAP_AVC_ATTACK", SGTL5000_DAP_AVC_ATTACK}, + {"DAP_AVC_DECAY", SGTL5000_DAP_AVC_DECAY}, + {"DAP_COEF_WR_B1_MSB", SGTL5000_DAP_COEF_WR_B1_MSB}, + {"DAP_COEF_WR_B1_LSB", SGTL5000_DAP_COEF_WR_B1_LSB}, + {"DAP_COEF_WR_B2_MSB", SGTL5000_DAP_COEF_WR_B2_MSB}, + {"DAP_COEF_WR_B2_LSB", SGTL5000_DAP_COEF_WR_B2_LSB}, + {"DAP_COEF_WR_A1_MSB", SGTL5000_DAP_COEF_WR_A1_MSB}, + {"DAP_COEF_WR_A1_LSB", SGTL5000_DAP_COEF_WR_A1_LSB}, + {"DAP_COEF_WR_A2_MSB", SGTL5000_DAP_COEF_WR_A2_MSB}, + {"DAP_COEF_WR_A2_LSB", SGTL5000_DAP_COEF_WR_A2_LSB}, +}; + +static unsigned int sgtl5000_hw_read(unsigned int reg) +{ + struct i2c_adapter *adp; + u8 buf0[2], buf1[2]; + u16 value; + int ret; + struct i2c_msg msg[2] = { + {0x0a, 0, 2, buf0}, + {0x0a, I2C_M_RD, 2, buf1}, + }; + + adp = i2c_get_adapter(1); + + buf0[0] = (reg & 0xff00) >> 8; + buf0[1] = reg & 0xff; + ret = i2c_transfer(adp, msg, 2); + if (ret < 0) { + return -ENODEV; + } + + value = buf1[0] << 8 | buf1[1]; + return value; + +} + +static unsigned int sgtl5000_hw_write(unsigned int reg, unsigned int value) +{ + struct i2c_adapter *adp; + u8 buf[4]; + int i2c_ret; + struct i2c_msg msg = { 0x0a, 0, 4, buf }; + + buf[0] = (reg & 0xff00) >> 8; + buf[1] = reg & 0xff; + buf[2] = (value & 0xff00) >> 8; + buf[3] = value & 0xff; + + adp = i2c_get_adapter(1); + i2c_ret = i2c_transfer(adp, &msg, 1); + if (i2c_ret < 0) { + return -EIO; + } + + return i2c_ret; +} + +static ssize_t sgtl5000_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + u32 value; + int i; + + for (i = 0; i < ARRAY_SIZE(sgtl_tbl); i++) { + value = sgtl5000_hw_read(sgtl_tbl[i].reg_addr); + if(value < 0) + return -ENODEV; + printk("%s:[0x%04x]=0x%04x\n", sgtl_tbl[i].name, sgtl_tbl[i].reg_addr, value); + } + + return 0; +} + +static ssize_t sgtl5000_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *end; + char *token; + char *running; + const char delimiters[] = "="; + u32 addr, value; + + running = (char *)buf; + + token = strsep(&running, delimiters); + addr = simple_strtoul(token, &end, 16); + if(addr > SGTL5000_DAP_COEF_WR_A2_LSB) { + return -EINVAL; + } + + token = strsep(&running, delimiters); + if(token != NULL) { + value = simple_strtoul(token, &end, 16); + } else { + value = sgtl5000_hw_read(addr); + printk("[%d] = 0x%04x\n", addr, value); + return -EINVAL; + } + + sgtl5000_hw_write(addr, value); + value = sgtl5000_hw_read(addr); + + printk("[%d] = 0x%04x\n", addr, value); + + return count; + +} + +static struct kobj_attribute reg_read_attribute = + __ATTR(reg_dump, 0666, reg_dump_show, reg_dump_store); +static struct kobj_attribute reg_write_attribute = + __ATTR(reg_write, 0666, reg_write_show, reg_write_store); +static struct kobj_attribute pmic_attribute = + __ATTR(pmic, 0666, pmic_show, pmic_store); +static struct kobj_attribute edid_attribute = + __ATTR(edid, 0666, edid_show, NULL); +static struct kobj_attribute battery_attribute = + __ATTR(battery, 0666, battery_show, NULL); +static struct kobj_attribute mtl017_attribute = + __ATTR(mtl017, 0666, mtl017_show, mtl017_store); +static struct kobj_attribute sgtl5000_attribute = + __ATTR(sgtl5000, 0666, sgtl5000_show, sgtl5000_store); + +static struct attribute *debug_attrs[] = { + ®_read_attribute.attr, + ®_write_attribute.attr, + &pmic_attribute.attr, + &edid_attribute.attr, + &battery_attribute.attr, + &mtl017_attribute.attr, + &sgtl5000_attribute.attr, + NULL, +}; + +static struct attribute_group debug_attr_group = { + .attrs = debug_attrs, +}; + + +static struct platform_device mxc_debug_device = { + .name = "mxc_debug", +}; + +static struct kobject *debug_kobj; + +static int __init mx51_debug_init(void) +{ + int retval; + + platform_device_register(&mxc_debug_device); + + debug_kobj = kobject_create_and_add("debug", &mxc_debug_device.dev.kobj); + if(!debug_kobj) + return -ENOMEM; + + + retval = sysfs_create_group(debug_kobj, &debug_attr_group); + if(retval) { + kobject_put(debug_kobj); + return retval; + } + + return 0; + +} + +static void __exit mx51_debug_exit(void) +{ + + sysfs_remove_group(debug_kobj, &debug_attr_group); + kobject_put(debug_kobj); + +} + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ron Lee , Pegatron Corp."); +module_init(mx51_debug_init) +module_exit(mx51_debug_exit) diff --git a/drivers/mxc/gps_ioctrl/Kconfig b/drivers/mxc/gps_ioctrl/Kconfig index 0a85d1636dd..debf6481109 100644 --- a/drivers/mxc/gps_ioctrl/Kconfig +++ b/drivers/mxc/gps_ioctrl/Kconfig @@ -6,7 +6,7 @@ menu "Broadcom GPS ioctrl support" config GPS_IOCTRL tristate "GPS ioctrl support" - depends on MACH_MX31_3DS || MACH_MX35_3DS || MACH_MX37_3DS || MACH_MX51_3DS + depends on MACH_MX31_3DS || MACH_MX35_3DS || MACH_MX37_3DS || MACH_MX51_3DS || MACH_MX51_EFIKASB ---help--- Say Y to enable Broadcom GPS ioctrl on MXC platform. diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index f90ffbf4c43..db418c7d536 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -124,4 +124,12 @@ config MXS_VBUS_CURRENT_DRAW Say Y to enable 100mA limitation when USB vbus power on system before enumeration to match USB2.0 requirement. + +config BATTERY_EFIKASB + tristate "Efikasb battery driver" + depends on I2C + help + Say Y here to enable support for Efikasb battery. + + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index cc430bda39d..5be85d8c664 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o obj-$(CONFIG_BATTERY_STMP3XXX) += stmp37xx/ obj-$(CONFIG_BATTERY_MXS) += mxs/ +obj-$(CONFIG_BATTERY_EFIKASB) += efikasb_battery.o \ No newline at end of file diff --git a/drivers/power/efikasb_battery.c b/drivers/power/efikasb_battery.c new file mode 100644 index 00000000000..bb877268f7f --- /dev/null +++ b/drivers/power/efikasb_battery.c @@ -0,0 +1,855 @@ +/* + * Efikasb Smart Battery driver + * + * Copyright (C) 2009 Ron Lee + * + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SBS_MFG_ACCESS 0x00 +#define SBS_REMAIN_CAPACITY_ALARM 0x01 +#define SBS_REMNAIN_TIME_ALARM 0x02 +#define SBS_BATTERY_MODE 0x03 +#define SBS_AT_RATE 0x04 +#define SBS_AT_RATE_TIME_TO_FULL 0x05 +#define SBS_AT_RATE_TIME_TO_EMPTY 0x06 +#define SBS_AT_RATE_OK 0x07 +#define SBS_TEMP 0x08 +#define SBS_VOLTAGE 0x09 +#define SBS_CURRENT 0x0A +#define SBS_AVG_CURRENT 0x0B +#define SBS_MAX_ERROR 0x0C +#define SBS_REL_STATE_OF_CHARGE 0x0D +#define SBS_ABS_STATE_OF_CHARGE 0x0E +#define SBS_REMAIN_CAPABILITY 0x0F +#define SBS_FULL_CHARGE_CAPACITY 0x10 +#define SBS_RUN_TIME_TO_EMPTY 0x11 +#define SBS_AVG_TIME_TO_EMPTY 0x12 +#define SBS_AVG_TIME_TO_FULL 0x13 +#define SBS_CHARGE_CURRENT 0x14 +#define SBS_CHARGE_VOLTAGE 0x15 +#define SBS_BATTERY_STATUS 0x16 +#define SBS_CYCLE_COUNT 0x17 +#define SBS_DESIGN_CAPACITY 0x18 +#define SBS_DESIGN_VOLTAGE 0x19 +#define SBS_SPEC_INFO 0x1A +#define SBS_MFG_DATE 0x1B +#define SBS_SERIAL_NO 0x1C +#define SBS_MFG_NAME 0x20 +#define SBS_DEV_NAME 0x21 +#define SBS_DEV_CHEMISTRY 0x22 +#define SBS_MFG_DATA 0x23 +#define SBS_BATTERY_USAGE 0x30 +#define SBS_PERMANENT_FAILURE 0x31 +#define SBS_BATTERY_LOG1 0x32 +#define SBS_BATTERY_LOG2 0x33 +#define SBS_FET_TEMP 0x3B +#define SBS_OPTION_MFG_FUNC5 0x2F +#define SBS_OPTION_MFG_FUNC4 0x3C +#define SBS_OPTION_MFG_FUNC3 0x3D +#define SBS_OPTION_MFG_FUNC2 0x3E +#define SBS_OPTION_MFG_FUNC1 0x3F + +/* SBS_BATTERY_STATUS Register Bit Mapping */ +#define SBS_STATUS_OVER_CHARGE_ALARM 0x8000 +#define SBS_STATUS_TERM_CHARGE_ALARM 0x4000 +#define SBS_STATUS_OVER_TEMP_ALARM 0x1000 +#define SBS_STATUS_TERM_DISCHARGE_ALARM 0x0800 +#define SBS_STATUS_REMAIN_CAPACITY_ALARM 0x0200 +#define SBS_STATUS_REMAIN_TIME_ALARM 0x0100 + +#define SBS_STATUS_INITIALIZED 0x0080 +#define SBS_STATUS_DISCHARGING 0x0040 +#define SBS_STATUS_FULLY_CHARGED 0x0020 +#define SBS_STATUS_FULLY_DISCHARGED 0x0010 + +static void update_status_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(update_status_work, update_status_worker); + +static void batt_capacity_worker(struct work_struct *work); +static DECLARE_WORK(batt_capacity_work, batt_capacity_worker); + +static void power_off_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(power_off_work, power_off_worker); + +extern void kernel_power_off(void); + +struct sbs_reg_tbl { + char *name; + unsigned char reg_offset; +}; + +#ifdef EFIKASB_BATTERY_DEBUG +static struct sbs_reg_tbl reg_tbl[] = { + {"Manufacture Access", SBS_MFG_ACCESS}, + {"Remain Capacity Alarm", SBS_REMAIN_CAPACITY_ALARM }, + {"Remain Time Alarm", SBS_REMNAIN_TIME_ALARM}, + {"Battery Mode", SBS_BATTERY_MODE}, + {"AT Rate", SBS_AT_RATE}, + {"AT Rate Time To Full", SBS_AT_RATE_TIME_TO_FULL}, + {"AT Rate Time To Empty", SBS_AT_RATE_TIME_TO_EMPTY}, + {"AT Rate OK", SBS_AT_RATE_OK}, + {"Temperature", SBS_TEMP}, + {"Voltage", SBS_VOLTAGE}, + {"Current", SBS_CURRENT}, + {"Average Current", SBS_AVG_CURRENT}, + {"Maximum Error", SBS_MAX_ERROR}, + {"Relative State of Charge", SBS_REL_STATE_OF_CHARGE}, + {"Absolute State of Charge", SBS_ABS_STATE_OF_CHARGE}, + {"Remain Capacity", SBS_REMAIN_CAPABILITY}, + {"Full Charge Capacity", SBS_FULL_CHARGE_CAPACITY}, + {"Run Time To Empty", SBS_RUN_TIME_TO_EMPTY}, + {"Average Time To Empty", SBS_AVG_TIME_TO_EMPTY}, + {"Average Time To Full", SBS_AVG_TIME_TO_FULL}, + {"Charge Current", SBS_CHARGE_CURRENT}, + {"Charge Voltage", SBS_CHARGE_VOLTAGE}, + {"Battery Status", SBS_BATTERY_STATUS}, + {"Cycle Count", SBS_CYCLE_COUNT}, + {"Design Capacity", SBS_DESIGN_CAPACITY}, + {"Design Voltage", SBS_DESIGN_VOLTAGE}, + {"Spec Info", SBS_SPEC_INFO}, + {"Manufacture Date", SBS_MFG_DATE}, + {"Serial Number", SBS_SERIAL_NO}, + {"Manufacture Name", SBS_MFG_NAME}, + {"Device Name", SBS_DEV_NAME}, + {"Device Chemistry", SBS_DEV_CHEMISTRY}, + {"Manufacture Date", SBS_MFG_DATA}, + {"Battery Usage", SBS_BATTERY_USAGE}, + {"Permanent Failure", SBS_PERMANENT_FAILURE}, + {"Battery Log1", SBS_BATTERY_LOG1}, + {"Battery Log2", SBS_BATTERY_LOG2}, + {"FET Temperature", SBS_FET_TEMP}, + {"Optional Mfg Func5", SBS_OPTION_MFG_FUNC5}, + {"Optional Mfg Func4", SBS_OPTION_MFG_FUNC4}, + {"Optional Mfg Func3", SBS_OPTION_MFG_FUNC3}, + {"Optional Mfg Func2", SBS_OPTION_MFG_FUNC2}, + {"Optional Mfg Func1", SBS_OPTION_MFG_FUNC1}, + +}; + +void dump_sbs_reg(struct i2c_client *client) +{ + int i; + unsigned int value; + + printk("Dump Smart Battery Register\n"); + for (i = 0; i < ARRAY_SIZE(reg_tbl); i ++) { + value = i2c_smbus_read_word_data(client, reg_tbl[i].reg_offset); + printk("%s: 0x%04x\n", reg_tbl[i].name, value); + } +} +#else +void dump_sbs_reg(struct i2c_client *client) {} +#endif + +struct efikasb_batt_dev_info; + +struct efikasb_batt_dev_info { + struct device *dev; + struct i2c_client *client; + struct power_supply *bat; + struct power_supply *ac_charger; + char mfg_name[32]; + char model_name[32]; + char serial[32]; + char chemistry[32]; + + int batt_in_irq; + int batt_low_irq; + int ac_in_irq; + + int batt_in; + int ac_in; + int batt_low; + u32 capacity; + + int (*get_batt_in_status) (void); + int (*get_batt_low_status) (void); + int (*get_ac_in_status) (void); + void (*set_batt_low_led) (int); + + struct timer_list batt_low_timer; +}; + +static struct efikasb_batt_dev_info *batt = NULL; + +static enum power_supply_property efikasb_batt_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, +/* POWER_SUPPLY_PROP_HEALTH, */ + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, + +}; + +static enum power_supply_property efikasb_ac_charger_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static int efikasb_batt_read(struct i2c_client *client, u8 reg, u32 *value) +{ + int ret; + int retry = 5; + + retry: + ret = i2c_smbus_read_word_data(client, reg); + if(ret < 0) { /* ron: retry i2c again to avoid conflict with PIC */ + if(retry -- > 0) + goto retry; + return ret; + } + + *value = ret; + return 0; +} + +/* Smart Battery Helper Function */ +static int efikasb_batt_get_status(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_BATTERY_STATUS, value); +} + +static int efikasb_batt_get_current(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_CURRENT, value); +} + +static int efikasb_batt_get_voltage(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_VOLTAGE, value); +} + +static int efikasb_batt_get_average_current(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_AVG_CURRENT, value); +} + +static int efikasb_batt_get_capacity(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_REL_STATE_OF_CHARGE, value); +} + +static int efikasb_batt_get_temperature(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_TEMP, value); +} + +static int efikasb_batt_run_time_to_empty(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_RUN_TIME_TO_EMPTY, value); +} + +static int efikasb_batt_avg_time_to_empty(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_AVG_TIME_TO_EMPTY, value); +} + +static int efikasb_batt_avg_time_to_full(struct efikasb_batt_dev_info *di, u32 *value) +{ + return efikasb_batt_read(di->client, SBS_AVG_TIME_TO_FULL, value); +} + +static int efikasb_batt_get_serial_no(struct efikasb_batt_dev_info *di) +{ + int ret; + u32 sn; + + ret = efikasb_batt_read(di->client, SBS_SERIAL_NO, &sn); + if(ret != 0) + return ret; + + sprintf(di->serial, "%d", sn); + + return ret; +} + +static int efikasb_batt_get_mfg_name(struct efikasb_batt_dev_info *di) +{ + int ret; + char mfg[33]; + + ret = i2c_smbus_read_i2c_block_data(di->client, SBS_MFG_NAME, 32, mfg); + if(ret < 0) + return ret; + + if(mfg[0] > sizeof(di->mfg_name)) + return -EINVAL; + + strncpy(di->mfg_name, &mfg[1], mfg[0]); + return 0; +} + +static int efikasb_batt_get_model_name(struct efikasb_batt_dev_info *di) +{ + int ret; + char model[33]; + + ret = i2c_smbus_read_i2c_block_data(di->client, SBS_DEV_NAME, 32, model); + if(ret < 0) + return ret; + + if(model[0] > sizeof(di->model_name)) + return -EINVAL; + + strncpy(di->model_name, &model[1], model[0]); + return 0; +} + +static int efikasb_batt_get_technology(struct efikasb_batt_dev_info *di) +{ + int ret; + char chem[33]; + + ret = i2c_smbus_read_i2c_block_data(di->client, SBS_DEV_CHEMISTRY, 32, chem); + if(ret < 0) + return ret; + + if(chem[0] > sizeof(di->chemistry)) + return -EINVAL; + + strncpy(di->chemistry, &chem[1], chem[0]); +/* printk("Technology: %s\n", di->chemistry); */ + + if (!strcasecmp("NiCd", di->chemistry)) + return POWER_SUPPLY_TECHNOLOGY_NiCd; + if (!strcasecmp("NiMH", di->chemistry)) + return POWER_SUPPLY_TECHNOLOGY_NiMH; + if (!strcasecmp("LION", di->chemistry)) + return POWER_SUPPLY_TECHNOLOGY_LION; + if (!strncasecmp("LI-ION", di->chemistry, 6)) + return POWER_SUPPLY_TECHNOLOGY_LION; + if (!strcasecmp("LiP", di->chemistry)) + return POWER_SUPPLY_TECHNOLOGY_LIPO; + return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; + +} + +#define to_efikasb_batt_device_info(x) container_of((x), \ + struct efikasb_batt_dev_info, bat); + +static int efikasb_batt_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct efikasb_batt_dev_info *di = batt; + u32 value; + int ret; + int batt_in, ac_in; + + batt_in = di->get_batt_in_status(); + + if (!batt_in) { + val->intval = 0; + return -ENODEV; + } + + ac_in = di->get_ac_in_status(); + + switch(psp) { + case POWER_SUPPLY_PROP_PRESENT: + val->intval = di->get_batt_in_status(); + break; + case POWER_SUPPLY_PROP_STATUS: + if (ac_in) { + ret = efikasb_batt_get_status(di, &value); + if (ret != 0) { + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + return 0; + } + + if (value & SBS_STATUS_FULLY_CHARGED) + val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_CHARGING; + } else { + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + } + + break; + + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = efikasb_batt_get_technology(di); + break; + + case POWER_SUPPLY_PROP_VOLTAGE_NOW: /* mV */ + ret = efikasb_batt_get_voltage(di, &value); + if(ret != 0) { + val->intval = 0; + break; + } + + val->intval = value; + break; + + case POWER_SUPPLY_PROP_CURRENT_NOW: /* mA */ + ret = efikasb_batt_get_current(di, &value); + if(ret != 0) { + val->intval = 0; + return ret; + } + + val->intval = value; + break; + + case POWER_SUPPLY_PROP_CURRENT_AVG: /* mA in 1 minute rolling avg */ + ret = efikasb_batt_get_average_current(di, &value); + if(ret != 0) + return ret; + val->intval = value; + break; + + case POWER_SUPPLY_PROP_CAPACITY: /* % percent */ + ret = efikasb_batt_get_capacity(di, &value); + if(ret != 0) + return ret; + val->intval = value; + di->capacity = value; /* ron: cache the battery capacity */ + break; + + case POWER_SUPPLY_PROP_TEMP: /* K degree */ + ret = efikasb_batt_get_temperature(di, &value); + if(ret != 0) + return ret; + val->intval = value; + break; + + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: /* minutes */ + ret = efikasb_batt_run_time_to_empty(di, &value); + if(ret != 0) + return ret; + val->intval = value; + break; + + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: /* minutes */ + ret = efikasb_batt_avg_time_to_empty(di, &value); + if(ret != 0) + return ret; + val->intval = value; + break; + + case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: /* minutes */ + ret = efikasb_batt_avg_time_to_full(di, &value); + if(ret != 0) + return ret; + val->intval = value; + break; + + case POWER_SUPPLY_PROP_MODEL_NAME: + ret = efikasb_batt_get_model_name(di); + if(ret < 0) + return ret; + val->strval = di->model_name; + break; + + case POWER_SUPPLY_PROP_MANUFACTURER: + ret = efikasb_batt_get_mfg_name(di); + if(ret < 0) + return ret; + val->strval = di->mfg_name; + break; + case POWER_SUPPLY_PROP_SERIAL_NUMBER: + ret = efikasb_batt_get_serial_no(di); + if(ret < 0) + return ret; + val->strval = di->serial; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int efikasb_ac_charger_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct efikasb_batt_dev_info *di = batt; + + switch(psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = di->get_ac_in_status(); + break; + default: + return -EINVAL; + break; + } + + return 0; +} + +static struct power_supply efikasb_batt = { + .name = "efikasb_battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = efikasb_batt_props, + .num_properties = ARRAY_SIZE(efikasb_batt_props), + .get_property = efikasb_batt_get_property, + .external_power_changed = NULL, + +}; + +static struct power_supply efikasb_ac_charger = { + .name = "efikasb_ac_charger", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = efikasb_ac_charger_props, + .num_properties = ARRAY_SIZE(efikasb_ac_charger_props), + .get_property = efikasb_ac_charger_get_property, + .external_power_changed = NULL, +}; + +static void update_status_worker(struct work_struct *work) +{ + power_supply_changed(batt->ac_charger); + power_supply_changed(batt->bat); +} + + +static irqreturn_t efikasb_ac_detect_handler(int irq, void *data) +{ + struct efikasb_batt_dev_info *di = data; + + di->ac_in = di->get_ac_in_status(); + printk("efikasb_ac_charger: AC %s\n", + di->ac_in ? "Inserted" : "Removed"); + + schedule_delayed_work(&update_status_work, msecs_to_jiffies(1500)); + + if (di->ac_in) { + if(di->set_batt_low_led) + di->set_batt_low_led(0); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + mod_timer(&di->batt_low_timer, jiffies + 10); + } else { + mod_timer(&di->batt_low_timer, jiffies + 10); + set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + } + + return IRQ_HANDLED; +} + +static irqreturn_t efikasb_batt_detect_handler(int irq, void *data) +{ + struct efikasb_batt_dev_info *di = data; + + di->batt_in = di->get_batt_in_status(); + printk("efikasb_battery: Battery %s\n", + di->batt_in ? "Inserted" : "Removed"); + + schedule_delayed_work(&update_status_work, msecs_to_jiffies(1500)); + + if (di->batt_in) { + mod_timer(&di->batt_low_timer, jiffies + 10); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + } else { + if(di->set_batt_low_led) + di->set_batt_low_led(0); + set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + } + + return IRQ_HANDLED; +} + +static void power_off_worker(struct work_struct *work) +{ + if(!batt->ac_in && batt->batt_low && batt->capacity == 0) { + sys_sync(); + kernel_power_off(); + } +} + +static irqreturn_t efikasb_batt_low_handler(int irq, void *data) +{ + struct efikasb_batt_dev_info *di = data; + + di->batt_low = batt->get_batt_low_status(); + printk("efikasb_batter: Battery %s\n", + di->batt_low ? "Low" : "Normal"); + + if (di->batt_low) { + set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + } else { + set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); + } + + return IRQ_HANDLED; +} + +static void batt_capacity_worker(struct work_struct *work) +{ + int ret; + u32 capacity; + + if(batt->batt_in) { + ret = efikasb_batt_get_capacity(batt, &capacity); + if(ret == 0) + batt->capacity = capacity; + + if(!batt->ac_in && batt->capacity == 0) { + sys_sync(); + kernel_power_off(); + } + } + +} + +static void batt_low_fn(unsigned long data) +{ + struct efikasb_batt_dev_info *di = (struct efikasb_batt_dev_info *)data; + + if(!di->batt_in) + return; + + if(!di->ac_in && di->batt_in) { /* battery is discharging */ + schedule_work(&batt_capacity_work); + if(di->set_batt_low_led) { + if(di->capacity <= 10) + di->set_batt_low_led(1); + else + di->set_batt_low_led(0); + + if(di->capacity <= 11 && di->capacity > 9) { + mod_timer(&di->batt_low_timer, jiffies + 4 * HZ); + } + + if(di->capacity <= 9 || di->capacity > 11) { + mod_timer(&di->batt_low_timer, jiffies + 60 * HZ); + } + } else { + mod_timer(&di->batt_low_timer, jiffies + 60 * HZ); + } + } else if(di->batt_in) { /* battery is charging */ + mod_timer(&di->batt_low_timer, jiffies + 60 * HZ); + } + + /* battery is not charging and capacity is critical low, power off immediately */ + if(!di->ac_in && di->batt_in && di->capacity == 0) + schedule_delayed_work(&power_off_work, msecs_to_jiffies(1000)); + +} + +static int efikasb_batt_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct efikasb_batt_dev_info *di; + struct mxc_battery_platform_data *platform_data; + int retval = 0; + + platform_data = (struct mxc_battery_platform_data *)client->dev.platform_data; + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if(!di) { + dev_err(&client->dev, "failed to allocate device info\n"); + retval = -ENOMEM; + return retval; + } + + batt = di; + + i2c_set_clientdata(client, di); + di->dev = &client->dev; + di->client = client; + di->bat = &efikasb_batt; + di->ac_charger = &efikasb_ac_charger; + + di->get_batt_in_status = platform_data->get_batt_in_status; + di->get_batt_low_status = platform_data->get_batt_low_status; + di->get_ac_in_status = platform_data->get_ac_in_status; + di->set_batt_low_led = platform_data->set_batt_low_led; + + if(di->get_batt_in_status) + di->batt_in = di->get_batt_in_status(); + if(di->get_ac_in_status) + di->ac_in = di->get_ac_in_status(); + if(di->get_batt_low_status) + di->batt_low = di->get_batt_low_status(); + + di->batt_in_irq = platform_data->batt_in_irq; + di->batt_low_irq = platform_data->batt_low_irq; + di->ac_in_irq = platform_data->ac_in_irq; + +#ifndef CONFIG_EFIKASB_EXPERIMENTAL_OS + if(di->batt_in) { + retval = request_irq(di->batt_in_irq, + efikasb_batt_detect_handler, \ + IRQ_TYPE_EDGE_RISING, + "efikasb_battery", di); + } else { + retval = request_irq(di->batt_in_irq, + efikasb_batt_detect_handler, + IRQ_TYPE_EDGE_FALLING, + "efikasb_battery", di); + } + if(retval) + goto batt_irq_failed; + + if(di->ac_in) { + retval = request_irq(di->ac_in_irq, + efikasb_ac_detect_handler, + IRQ_TYPE_EDGE_RISING, + "efikasb_ac_charger", di); + } else { + retval = request_irq(di->ac_in_irq, + efikasb_ac_detect_handler, + IRQ_TYPE_EDGE_FALLING, + "efikasb_ac_charger", di); + } + if(retval) + goto ac_irq_failed; + + if(di->batt_low) { + retval = request_irq(di->batt_low_irq, + efikasb_batt_low_handler, + IRQ_TYPE_LEVEL_HIGH, "efikasb_batt_low", di); + } else { + retval = request_irq(di->batt_low_irq, + efikasb_batt_low_handler, + IRQ_TYPE_LEVEL_LOW, "efikasb_batt_low", di); + } + if(retval) + goto batt_low_irq_failed; + + /* ron: the battery low pin is triggered at 10% battery capacity, + battery critical low won't generate wake up event, + the battery power may be exhauseted */ + /* enable_irq_wake(di->batt_low_irq); */ +#endif + + retval = power_supply_register(&client->dev, &efikasb_batt); + if(retval) { + dev_err(&client->dev, "failed to register battery\n"); + goto batt_failed; + } + + retval =power_supply_register(&client->dev, &efikasb_ac_charger); + if(retval) { + dev_err(&client->dev, "failed to register ac charger\n"); + goto ac_charger_failed; + } + if(di->batt_in) { + efikasb_batt_get_mfg_name(di); + efikasb_batt_get_model_name(di); + efikasb_batt_get_capacity(di, &di->capacity); + } + + + printk("Probe Efikasb Battery: %s %s %s: %d%%, AC %s\n", + di->mfg_name, di->model_name, + di->batt_in ? "Inserted" : "Removed", di->capacity, + di->ac_in ? "Inserted" : "Removed"); + + dump_sbs_reg(client); + + init_timer(&di->batt_low_timer); + di->batt_low_timer.data = (unsigned long)di; + di->batt_low_timer.function = batt_low_fn; + di->batt_low_timer.expires = jiffies + 10; + if(!di->ac_in && di->batt_in) + add_timer(&di->batt_low_timer); + + /* ron: if battery critical low, shutdown immediately */ + if(!di->ac_in && di->batt_low && di->capacity == 0) { + printk("Battery critical low, shutdown now....\n"); + schedule_delayed_work(&power_off_work, msecs_to_jiffies(1000)); + } + + return 0; + + ac_charger_failed: + power_supply_unregister(&efikasb_batt); + batt_failed: + free_irq(di->batt_low_irq, NULL); + batt_low_irq_failed: + free_irq(di->ac_in_irq, NULL); + ac_irq_failed: + free_irq(di->batt_in_irq, NULL); + batt_irq_failed: + i2c_set_clientdata(client, NULL); + kfree(di); + return retval; +} + +static int efikasb_batt_i2c_remove(struct i2c_client *client) +{ + struct efikasb_batt_dev_info *di = i2c_get_clientdata(client); + + power_supply_unregister(&efikasb_batt); + power_supply_unregister(&efikasb_ac_charger); + free_irq(di->batt_in_irq, NULL); + free_irq(di->ac_in_irq, NULL); + kfree(di); + batt = NULL; + + return 0; +} + +static const struct i2c_device_id efikasb_batt_id[] = { + { "efikasb-battery", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, efikasb_batt_id); + +static struct i2c_driver efikasb_batt_i2c_driver = { + .driver = { + .name = "efikasb-battery", + }, + .probe = efikasb_batt_i2c_probe, + .remove = efikasb_batt_i2c_remove, + .id_table = efikasb_batt_id, +}; + +static int __init efikasb_batt_init(void) +{ + int ret; + + ret = i2c_add_driver(&efikasb_batt_i2c_driver); + if(ret) + printk(KERN_ERR "Unable to register Efikasb Battery Driver\n"); + + return ret; +} +module_init(efikasb_batt_init); + +static void __exit efikasb_batt_exit(void) +{ + i2c_del_driver(&efikasb_batt_i2c_driver); + +} +module_exit(efikasb_batt_exit); + +MODULE_AUTHOR("Ron Lee "); +MODULE_DESCRIPTION("Efikasb Smart Battery Driver"); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 17432a6edfa..67ca5fe4613 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -258,6 +258,12 @@ config BACKLIGHT_MXC_MC13892 depends on BACKLIGHT_MXC && MXC_MC13892_LIGHT default y + +config BACKLIGHT_MXC_EFIKASB + tristate "MXC Efikasb LCD Backlight Driver" + depends on BACKLIGHT_MXC + default y + config BACKLIGHT_STMP37XX tristate "SigmaTel STMP37xx Backlight Driver" depends on BACKLIGHT_CLASS_DEVICE && (ARCH_STMP37XX || ARCH_STMP378X) diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 2f530db27d5..ede12e7ea85 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_BACKLIGHT_MXC_IPU) += mxc_ipu_bl.o obj-$(CONFIG_BACKLIGHT_MXC_PMIC) += mxc_pmic_bl.o obj-$(CONFIG_BACKLIGHT_WM8350) += wm8350_bl.o obj-$(CONFIG_BACKLIGHT_MXC_MC13892) += mxc_mc13892_bl.o +obj-$(CONFIG_BACKLIGHT_MXC_EFIKASB) += mxc_efikasb_bl.o obj-$(CONFIG_BACKLIGHT_STMP37XX) += stmp37xx_bl.o obj-$(CONFIG_BACKLIGHT_MXS) += mxs_bl.o diff --git a/drivers/video/backlight/mxc_efikasb_bl.c b/drivers/video/backlight/mxc_efikasb_bl.c new file mode 100644 index 00000000000..bb0aee5b4ea --- /dev/null +++ b/drivers/video/backlight/mxc_efikasb_bl.c @@ -0,0 +1,332 @@ +/* + * Copyright 2007 Pegatron Corp, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +/*! + * @defgroup LCDC_BL MXC LCDC Backlight Driver + */ +/*! + * @file mxc_efikasb_bl.c + * + * @brief Backlight Driver for LCDC PWM on Freescale MXC/i.MX Efikasb platforms. + * + * This file contains API defined in include/linux/clk.h for setting up and + * retrieving clocks. + * + * Based on Sharp's Corgi Backlight Driver + * + * @ingroup LCDC_BL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXC_MAX_BL_LEVEL 11 +#define MXC_MIN_BL_LEVEL 0 +#define MXC_DFL_BL_LEVEL 6 + +#define MXC_MAX_INTENSITY 255 +#define MXC_DEFAULT_INTENSITY 127 +#define MXC_INTENSITY_OFF 0 +#define MXC_PWM_PERIOD_NS 78770 + +#define MXC_PWMCR (0x00) +#define MXC_PWMSR (0x04) +#define MXC_PWMIR (0x08) +#define MXC_PWMSAR (0x0C) +#define MXC_PWMPR (0x10) +#define MXC_PWMCNR (0x14) + +#define MXC_PWMCR_EN (1) +#define MXC_PWMCR_PRESCALER_MASK (0xFFFF000F) +#define MXC_PWMCR_PRESCALER_OFFSET (4) +#define MXC_PWMCR_CLKSRC_OFF (0) +#define MXC_PWMCR_CLKSRC_IPG (1 << 16) +#define MXC_PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define MXC_PWMCR_CLKSRC_32K (3 << 16) +#define MXC_PWMCR_STOPEN (1 << 25) +#define MXC_PWMCR_DOZEEN (1 << 24) +#define MXC_PWMCR_WAITEN (1 << 23) +#define MXC_PWMCR_DBGEN (1 << 22) + +#define MXC_PWMSAR_SAMPLE_MASK (0xFFFF0000) +#define MXC_PWMPR_PERIOD_MASK (0xFFFF0000) + +#define MXC_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) + +int bl_level_to_pwm_map[MXC_MAX_BL_LEVEL] = { + 0, 4, 25, 63, 75, 101, 127, 153, 179, 205, 231, 255, +}; + +static BLOCKING_NOTIFIER_HEAD(backlight_notifier_list); + +int register_backlight_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&backlight_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(register_backlight_notifier); + +int unregister_backlight_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&backlight_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_backlight_notifier); + +struct mxcbl_dev_data { + void *base; + struct clk *clk; + int clk_enabled; + int intensity; + int suspend; +}; + +static int mxc_pwm_enable(struct mxcbl_dev_data *mxc_bl) +{ + unsigned long reg; + int rc = 0; + + if (!mxc_bl->clk_enabled) { + rc = clk_enable(mxc_bl->clk); + if (!rc) + mxc_bl->clk_enabled = 1; + } + + reg = __raw_readl(mxc_bl->base + MXC_PWMCR); + reg |= MXC_PWMCR_EN; + __raw_writel(reg, mxc_bl->base + MXC_PWMCR); + return rc; +} + +static void mxc_pwm_disable(struct mxcbl_dev_data *mxc_bl) +{ + unsigned long reg; + + if (mxc_bl->clk_enabled) { + clk_disable(mxc_bl->clk); + mxc_bl->clk_enabled = 0; + } + + reg = __raw_readl(mxc_bl->base + MXC_PWMCR); + reg &= ~MXC_PWMCR_EN; + __raw_writel(reg, mxc_bl->base + MXC_PWMCR); + +} + +void mxc_set_brightness(struct mxcbl_dev_data *mxc_bl, uint8_t level) +{ + unsigned long long c; + unsigned long period_cycles, duty_cycles, prescale; + int duty_ns, period_ns; + + //printk("mxc_set_brightness: level=%x\n", level); + +#if 0 + period_ns = MXC_PWM_PERIOD_NS; + duty_ns = level * period_ns / MXC_MAX_INTENSITY; + + c = clk_get_rate(mxc_bl->clk) * 665 / 80; + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + prescale = period_cycles / 0x10000 + 1; + + period_cycles /= prescale; + c = (unsigned long long)period_cycles * duty_ns; + do_div(c, period_ns); + duty_cycles = c; +#else + /* ron: hard code the PWM configuration */ + prescale = 300; + period_cycles = 0x03f1; + duty_cycles = bl_level_to_pwm_map[level] * period_cycles / MXC_MAX_INTENSITY; +#endif + //printk("duty_cycles %d, period_cycles %d\n", duty_cycles, period_cycles); + __raw_writel(duty_cycles, mxc_bl->base + MXC_PWMSAR); + __raw_writel(period_cycles, mxc_bl->base + MXC_PWMPR); + __raw_writel(MXC_PWMCR_PRESCALER(prescale) | + MXC_PWMCR_CLKSRC_IPG | + MXC_PWMCR_STOPEN | MXC_PWMCR_DOZEEN | + MXC_PWMCR_WAITEN | MXC_PWMCR_DBGEN | MXC_PWMCR_EN, + mxc_bl->base + MXC_PWMCR); +} + +#define BL_BRIGHTNESS 0x01 + +static int mxcbl_set_brightness(struct backlight_device *bd) +{ + int level = bd->props.brightness; + struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); + + if (level > MXC_MAX_BL_LEVEL) + return 0; + + if (bd->props.power != FB_BLANK_UNBLANK) + level = 0; + if (bd->props.fb_blank != FB_BLANK_UNBLANK) + level = 0; + + if (level && !devdata->clk_enabled) + mxc_pwm_enable(devdata); + + mxc_set_brightness(devdata, level); + + if (level == 0 && devdata->clk_enabled) + mxc_pwm_disable(devdata); + + devdata->intensity = bl_level_to_pwm_map[level]; + blocking_notifier_call_chain(&backlight_notifier_list, BL_BRIGHTNESS, &level); + + return 0; +} + +static int mxcbl_get_brightness(struct backlight_device *bd) +{ + struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); + printk("intensity=%d\n", devdata->intensity); + return bd->props.brightness; +} + +static int mxcbl_check_fb(struct fb_info *info) +{ + + if (strcmp(info->fix.id, "DISP0 BG") == 0) { + return 1; + } + return 0; +} + +static struct backlight_ops mxcbl_ops = { + .get_brightness = mxcbl_get_brightness, + .update_status = mxcbl_set_brightness, + .check_fb = mxcbl_check_fb, +}; + +static int __init mxcbl_probe(struct platform_device *pdev) +{ + struct backlight_device *bd; + struct mxcbl_dev_data *devdata; + int ret = 0; + + devdata = kzalloc(sizeof(struct mxcbl_dev_data), GFP_KERNEL); + if (!devdata) + return -ENOMEM; +; + /* ron: TBD */ + devdata->base = IO_ADDRESS(PWM1_BASE_ADDR); + devdata->clk = clk_get(&pdev->dev, "pwm"); + devdata->clk_enabled = 0; + mxc_pwm_enable(devdata); + +#if 0 //vv, 20100316 dev.bus_id is deprecated, change to use dev_name(&pdev->dev) + bd = backlight_device_register(pdev->dev.bus_id, &pdev->dev, devdata, + &mxcbl_ops); +#else + bd = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, devdata, + &mxcbl_ops); +#endif + + if (IS_ERR(bd)) { + ret = PTR_ERR(bd); + goto err0; + } + + platform_set_drvdata(pdev, bd); + + bd->props.brightness = MXC_DFL_BL_LEVEL; + bd->props.max_brightness = MXC_MAX_BL_LEVEL; + bd->props.power = FB_BLANK_UNBLANK; + bd->props.fb_blank = FB_BLANK_UNBLANK; + mxc_set_brightness(devdata, MXC_DFL_BL_LEVEL); + + /*printk("MXC Backlight Device %s Initialized.\n", pdev->dev.bus_id);*/ + printk("MXC Backlight Device %s Initialized.\n", dev_name(&pdev->dev)); + + return 0; + +err0: + + mxc_pwm_disable(devdata); + kfree(devdata); + return ret; +} + +static int mxcbl_remove(struct platform_device *pdev) +{ + struct backlight_device *bd = platform_get_drvdata(pdev); + struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); + + bd->props.brightness = MXC_INTENSITY_OFF; + backlight_update_status(bd); + mxc_pwm_disable(devdata); + backlight_device_unregister(bd); + + return 0; +} + +static int mxcbl_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct backlight_device *bd = platform_get_drvdata(pdev); + struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); + + devdata->suspend = 1; + backlight_update_status(bd); + mxc_pwm_disable(devdata); + + return 0; +} + +static int mxcbl_resume(struct platform_device *pdev) +{ + struct backlight_device *bd = platform_get_drvdata(pdev); + struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); + + mxc_pwm_enable(devdata); + devdata->suspend = 0; + backlight_update_status(bd); + + return 0; +} + +static struct platform_driver mxcbl_driver = { + .probe = mxcbl_probe, + .remove = mxcbl_remove, + .suspend = mxcbl_suspend, + .resume = mxcbl_resume, + .driver = { + .name = "mxc_efikasb_bl", + }, +}; + +static int __init mxcbl_init(void) +{ + + return platform_driver_register(&mxcbl_driver); +} + +static void __exit mxcbl_exit(void) +{ + platform_driver_unregister(&mxcbl_driver); +} + +module_init(mxcbl_init); +module_exit(mxcbl_exit); + +MODULE_DESCRIPTION("Pegatron iMX51 Efikasb LCDC PWM Backlight Driver"); +MODULE_AUTHOR("Pegatron Corp."); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/mxc/Kconfig b/drivers/video/mxc/Kconfig index 424c6b826ef..00c9c084dcf 100644 --- a/drivers/video/mxc/Kconfig +++ b/drivers/video/mxc/Kconfig @@ -42,6 +42,20 @@ config FB_MXC_SII9022 depends on FB_MXC_SYNC_PANEL tristate "SII9022A HDMI Interface Chip" +config FB_MXC_CS8556 + depends on FB_MXC_SYNC_PANEL + tristate "Myson CS8556 VGA Interface Chip" + default y + + + + +config FB_MXC_MTL017 + depends on FB_MXC_SYNC_PANEL + tristate "Myson MTL017 LVDS Controller" + default n + + config FB_MXC_CH7026 depends on FB_MXC_SYNC_PANEL tristate "Chrontel CH7026 VGA Interface Chip" diff --git a/drivers/video/mxc/Makefile b/drivers/video/mxc/Makefile index 170afd836ab..72991414c01 100644 --- a/drivers/video/mxc/Makefile +++ b/drivers/video/mxc/Makefile @@ -21,5 +21,7 @@ obj-$(CONFIG_FB_MXC_LDB) += ldb.o obj-$(CONFIG_FB_MXC_CH7026) += mxcfb_ch7026.o #obj-$(CONFIG_FB_MODE_HELPERS) += mxc_edid.o obj-$(CONFIG_FB_MXC_SII9022) += mxcfb_sii9022.o +obj-$(CONFIG_FB_MXC_CS8556) += mxcfb_cs8556.o +obj-$(CONFIG_FB_MXC_MTL017) += mxcfb_mtl017.o obj-$(CONFIG_FB_MXC_EINK_PANEL) += mxc_epdc_fb.o obj-$(CONFIG_FB_MXC_ELCDIF_FB) += mxc_elcdif_fb.o diff --git a/drivers/video/mxc/mxcfb_cs8556.c b/drivers/video/mxc/mxcfb_cs8556.c new file mode 100644 index 00000000000..7f007aff56b --- /dev/null +++ b/drivers/video/mxc/mxcfb_cs8556.c @@ -0,0 +1,565 @@ +/* + * Copyright 2009 Pegatron Corporation. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. + */ + +/*! + * @file mxcfb_cs8556.c + * + * @brief MXC Frame buffer driver for SDC + * + * @ingroup Framebuffer + */ + +/*! + * Include files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct i2c_client *cs8556_client; + +static int lcd_init(void); +static void lcd_poweron(struct fb_info *info); +static void lcd_poweroff(void); + +static void (*lcd_reset) (void); +static struct regulator *io_reg; +static struct regulator *core_reg; +static struct regulator *analog_reg; + +static struct fb_videomode mode = { + "1024x768", 60, 1024, 768, 16081, 160, 56, 20, 3, 104, 4, 2, FB_VMODE_NONINTERLACED +}; + +static void lcd_init_fb(struct fb_info *info) +{ + struct fb_var_screeninfo var; + + memset(&var, 0, sizeof(var)); + + fb_videomode_to_var(&var, &mode); + + var.activate = FB_ACTIVATE_ALL; + + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + fb_set_var(info, &var); + fb_blank(info, FB_BLANK_UNBLANK); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); +} + +static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v) +{ + struct fb_event *event = v; + + if (strcmp(event->info->fix.id, "DISP3 BG - DI1")) + return 0; + + switch (val) { + case FB_EVENT_FB_REGISTERED: + lcd_init_fb(event->info); + lcd_poweron(event->info); + break; + case FB_EVENT_BLANK: + if (*((int *)event->data) == FB_BLANK_UNBLANK) + lcd_poweron(event->info); + else + lcd_poweroff(); + break; + } + return 0; +} + +static struct notifier_block nb = { + .notifier_call = lcd_fb_event, +}; + +/*! + * This function is called whenever the SPI slave device is detected. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int __devinit lcd_probe(struct device *dev) +{ + int ret = 0; + int i; + struct mxc_lcd_platform_data *plat = dev->platform_data; + + if (plat) { + lcd_reset = plat->reset; + if (lcd_reset) + lcd_reset(); + } + + for (i = 0; i < num_registered_fb; i++) { + if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { + ret = lcd_init(); + if (ret < 0) + goto err; + + lcd_init_fb(registered_fb[i]); + fb_show_logo(registered_fb[i], 0); + lcd_poweron(registered_fb[i]); + } + } + + fb_register_client(&nb); + return 0; +err: + if (io_reg) + regulator_disable(io_reg); + if (core_reg) + regulator_disable(core_reg); + if (analog_reg) + regulator_disable(analog_reg); + + return ret; +} + +static int __devinit cs8556_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int id_reg; + cs8556_client = client; + + return lcd_probe(&client->dev); +} + +static int __devexit cs8556_remove(struct i2c_client *client) +{ + fb_unregister_client(&nb); + lcd_poweroff(); + regulator_put(io_reg); + regulator_put(core_reg); + regulator_put(analog_reg); + + return 0; +} + +static int cs8556_suspend(struct i2c_client *client, pm_message_t message) +{ + return 0; +} + +static int cs8556_resume(struct i2c_client *client) +{ + return 0; +} + +// Hungwen +u8 __devinitdata xga2xga_tbl1[] = { + // 0x00 - 0x0F + 0x00, + 0x0E, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + // 0x10 - 0x1F + 0x10, + //0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //RGB24 + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //RGB565 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x20 - 0x2F + 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x30 - 0x3F + 0x30, + 0x3F, 0x05, 0x67, 0x00, 0x08, 0x01, 0x08, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x40 - 0x4F + 0x40, + 0x1A, 0x03, 0x03, 0x00, 0x17, 0x00, 0x16, 0x03, + 0x00, 0x00, 0x9F, 0x00, 0x15, 0x00, 0x37, 0x00, + // 0x50 - 0x5F + 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x60 - 0x6F + 0x60, + 0x1F, 0x05, 0x20, 0x00, 0xC0, 0x00, 0xC0, 0x04, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x38, 0x03, + // 0x70 - 0x7F + 0x70, + 0x3D, 0x03, 0x0C, 0x00, 0x16, 0x00, 0x04, 0x03, + 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x80 - 0x8F + 0x80, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x90 - 0x9F + 0x90, + 0x04, 0x01, 0x11, 0x0D, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xA0 - 0xAF + 0xA0, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + // 0xB0 - 0xBF + 0xB0, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + // 0xC0 - 0xCF + 0xC0, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + // 0xD0 - 0xDF + 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xE0 - 0xEF + 0xE0, + //0x01, 0x06, 0x13, 0x00, 0x01, 0x02, 0x00, 0x00, + 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xF0 - 0xFF + 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +u8 __devinitdata xga2xga_tbl2[] = { + // 0x00 - 0x0F + 0x00, + 0x80, 0x10, 0x80, 0x00, 0x00, 0x00, 0x99, 0x11, + 0x2A, 0x00, 0x70, 0x30, 0x2A, 0x71, 0x9C, 0x00, + // 0x10 - 0x1F + 0x10, + 0x10, 0x2A, 0x85, 0x82, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + // 0x20 - 0x2F + 0x20, + 0x41, 0x09, 0x98, 0x08, 0xCC, 0x00, 0x4C, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, + // 0x30 - 0x3F + 0x30, + 0x00, 0x01, 0xEE, 0x02, 0x3A, 0x07, 0x65, 0x04, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x40 - 0x4F + 0x40, + 0x06, 0x40, 0x07, 0x30, 0x15, 0x10, 0x31, 0x02, + 0x33, 0x12, 0x34, 0x52, 0x38, 0x42, 0x39, 0x62, + // 0x50 - 0x5F + 0x50, + 0x48, 0x12, 0x64, 0x04, 0x66, 0x14, 0x00, 0x10, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, + // 0x60 - 0x6F + 0x60, + 0x7E, 0x10, 0x00, 0xF4, 0x10, 0x76, 0x08, 0x00, + 0x8A, 0x00, 0x8F, 0x11, 0x8F, 0x8F, 0x81, 0x00, + // 0x70 - 0x7F + 0x70, + 0x03, 0x00, 0x89, 0x45, 0x01, 0x45, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + // 0x80 - 0x8F + 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x90 - 0x9F + 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xA0 - 0xAF + 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xB0 - 0xBF + 0xB0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xC0 - 0xCF + 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xD0 - 0xDF + 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xE0 - 0xEF + 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xF0 - 0xFF + 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/*******************************************************************/ + +u8 __devinitdata wsvga2xga_tbl1[] = { + // 0x00 - 0x0F + 0x00, + 0x0E, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, + // 0x10 - 0x0F + 0x10, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x20 - 0x0F + 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x30 - 0x0F + 0x30, + 0x7B, 0x04, 0x10, 0x00, 0x54, 0x00, 0x54, 0x04, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + // 0x40 - 0x0F + 0x40, + 0x97, 0x02, 0x03, 0x00, 0x12, 0x00, 0x6A, 0x02, + 0x00, 0x00, 0x50, 0x00, 0x14, 0x00, 0x17, 0x00, + // 0x50 - 0x0F + 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x60 - 0x0F + 0x60, + 0x1F, 0x05, 0x20, 0x00, 0xC0, 0x00, 0xC0, 0x04, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x38, 0x03, + // 0x70 - 0x0F + 0x70, + 0x3D, 0x03, 0x0C, 0x00, 0x16, 0x00, 0x04, 0x03, + 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x80 - 0x0F + 0x80, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x90 - 0x0F + 0x90, + 0x04, 0x01, 0x11, 0x0D, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xA0 - 0x0F + 0xA0, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + // 0xB0 - 0x0F + 0xB0, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + // 0xC0 - 0x0F + 0xC0, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + // 0xD0 - 0x0F + 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xE0 - 0x0F + 0xE0, + 0x01, 0x06, 0x13, 0x00, 0x01, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xF0 - 0x0F + 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +u8 __devinitdata wsvga2xga_tbl2[] = { + // 0x00 - 0x0F + 0x00, + 0x80, 0x10, 0x80, 0x00, 0x00, 0x00, 0x99, 0x11, + 0x2A, 0x00, 0x70, 0x30, 0x2A, 0x71, 0x9C, 0x00, + // 0x10 - 0x0F + 0x10, + 0x10, 0x2A, 0x85, 0x82, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + // 0x20 - 0x0F + 0x20, + 0x41, 0x01, 0x98, 0x08, 0xCC, 0x00, 0x4C, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, + // 0x30 - 0x0F + 0x30, + 0x00, 0x01, 0xEE, 0x02, 0x3A, 0x07, 0x65, 0x04, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x40 - 0x0F + 0x40, + 0x06, 0x40, 0x07, 0x30, 0x15, 0x10, 0x31, 0x02, + 0x33, 0x12, 0x34, 0x52, 0x38, 0x42, 0x39, 0x62, + // 0x50 - 0x0F + 0x50, + 0x48, 0x12, 0x64, 0x04, 0x66, 0x14, 0x00, 0x10, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, + // 0x60 - 0x0F + 0x60, + 0x7E, 0x10, 0x00, 0xF4, 0x10, 0x76, 0x08, 0x00, + 0x8A, 0x00, 0x8F, 0x11, 0x8F, 0x8F, 0x81, 0x00, + // 0x70 - 0x0F + 0x70, + 0x03, 0x00, 0x89, 0x45, 0x01, 0x45, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + // 0x80 - 0x0F + 0x80, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x90 - 0x0F + 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xA0 - 0x0F + 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xB0 - 0x0F + 0xB0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xC0 - 0x0F + 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xD0 - 0x0F + 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xE0 - 0x0F + 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xF0 - 0x0F + 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +#define REGMAP_LENGTH (sizeof(reg_init) / (2*sizeof(u8))) +#define BLOCK_TX_SIZE (16+1) //Must small than 32 + +/* + * Send init commands to L4F00242T03 + * + */ +static int lcd_init(void) +{ + int i, j; + int dat; + u8 *tables[] = { xga2xga_tbl1, xga2xga_tbl2 }; + int tbl_len[] = { + sizeof(xga2xga_tbl1) / sizeof(u8), + sizeof(xga2xga_tbl2) / sizeof(u8) + }; + + dev_dbg(&cs8556_client->dev, "initializing CS8556AG\n"); + + /* read device ID */ + msleep(100); + dat = i2c_smbus_read_byte_data(cs8556_client, 0x00); + dev_dbg(&cs8556_client->dev, "read id = 0x%02X\n", dat); + //if (dat != 0x54) + // return -ENODEV; + + // Writing configuration table. + for (i = 0; i < 2; i++) { + for (j = 0; j < tbl_len[i]; j += BLOCK_TX_SIZE) { + if (i2c_smbus_write_i2c_block_data(cs8556_client, i, + BLOCK_TX_SIZE, &(tables[i][j]) ) < 0) { + printk("@_@ VGA controller init error!!\n"); + return -ENODEV; + } + } + } + + return 0; +} + +static int lcd_on; +/* + * Send Power On commands to L4F00242T03 + * + */ +static void lcd_poweron(struct fb_info *info) +{ + u16 data[4]; + u32 refresh; + + if (lcd_on) + return; + + dev_dbg(&cs8556_client->dev, "turning on LCD\n"); + + data[0] = PICOS2KHZ(info->var.pixclock) / 10; + data[2] = info->var.hsync_len + info->var.left_margin + + info->var.xres + info->var.right_margin; + data[3] = info->var.vsync_len + info->var.upper_margin + + info->var.yres + info->var.lower_margin; + + refresh = data[2] * data[3]; + refresh = (PICOS2KHZ(info->var.pixclock) * 1000) / refresh; + data[1] = refresh * 100; + + lcd_on = 1; +} + +/* + * Send Power Off commands to L4F00242T03 + * + */ +static void lcd_poweroff(void) +{ + if (!lcd_on) + return; + + dev_dbg(&cs8556_client->dev, "turning off LCD\n"); + + lcd_on = 0; +} + +static const struct i2c_device_id cs8556_id[] = { + {"cs8556", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, cs8556_id); + +static struct i2c_driver cs8556_driver = { + .driver = { + .name = "cs8556", + }, + .probe = cs8556_probe, + .remove = cs8556_remove, + .suspend = cs8556_suspend, + .resume = cs8556_resume, + .id_table = cs8556_id, +}; + +static int __init cs8556_init(void) +{ + return i2c_add_driver(&cs8556_driver); +} + +static void __exit cs8556_exit(void) +{ + i2c_del_driver(&cs8556_driver); +} + +module_init(cs8556_init); +module_exit(cs8556_exit); + +MODULE_AUTHOR("Pegatron Corporation"); +MODULE_DESCRIPTION("cs8556 VGA driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/mxc/mxcfb_mtl017.c b/drivers/video/mxc/mxcfb_mtl017.c new file mode 100644 index 00000000000..83ace3d6242 --- /dev/null +++ b/drivers/video/mxc/mxcfb_mtl017.c @@ -0,0 +1,950 @@ +/* + * Copyright 2009 Pegatron, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup Framebuffer Framebuffer Driver for Efikasb Platform. + */ + +/*! + * @file mxcfb_mtl017.c + * + * @brief MXC Frame buffer driver for Efikasb Platform + * + * @ingroup Framebuffer + */ + +/*! + * Include files + */ +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EDID_LENGTH 128 + +extern int register_backlight_notifier(struct notifier_block *nb); +extern int unregister_backlight_notifier(struct notifier_block *nb); + +#if 0 //vv +struct mtl017_dev_data { + struct i2c_client *client; + u8 edid[EDID_LENGTH]; + struct fb_videomode *mode; + u8 *regs; + int suspending; + int disp_on; + + struct semaphore sem; + + void (*reset)(void); + void (*power_on_lcd) (int); + void (*power_on_lvds) (int); + void (*turn_on_backlight) (int); + void (*lvds_enable) (int); +}; +#else +typedef struct mtl017_dev_data_tag { + struct i2c_client *client; + u8 edid[EDID_LENGTH]; + struct fb_videomode *mode; + u8 *regs; + int suspending; + int disp_on; + + struct semaphore sem; + + void (*reset)(void); + void (*power_on_lcd) (int); + void (*power_on_lvds) (int); + void (*turn_on_backlight) (int); + void (*lvds_enable) (int); +} mtl017_dev_data; +#endif + +//vv static struct mtl017_dev_data *mtl017 = NULL; +static mtl017_dev_data * mtl017 = NULL; //vv +static void mtl017_conf(u8 *reg_tbl); +static void disp_power_on(void); +static void disp_power_off(void); + +static void disp_on_work_handler(struct work_struct *work); +static void disp_off_work_handler(struct work_struct *work); + +static void disp_on_work_handler(struct work_struct *work) +{ + disp_power_on(); +} + +static void disp_off_work_handler(struct work_struct *work) +{ + disp_power_off(); +} + +static DECLARE_WORK(disp_off_work, disp_off_work_handler); +static DECLARE_WORK(disp_on_work, disp_on_work_handler); + +#ifdef DEBUG_MTL017 +static void dump_edid(unsigned char *id) +{ + int i; + + printk("EDID Dump:\n"); + for (i=0; i < EDID_LENGTH; i++) { + printk("[%x]=%x\n", i, id[i]); + } + + printk("\n"); +} + +static void dump_screeninfo(struct fb_var_screeninfo *einfo) +{ + printk("resolution: r(%d, %d), v(%d, %d) o(%d, %d)\n", + einfo->xres, + einfo->yres, + einfo->xres_virtual, + einfo->yres_virtual, + einfo->xoffset, + einfo->yoffset); + printk("bpp=%d, hw(%d, %d), pclk=%d\n", + einfo->bits_per_pixel, + einfo->height, + einfo->width, + einfo->pixclock); + + printk("margin(%d, %d, %d, %d)\n", + einfo->left_margin, + einfo->right_margin, + einfo->upper_margin, + einfo->lower_margin); + + printk("hv(%d, %d), sync=%x, vmode=%x\n", + einfo->hsync_len, + einfo->vsync_len, + einfo->sync, + einfo->vmode); + +} +#else +static void dump_edid(unsigned char *edid) {} +static void dump_screeninfo(struct fb_var_screeninfo *einfo) {} +#endif + +static u8 mtl017_auo_tbl[] = { + /* ron: 66M to 66M */ +/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */ +/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */ +/* 0x00,0x21,0x01,0x08,0x00,0x1E,0x01,0x05, */ +/* 0x00,0x01,0x7C,0x04,0x32,0x00,0x00,0x04, */ +/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */ +/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */ +/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */ +/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */ +/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */ +/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */ +/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */ +/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */ +/* 0x00,0x00,0x06,0x01,0x02,0x00,0x10,0x04, */ +/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */ +/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */ +/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */ +/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ + + /* ron: 44MHz to 54MHz */ +/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */ +/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */ +/* 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, */ +/* 0x00,0x01,0x82,0x05,0x32,0x00,0x00,0x04, */ +/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */ +/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */ +/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */ +/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */ +/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */ +/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */ +/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */ +/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */ +/* 0x00,0x04,0x2A,0x01,0x02,0x00,0x10,0x04, */ +/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */ +/* 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, */ +/* 0x02,0x7C,0x04,0x7E,0x02,0x11,0x78,0x18, */ +/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ + + + /* ron: 44MHz to 48MHz */ +/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */ +/* 0x00,0x04,0x16,0x00,0x59,0x02,0x00,0x00, */ +/* 0x00,0x21,0x00,0x09,0x00,0x1E,0x01,0x05, */ +/* 0x00,0x01,0xEA,0x04,0x32,0x00,0x00,0x04, */ +/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */ +/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */ +/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */ +/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */ +/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */ +/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */ +/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */ +/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */ +/* 0x00,0x02,0x16,0x01,0x02,0x00,0x10,0x04, */ +/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */ +/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */ +/* 0x02,0x7C,0x04,0x7E,0x02,0x11,0x78,0x18, */ +/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ + + /* ron: 44M to 53.8M */ +/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */ +/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */ +/* 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, */ +/* 0x00,0x01,0x7E,0x05,0x32,0x00,0x00,0x04, */ +/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */ +/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */ +/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */ +/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */ +/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */ +/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */ +/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */ +/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */ +/* 0x00,0x06,0x3B,0x01,0x02,0x00,0x10,0x04, */ +/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */ +/* 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, */ +/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */ +/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ + + /* ron: 44M to 53.9M */ + 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, + 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, + 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, + 0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04, + 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, + 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, + 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, + 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, + 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, + 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, + 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, + 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, + 0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04, + 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, + 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, + 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, + 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + +}; + +static u8 mtl017_cpt_tbl[] = { +/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */ +/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */ +/* 0x00,0x21,0x01,0x08,0x00,0x1E,0x01,0x05, */ +/* 0x00,0x01,0x7C,0x04,0x32,0x00,0x00,0x04, */ +/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */ +/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */ +/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */ +/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */ +/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */ +/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */ +/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */ +/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */ +/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */ +/* 0x00,0x00,0x06,0x01,0x02,0x00,0x10,0x04, */ +/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */ +/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */ +/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */ +/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ +/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */ + + /* ron: 44M to 53.9M */ + 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, + 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, + 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, + 0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04, + 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, + 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, + 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, + 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, + 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, + 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, + 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, + 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, + 0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04, + 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, + 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, + 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, + 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +}; + +static u8 mtl017_auo_hires_tbl[] = { + 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x3D,0x00, + 0x00,0x05,0x0C,0x00,0xD0,0x02,0x00,0x00, + 0x00,0x05,0x00,0x02,0x00,0x02,0x00,0x0A, + 0x00,0x01,0x70,0x05,0x3D,0x00,0x00,0x05, + 0x00,0x00,0x20,0xF0,0x02,0x0C,0x00,0xD0, + 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, + 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, + 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, + 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, + 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, + 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, + 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, + 0x00,0x00,0x06,0x01,0x02,0x00,0x12,0x04, + 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, + 0x3D,0x00,0x00,0x05,0x0C,0x00,0xD0,0x02, + 0x02,0x70,0x05,0xE0,0x02,0x11,0x78,0x18, + 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +}; + +static u8 mtl017_cmo_tbl[] = { + /* ron: 44M to 53.9M */ + 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, + 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, + 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, + 0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04, + 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, + 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, + 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, + 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, + 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, + 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, + 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, + 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, + 0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04, + 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, + 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, + 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, + 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +}; + +#define REGMAP_LENGTH ( sizeof(mtl017_auo_tbl) / sizeof(u8) ) +#define BLOCK_TX_SIZE 32 + +static int mtl017_read_edid(struct i2c_adapter *adp, unsigned char *edid) +{ + u8 buf0[2] = {0, 0}; + int dat = 0; + u16 addr = 0x50; + struct i2c_msg msg[2] = { + { + .addr = addr, + .flags = 0, + .len = 1, + .buf = buf0, + }, { + .addr = addr, + .flags = I2C_M_RD, + .len = EDID_LENGTH, + .buf = edid, + }, + }; + + if (adp == NULL) + return -EINVAL; + + buf0[0] = 0x00; + memset(edid, 0, EDID_LENGTH); + dat = i2c_transfer(adp, msg, 2); + if (dat <= 0) + return -ENODEV; + + if (edid[1] == 0x00) + return -ENOENT; + + return 0; +} + +/* ron: for AUO B101AW02 1024x600 LCD Panel */ +static struct fb_videomode auo_mode = { + .name = "AUO B101AW02 1024x600", + .refresh = 60, + .xres = 1024, + .yres = 600, +/* .pixclock = 16666, */ /* ron: 66MHz display clock*/ + .pixclock = 22800, /* ron: 44MHz display clock*/ + .left_margin = 80, + .right_margin = 40, + .upper_margin = 20, + .lower_margin = 21, + .hsync_len = 4, + .vsync_len = 4, + .sync = FB_SYNC_OE_LOW_ACT, + .vmode = FB_VMODE_NONINTERLACED, +}; + +/* ron: for AUO B101EW01 1280x720 LCD Panel */ +static struct fb_videomode auo_hires_mode = { + .name = "AUO B101EW01 1280x720", + .refresh = 60, + .xres = 1280, + .yres = 720, + .pixclock = 16260, + .left_margin = 32, + .right_margin = 48, + .upper_margin = 7, + .lower_margin = 3, + .hsync_len = 32, + .vsync_len = 6, + .sync = FB_SYNC_OE_LOW_ACT, + .vmode = FB_VMODE_NONINTERLACED, +}; + +/* ron: for CPT CLAA101NB03A 1024x600 LCD Panel */ +static struct fb_videomode cpt_mode = { + .name = "CPT CLAA101 1024x600", + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = 22800, /* ron: 44M display clock */ + .left_margin = 80, + .right_margin = 40, + .upper_margin = 20, + .lower_margin = 21, + .hsync_len = 4, + .vsync_len = 4, + .sync = FB_SYNC_OE_LOW_ACT, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_videomode cmo_mode = { + .name = "CMO N101L6-L0D 1024x600", + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = 22800, /* ron: 44MHz display clock*/ + .left_margin = 80, + .right_margin = 40, + .upper_margin = 20, + .lower_margin = 21, + .hsync_len = 4, + .vsync_len = 4, + .sync = FB_SYNC_OE_LOW_ACT, + .vmode = FB_VMODE_NONINTERLACED, +}; + +struct lcd_panel_info { + char manufacture[16]; + char product_name[16]; + struct fb_videomode *mode; + u8 *regs; +}; + +static struct lcd_panel_info pinfo[] = { + { + .manufacture = "AUO", + .product_name = "B101AW02 V0", + .mode = &auo_mode, + .regs = mtl017_auo_tbl, + }, + { + .manufacture = "CPT", + .product_name = "CLAA101NB03A", + .mode = &cpt_mode, + .regs = mtl017_cpt_tbl, + }, + { + .manufacture = "AUO", + .product_name = "B101EW01", + .mode = &auo_hires_mode, + .regs = mtl017_auo_hires_tbl, + }, + { + .manufacture = "CMO", + .product_name = "N101L6-L0D", + .mode = &cmo_mode, + .regs = mtl017_cmo_tbl, + } +}; + +//vv static void mtl017_find_videomode(struct mtl017_dev_data *mtl017) +static void mtl017_find_videomode(mtl017_dev_data *mtl017) +{ + int i; + struct i2c_adapter *adp; + struct fb_var_screeninfo var; + int err; + + adp = i2c_get_adapter(1); + err = mtl017_read_edid(adp, mtl017->edid); + + dump_edid(mtl017->edid); + /* ron: use edid to parse screeninfo, + but these parameters have some problem */ + memset(&var, 0, sizeof(var)); + fb_parse_edid(mtl017->edid, &var); + dump_screeninfo(&var); + + for (i = 0; i < ARRAY_SIZE(pinfo); i ++) { + if(/* (memcmp(mtl017->edid + 0x5f, pinfo[i].manufacture, strlen(pinfo[i].manufacture)) == 0) && */ + (memcmp(mtl017->edid + 0x71, pinfo[i].product_name, strlen(pinfo[i].product_name)) == 0)) { + printk("mtl017: Probe LCD Panel: %s %s\n", + pinfo[i].manufacture, + pinfo[i].product_name); + mtl017->mode = pinfo[i].mode; + mtl017->regs = pinfo[i].regs; + + return; + } + } + + mtl017->regs = NULL; + mtl017->mode = NULL; + +} + +static void lcd_init_fb(struct fb_info *info) +{ + struct fb_var_screeninfo var; + + memset(&var, 0, sizeof(var)); + + fb_videomode_to_var(&var, mtl017->mode); + var.activate = FB_ACTIVATE_ALL; + + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + fb_set_var(info, &var); + fb_blank(info, FB_BLANK_UNBLANK); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); + + +} + +static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v) +{ + struct fb_event *event = v; + + if (strcmp(event->info->fix.id, "DISP3 BG - DI1")) { + return 0; + } + + switch (val) { + case FB_EVENT_FB_REGISTERED: + lcd_init_fb(event->info); + break; + case FB_EVENT_BLANK: + if (*((int *)event->data) == FB_BLANK_UNBLANK) { + disp_power_on(); + } else { + disp_power_off(); + } + break; + } + return 0; +} + +#define BL_BRIGHTNESS 0x01 + +static int lcd_bl_event(struct notifier_block *nb, unsigned long val, void *v) +{ + int brightness = v; + + switch (val) { + case BL_BRIGHTNESS: + if(brightness == 0) { + disp_power_off(); + } else { + disp_power_on(); + } + break; + + } + + return 0; +} + +static struct notifier_block fb_nb = { + .notifier_call = lcd_fb_event, +}; + +static struct notifier_block bl_nb = { + .notifier_call = lcd_bl_event, +}; + +/*! + * This function is called whenever the SPI slave device is detected. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ + +static int __devinit mtl017_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct mxc_lcd_platform_data *plat = client->dev.platform_data; + int retval; + int i; + +//vv mtl017 = kzalloc(sizeof(*mtl017), GFP_KERNEL); + mtl017 = (mtl017_dev_data*)kzalloc(sizeof(*mtl017), GFP_KERNEL); + + if(!mtl017) { + dev_err(&client->dev, "failed to allocate mtl017 device\n"); + retval = -ENOMEM; + return retval; + } + + mtl017->suspending = 0; + mtl017->client = client; + if(plat) { + mtl017->reset = + plat->reset; + mtl017->power_on_lcd = + plat->power_on_lcd; + mtl017->power_on_lvds = + plat->power_on_lvds; + mtl017->turn_on_backlight = + plat->turn_on_backlight; + mtl017->lvds_enable = + plat->lvds_enable; + } + +/* mtl017->lock = SPIN_LOCK_UNLOCKED; */ + sema_init(&mtl017->sem, 1); + + mtl017_find_videomode(mtl017); + if(mtl017->mode == NULL) + mtl017->mode = &auo_mode; + if(mtl017->regs == NULL) + mtl017->regs = mtl017_auo_tbl; + + for (i = 0; i < num_registered_fb; i++) { + if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { + lcd_init_fb(registered_fb[i]); + fb_show_logo(registered_fb[i], 0); + } + } + + fb_register_client(&fb_nb); + register_backlight_notifier(&bl_nb); + + /* disp_power_on(); */ + schedule_work(&disp_on_work); + + return 0; + +} + +static int __devexit mtl017_remove(struct i2c_client *client) +{ + unregister_backlight_notifier(&bl_nb); + fb_unregister_client(&fb_nb); + disp_power_off(); + + kfree(mtl017); + + return 0; +} + +static int mtl017_suspend(struct i2c_client *client, pm_message_t message) +{ + mtl017->suspending = 1; + disp_power_off(); + + return 0; +} + +static int mtl017_resume(struct i2c_client *client) +{ + /* ron: because we turn off regulator, */ + /* so re-initialize MTL017 controller after suspending */ + mtl017->suspending = 0; + disp_power_on(); + + return 0; +} + +static void mtl017_conf(u8 *reg_tbl) +{ + int i; + int ret; + int retry = 5; + + dev_dbg(&mtl017->client->dev, "Initializing MTL017 LVDS Controller\n"); + + // Writing configuration table. + for (i = 0; i < REGMAP_LENGTH; i+=BLOCK_TX_SIZE) { + retry: + msleep(1); + ret = i2c_smbus_write_i2c_block_data(mtl017->client, i, BLOCK_TX_SIZE, &(reg_tbl[i])); + if (ret < 0) { + printk(KERN_WARNING "MTL017 LVDS Controller Initialize Fail!\n"); + if(retry -- > 0) + goto retry; + return; + } + + } + +} +static void disp_power_on(void) +{ + if(mtl017->disp_on || mtl017->suspending) + return; + + down_interruptible(&mtl017->sem); + + if(mtl017->mode == &auo_mode) { + + + if(mtl017->power_on_lcd) + mtl017->power_on_lcd(1); + + msleep(10); + + if(mtl017->lvds_enable) + mtl017->lvds_enable(1); + + msleep(5); + + if(mtl017->power_on_lvds) + mtl017->power_on_lvds(1); + + msleep(5); + + mtl017_conf(mtl017->regs); + + msleep(200); + + if(mtl017->turn_on_backlight) + mtl017->turn_on_backlight(1); + } else { + if(mtl017->lvds_enable) + mtl017->lvds_enable(-1); + + if(mtl017->power_on_lcd) + mtl017->power_on_lcd(1); + + if(mtl017->power_on_lvds) + mtl017->power_on_lvds(1); + + mtl017_conf(mtl017->regs); + + msleep(200); + + if(mtl017->turn_on_backlight) + mtl017->turn_on_backlight(1); + } + + mtl017->disp_on = 1; + + up(&mtl017->sem); +} + +static void disp_power_off(void) +{ + if(mtl017->disp_on == 0) + return; + + down_interruptible(&mtl017->sem); + + if(mtl017->turn_on_backlight) + mtl017->turn_on_backlight(0); + + msleep(200); + + if(mtl017->mode == &auo_mode) { + if(mtl017->lvds_enable) + mtl017->lvds_enable(0); + } + + if(mtl017->power_on_lvds) + mtl017->power_on_lvds(0); + + msleep(5); + + if(mtl017->power_on_lcd) + mtl017->power_on_lcd(0); + + + mtl017->disp_on = 0; + + up(&mtl017->sem); + +} + +static const struct i2c_device_id mtl017_id[] = { + { "mtl017", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, mtl017_id); + +static struct i2c_driver mtl017_driver = { + .driver = { + .name = "mtl017", + }, + .probe = mtl017_probe, + .remove = mtl017_remove, + .suspend = mtl017_suspend, + .resume = mtl017_resume, + .id_table = mtl017_id, +}; + +static int __init mtl017_init(void) +{ + return i2c_add_driver(&mtl017_driver); +} + +static void __exit mtl017_exit(void) +{ + i2c_del_driver(&mtl017_driver); +} + +module_init(mtl017_init); +module_exit(mtl017_exit); + +MODULE_AUTHOR("Ron Lee Pegatron Corp."); +MODULE_DESCRIPTION("MTL017 LVDS Controller driver"); +MODULE_LICENSE("GPL"); +