From 7902882ebb9fa52fa32d96a7b60e35a5415f3c1c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=94=A1=E6=9E=AB?= Date: Fri, 24 Jun 2011 22:39:48 +0800 Subject: [PATCH] add support for newton board --- arch/arm/configs/rk29_newton_defconfig | 2144 ++++++++++++++++++ arch/arm/mach-rk29/board-rk29-newton.c | 1838 +++++++++++++++ arch/arm/mach-rk29/include/mach/board.h | 8 + drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/ft5406_ts.c | 1039 +++++++++ drivers/input/touchscreen/ft5406_ts.h | 41 + drivers/rtc/Kconfig | 7 + drivers/rtc/Makefile | 2 + drivers/rtc/rtc-m41t66.c | 813 +++++++ drivers/video/display/screen/Kconfig | 2 + drivers/video/display/screen/Makefile | 1 + drivers/video/display/screen/lcd_at070tn93.c | 76 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/cs42l52.c | 1400 ++++++++++++ sound/soc/codecs/cs42l52.h | 323 +++ sound/soc/rk29/Kconfig | 11 +- sound/soc/rk29/Makefile | 2 + sound/soc/rk29/rk29_cs42l52.c | 218 ++ 20 files changed, 7940 insertions(+), 1 deletion(-) create mode 100644 arch/arm/configs/rk29_newton_defconfig create mode 100755 arch/arm/mach-rk29/board-rk29-newton.c create mode 100755 drivers/input/touchscreen/ft5406_ts.c create mode 100755 drivers/input/touchscreen/ft5406_ts.h create mode 100755 drivers/rtc/rtc-m41t66.c create mode 100755 drivers/video/display/screen/lcd_at070tn93.c create mode 100755 sound/soc/codecs/cs42l52.c create mode 100755 sound/soc/codecs/cs42l52.h create mode 100755 sound/soc/rk29/rk29_cs42l52.c diff --git a/arch/arm/configs/rk29_newton_defconfig b/arch/arm/configs/rk29_newton_defconfig new file mode 100644 index 000000000000..ef33ff53ffab --- /dev/null +++ b/arch/arm/configs/rk29_newton_defconfig @@ -0,0 +1,2144 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32.27 +# Fri Jun 24 22:35:28 2011 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_SCHED_CLOCK=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +# CONFIG_CGROUP_NS is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +# CONFIG_CGROUP_MEM_RES_CTLR is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_ASHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_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 is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +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_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_RK2818 is not set +CONFIG_ARCH_RK29=y +CONFIG_WIFI_CONTROL_FUNC=y +# CONFIG_MACH_RK29SDK is not set +CONFIG_MACH_RK29SDK_DDR3=y +# CONFIG_MACH_RK29WINACCORD is not set +# CONFIG_MACH_RK29FIH is not set +# CONFIG_MACH_RK29_MALATA is not set +# CONFIG_MACH_RK29_PHONESDK is not set +# CONFIG_MACH_RK29_A22 is not set +# CONFIG_MACH_RK29_PHONEPADSDK is not set +# CONFIG_DDR_TYPE_DDRII is not set +# CONFIG_DDR_TYPE_LPDDR is not set +# CONFIG_DDR_TYPE_DDR3_800D is not set +# CONFIG_DDR_TYPE_DDR3_800E is not set +# CONFIG_DDR_TYPE_DDR3_1066E is not set +# CONFIG_DDR_TYPE_DDR3_1066F is not set +# CONFIG_DDR_TYPE_DDR3_1066G is not set +# CONFIG_DDR_TYPE_DDR3_1333F is not set +# CONFIG_DDR_TYPE_DDR3_1333G is not set +# CONFIG_DDR_TYPE_DDR3_1333H is not set +# CONFIG_DDR_TYPE_DDR3_1333J is not set +# CONFIG_DDR_TYPE_DDR3_1600G is not set +# CONFIG_DDR_TYPE_DDR3_1600H is not set +# CONFIG_DDR_TYPE_DDR3_1600J is not set +# CONFIG_DDR_TYPE_DDR3_1600K is not set +# CONFIG_DDR_TYPE_DDR3_1866J is not set +# CONFIG_DDR_TYPE_DDR3_1866K is not set +# CONFIG_DDR_TYPE_DDR3_1866L is not set +# CONFIG_DDR_TYPE_DDR3_1866M is not set +# CONFIG_DDR_TYPE_DDR3_2133K is not set +# CONFIG_DDR_TYPE_DDR3_2133L is not set +# CONFIG_DDR_TYPE_DDR3_2133M is not set +# CONFIG_DDR_TYPE_DDR3_2133N is not set +CONFIG_DDR_TYPE_DDR3_DEFAULT=y +CONFIG_RK29_MEM_SIZE_M=512 +CONFIG_DDR_SDRAM_FREQ=400 + +# +# RK29 VPU (Video Processing Unit) support +# +CONFIG_RK29_VPU=y +# CONFIG_RK29_VPU_DEBUG is not set +CONFIG_RK29_JTAG=y +CONFIG_RK29_LAST_LOG=y + +# +# The control interface support for RK29 suspend +# +CONFIG_RK29_PWM_INSRAM=y + +# +# 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_V7=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=y +CONFIG_ARM_THUMBEE=y +# 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_L1_CACHE_SHIFT=6 +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_ARM_GIC=y +CONFIG_PL330=y +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +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=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +CONFIG_KEXEC=y +CONFIG_ATAGS_PROC=y + +# +# 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 is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=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_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_HAS_WAKELOCK=y +CONFIG_HAS_EARLYSUSPEND=y +CONFIG_WAKELOCK=y +CONFIG_WAKELOCK_STAT=y +CONFIG_USER_WAKELOCK=y +CONFIG_EARLYSUSPEND=y +# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set +# CONFIG_CONSOLE_EARLYSUSPEND is not set +CONFIG_FB_EARLYSUSPEND=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=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=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_ANDROID_PARANOID_NETWORK=y +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_BNEP is not set +# CONFIG_BT_HIDP is not set + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +CONFIG_BT_HCIBCM4325=y +CONFIG_IDBLOCK=y +# CONFIG_WIFI_MAC is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# + +# +# Some wireless drivers require a rate control algorithm +# +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_PM is not set +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND is not set +CONFIG_MTD_RKNAND=y +CONFIG_MTD_NAND_RK29XX=y +CONFIG_RKFTL_PAGECACHE_SIZE=64 +CONFIG_MTD_RKNAND_BUFFER=y +# CONFIG_MTD_NAND_RK29XX_DEBUG 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_ANDROID_PMEM=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_KERNEL_DEBUGGER_CORE is not set +# CONFIG_ISL29003 is not set +CONFIG_UID_STAT=y +# CONFIG_WL127X_RFKILL is not set +CONFIG_APANIC=y +CONFIG_APANIC_PLABEL="kpanic" +# CONFIG_STE is not set +# CONFIG_MTK23D is not set +# CONFIG_FM580X is not set +# CONFIG_MU509 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_RK29_SUPPORT_MODEM=y +CONFIG_MODEM_ROCKCHIP_DEMO=y +# CONFIG_RK29_GPS is not set + +# +# Motion Sensors Support +# +# CONFIG_MPU_NONE is not set +# CONFIG_SENSORS_MPU3050 is not set +# CONFIG_SENSORS_MPU6000 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 is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_RK29_VMAC=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +CONFIG_WLAN_80211=y +# CONFIG_WIFI_NONE is not set +CONFIG_BCM4329=y +# CONFIG_MV8686 is not set +# CONFIG_BCM4319 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO 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 is not set +# CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set +# CONFIG_PPPOLAC is not set +# CONFIG_PPPOPNS is not set +# 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 +# CONFIG_PHONE 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 is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_KEYRESET=y + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYS_RK29=y +# CONFIG_SYNAPTICS_SO340010 is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_WM831X_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ILI2102_IIC is not set +# CONFIG_TOUCHSCREEN_IT7250 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_HANNSTAR_P1003 is not set +# CONFIG_ATMEL_MXT224 is not set +# CONFIG_SINTEK_3FA16 is not set +# CONFIG_EETI_EGALAX is not set +# CONFIG_TOUCHSCREEN_IT7260 is not set +# CONFIG_TOUCHSCREEN_GT801_IIC is not set +# CONFIG_TOUCHSCREEN_GT818_IIC is not set +# CONFIG_D70_L3188A is not set +CONFIG_TOUCHSCREEN_FT5406=y +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_LPSENSOR_ISL29028 is not set +# CONFIG_INPUT_LPSENSOR_CM3602 is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_MAG_SENSORS is not set +CONFIG_G_SENSOR_DEVICE=y +# CONFIG_GS_MMA7660 is not set +CONFIG_GS_MMA8452=y +# CONFIG_GS_L3G4200D is not set +# CONFIG_INPUT_JOGBALL is not set +# CONFIG_LIGHT_SENSOR_DEVICE is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_CONSOLE_TRANSLATIONS is not set +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVMEM=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_RK29=y +CONFIG_UART0_RK29=y +CONFIG_UART0_CTS_RTS_RK29=y +CONFIG_UART1_RK29=y +CONFIG_UART2_RK29=y +CONFIG_UART2_CTS_RTS_RK29=y +# CONFIG_UART3_RK29 is not set +CONFIG_SERIAL_RK29_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# +CONFIG_I2C_RK29=y + +# +# Now, there are four I2C interfaces selected by developer. +# +CONFIG_I2C0_RK29=y +CONFIG_RK29_I2C0_CONTROLLER=y +# CONFIG_RK29_I2C0_GPIO is not set +CONFIG_I2C1_RK29=y +CONFIG_RK29_I2C1_CONTROLLER=y +# CONFIG_RK29_I2C1_GPIO is not set +CONFIG_I2C2_RK29=y +CONFIG_RK29_I2C2_CONTROLLER=y +# CONFIG_RK29_I2C2_GPIO is not set +CONFIG_I2C3_RK29=y +CONFIG_RK29_I2C3_CONTROLLER=y +# CONFIG_RK29_I2C3_GPIO is not set +CONFIG_I2C_DEV_RK29=y + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_PCA963X is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +CONFIG_ADC=y +# CONFIG_ADC_RK28 is not set +CONFIG_ADC_RK29=y +# CONFIG_SPI_FPGA is not set + +# +# Headset device support +# +CONFIG_RK_HEADSET_DET=y + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# 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: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_GPIO_PCA9554 is not set +# CONFIG_IOEXTEND_TCA6424 is not set +CONFIG_EXPANDED_GPIO_NUM=0 +CONFIG_EXPANDED_GPIO_IRQ_NUM=0 +# CONFIG_EXPAND_GPIO_SOFT_INTERRUPT is not set +CONFIG_SPI_FPGA_GPIO_NUM=96 +CONFIG_SPI_FPGA_GPIO_IRQ_NUM=16 +# 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_STC3100 is not set +CONFIG_BATTERY_BQ27510=y +# CONFIG_BATTERY_BQ3060 is not set +# CONFIG_CHECK_BATT_CAPACITY is not set +CONFIG_NO_BATTERY_IC=y +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TPS65910_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE 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_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_RK2818_REGULATOR_CHARGE is not set +# CONFIG_RK2818_REGULATOR_LP8725 is not set +CONFIG_RK29_PWM_REGULATOR=y +CONFIG_MEDIA_SUPPORT=y + +# +# 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_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF_DMA_CONTIG=y +# CONFIG_VIDEO_RK29XX_VOUT is not set +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_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=y +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9M112 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T111 is not set +# CONFIG_SOC_CAMERA_MT9P111 is not set +# CONFIG_SOC_CAMERA_MT9D112 is not set +# CONFIG_SOC_CAMERA_MT9D113 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set +# CONFIG_SOC_CAMERA_PLATFORM is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV7675 is not set +# CONFIG_SOC_CAMERA_OV2655 is not set +CONFIG_SOC_CAMERA_OV2659=y +# CONFIG_SOC_CAMERA_OV9650 is not set +# CONFIG_SOC_CAMERA_OV2640 is not set +# CONFIG_SOC_CAMERA_OV3640 is not set +CONFIG_SOC_CAMERA_OV5642=y +CONFIG_OV5642_AUTOFOCUS=y +# CONFIG_OV5642_FIXEDFOCUS is not set +# CONFIG_SOC_CAMERA_OV5640 is not set +# CONFIG_SOC_CAMERA_S5K6AA is not set +# CONFIG_SOC_CAMERA_GT2005 is not set +# CONFIG_SOC_CAMERA_GC0308 is not set +# CONFIG_SOC_CAMERA_GC0309 is not set +# CONFIG_SOC_CAMERA_GC2015 is not set +# CONFIG_SOC_CAMERA_HI253 is not set +# CONFIG_SOC_CAMERA_HI704 is not set +# CONFIG_SOC_CAMERA_SIV120B is not set +# CONFIG_SOC_CAMERA_SID130B is not set +# CONFIG_SOC_CAMERA_NT99250 is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_VIDEO_RK29=y +CONFIG_VIDEO_RK29_WORK_ONEFRAME=y +# CONFIG_VIDEO_RK29_WORK_PINGPONG is not set +CONFIG_VIDEO_RK29_WORK_IPP=y +# CONFIG_VIDEO_RK29_WORK_NOT_IPP is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +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_GL860 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_JEILINJ 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=y +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_RADIO_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_SMS_SIANO_MDTV 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 is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_RK2818 is not set +CONFIG_FB_RK29=y +CONFIG_FB_WORK_IPP=y +# CONFIG_FB_SCALING_OSD is not set +# CONFIG_FB_ROTATE_VIDEO 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_RK29_BL=y +# CONFIG_FIH_TOUCHKEY_LED is not set +# CONFIG_BACKLIGHT_AW9364 is not set +# CONFIG_BUTTON_LIGHT is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# +# CONFIG_LCD_NULL is not set +# CONFIG_LCD_TD043MGEA1 is not set +# CONFIG_LCD_HX8357 is not set +# CONFIG_LCD_TJ048NC01CA is not set +# CONFIG_LCD_HL070VM4AU is not set +# CONFIG_LCD_HSD070IDW1 is not set +# CONFIG_LCD_RGB_TFT480800_25_E is not set +# CONFIG_LCD_HSD100PXN is not set +# CONFIG_LCD_HSD07PFW1 is not set +# CONFIG_LCD_B101AW06 is not set +# CONFIG_LCD_LS035Y8DX02A is not set +# CONFIG_LCD_CPTCLAA038LA31XE is not set +# CONFIG_LCD_A060SE02 is not set +# CONFIG_LCD_S1D13521 is not set +# CONFIG_LCD_NT35582 is not set +# CONFIG_LCD_NT35580 is not set +# CONFIG_LCD_IPS1P5680_V1_E is not set +# CONFIG_LCD_MCU_TFT480800_25_E is not set +# CONFIG_LCD_NT35510 is not set +# CONFIG_LCD_ILI9803_CPT4_3 is not set +# CONFIG_DEFAULT_OUT_HDMI is not set +# CONFIG_LCD_AT070TNA2 is not set +CONFIG_LCD_AT070TN93=y + +# +# HDMI +# +# CONFIG_HDMI is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE 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_LOGO_CHARGER_CLUT224 is not set +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 is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y +CONFIG_SND_RK29_SOC=y +CONFIG_SND_RK29_SOC_I2S=y +# CONFIG_SND_RK29_SOC_I2S_2CH is not set +CONFIG_SND_RK29_SOC_I2S_8CH=y +# CONFIG_SND_RK29_SOC_WM8988 is not set +# CONFIG_SND_RK29_SOC_WM8900 is not set +# CONFIG_SND_RK29_SOC_alc5621 is not set +# CONFIG_SND_RK29_SOC_alc5631 is not set +# CONFIG_SND_RK29_SOC_RT5625 is not set +# CONFIG_SND_RK29_SOC_WM8994 is not set +CONFIG_SND_RK29_SOC_CS42L52=y +# CONFIG_SND_RK29_CODEC_SOC_MASTER is not set +CONFIG_SND_RK29_CODEC_SOC_SLAVE=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_CS42L52=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_OTG_BLACKLIST_HUB=y +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# 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=y +# 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_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=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +CONFIG_USB_GADGET_DWC_OTG=y +CONFIG_USB_DWC_OTG=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_ANDROID=y +# CONFIG_USB_ANDROID_ACM is not set +CONFIG_USB_ANDROID_ADB=y +CONFIG_USB_ANDROID_MASS_STORAGE=y +# CONFIG_USB_ANDROID_RNDIS is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB11_HOST=y +CONFIG_USB11_HOST_EN=y +CONFIG_USB20_HOST=y +CONFIG_USB20_HOST_EN=y +CONFIG_USB20_OTG=y +# CONFIG_DWC_OTG_HOST_ONLY is not set +CONFIG_DWC_OTG_DEVICE_ONLY=y +# CONFIG_DWC_OTG_BOTH_HOST_SLAVE is not set +CONFIG_DWC_CONN_EN=y +# CONFIG_DWC_OTG_DEBUG is not set +CONFIG_DWC_OTG=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_EMBEDDED_SDIO=y +# CONFIG_MMC_PARANOID_SD_INIT is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_SDMMC_RK29=y + +# +# Now, there are two SDMMC controllers selected, SDMMC0 and SDMMC1. +# +CONFIG_SDMMC0_RK29=y +# CONFIG_EMMC_RK29 is not set +CONFIG_SDMMC1_RK29=y +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +CONFIG_SWITCH=y +CONFIG_SWITCH_GPIO=y +# CONFIG_ACCESSIBILITY 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 is not set +CONFIG_RTC_INTF_ALARM=y +CONFIG_RTC_INTF_ALARM_DEV=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_HYM8563 is not set +CONFIG_RTC_DRV_M41T66=y +# 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_S35392A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_TRANZPORT is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=y +CONFIG_ANDROID_RAM_CONSOLE=y +CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d +# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set +CONFIG_ANDROID_TIMED_OUTPUT=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y + +# +# Qualcomm MSM Camera And Video +# + +# +# Camera Sensor Selection +# +# CONFIG_DST is not set +# CONFIG_POHMELFS is not set +# CONFIG_PLAN9AUTH is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_VT6656 is not set +# CONFIG_FB_UDL is not set + +# +# RAR Register Driver +# +# CONFIG_RAR_REGISTER is not set +# CONFIG_IIO is not set + +# +# DSP +# +# CONFIG_RK2818_DSP is not set + +# +# RK1000 control +# +# CONFIG_RK1000_CONTROL is not set + +# +# rk2818 POWER CONTROL +# +# CONFIG_RK2818_POWER is not set + +# +# GPU Vivante +# +CONFIG_VIVANTE=y + +# +# IPP +# +CONFIG_RK29_IPP=y + +# +# CMMB +# +# CONFIG_CMMB is not set +# CONFIG_TEST_CODE is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=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_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +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_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_9BYTE_TAGS is not set +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_PAGE_POISONING is not set +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_KGDB is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL 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_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 + +# +# 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=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=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 is not set +# 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=y +# 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=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# 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 is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/arm/mach-rk29/board-rk29-newton.c b/arch/arm/mach-rk29/board-rk29-newton.c new file mode 100755 index 000000000000..1147594f2460 --- /dev/null +++ b/arch/arm/mach-rk29/board-rk29-newton.c @@ -0,0 +1,1838 @@ +/* arch/arm/mach-rk29/board-rk29.c + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#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 /* ddl@rock-chips.com : camera support */ +#include /* ddl@rock-chips.com : camera support */ +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "devices.h" +#include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h" + +#ifdef CONFIG_VIDEO_RK29 +/*---------------- Camera Sensor Macro Define Begin ------------------------*/ +/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/ +#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642 /* back camera sensor */ +#define CONFIG_SENSOR_IIC_ADDR_0 0x78 +#define CONFIG_SENSOR_IIC_ADAPTER_ID_0 1 +#define CONFIG_SENSOR_POWER_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_RESET_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_POWERDN_PIN_0 RK29_PIN6_PB7 +#define CONFIG_SENSOR_FALSH_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L +#define CONFIG_SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L +#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H +#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L + +#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659 /* front camera sensor */ +#define CONFIG_SENSOR_IIC_ADDR_1 0x60 +#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 1 +#define CONFIG_SENSOR_POWER_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_RESET_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_POWERDN_PIN_1 RK29_PIN5_PD7 +#define CONFIG_SENSOR_FALSH_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L +#define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L +#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H +#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L +#endif //#ifdef CONFIG_VIDEO_RK29 +/*---------------- Camera Sensor Configuration Macro End------------------------*/ +#include "../../../drivers/media/video/rk29_camera.c" +/*---------------- Camera Sensor Macro Define End ------------------------*/ + +/* Set memory size of pmem */ +#ifdef CONFIG_RK29_MEM_SIZE_M +#define SDRAM_SIZE (CONFIG_RK29_MEM_SIZE_M * SZ_1M) +#else +#define SDRAM_SIZE SZ_512M +#endif +#define PMEM_GPU_SIZE SZ_64M +#define PMEM_UI_SIZE SZ_32M +#define PMEM_VPU_SIZE SZ_64M +#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY +#ifdef CONFIG_VIDEO_RK29_WORK_IPP +#define MEM_CAMIPP_SIZE SZ_4M +#else +#define MEM_CAMIPP_SIZE 0 +#endif +#define MEM_FB_SIZE (3*SZ_2M) +#ifdef CONFIG_FB_WORK_IPP +#define MEM_FBIPP_SIZE SZ_8M //1920 x 1080 x 2 x 2 //RGB565 = x2;RGB888 = x4 +#else +#define MEM_FBIPP_SIZE 0 +#endif +#define PMEM_GPU_BASE ((u32)RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE) +#define PMEM_UI_BASE (PMEM_GPU_BASE - PMEM_UI_SIZE) +#define PMEM_VPU_BASE (PMEM_UI_BASE - PMEM_VPU_SIZE) +#define PMEM_CAM_BASE (PMEM_VPU_BASE - PMEM_CAM_SIZE) +#define MEM_CAMIPP_BASE (PMEM_CAM_BASE - MEM_CAMIPP_SIZE) +#define MEM_FB_BASE (MEM_CAMIPP_BASE - MEM_FB_SIZE) +#define MEM_FBIPP_BASE (MEM_FB_BASE - MEM_FBIPP_SIZE) +#define LINUX_SIZE (MEM_FBIPP_BASE - RK29_SDRAM_PHYS) + +#define PREALLOC_WLAN_SEC_NUM 4 +#define PREALLOC_WLAN_BUF_NUM 160 +#define PREALLOC_WLAN_SECTION_HEADER 24 + +#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512) +#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024) + +#define WLAN_SKB_BUF_NUM 16 + +static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; + +struct wifi_mem_prealloc { + void *mem_ptr; + unsigned long size; +}; + +extern struct sys_timer rk29_timer; + +static int rk29_nand_io_init(void) +{ + return 0; +} + +struct rk29_nand_platform_data rk29_nand_data = { + .width = 1, /* data bus width in bytes */ + .hw_ecc = 1, /* hw ecc 0: soft ecc */ + .num_flash = 1, + .io_init = rk29_nand_io_init, +}; + +#define TOUCH_SCREEN_STANDBY_PIN RK29_PIN6_PD1 +#define TOUCH_SCREEN_STANDBY_VALUE GPIO_HIGH +#define TOUCH_SCREEN_DISPLAY_PIN INVALID_GPIO +#define TOUCH_SCREEN_DISPLAY_VALUE GPIO_HIGH +#ifdef CONFIG_FB_RK29 +/***************************************************************************************** + * lcd devices + * author: zyw@rock-chips.com + *****************************************************************************************/ +//#ifdef CONFIG_LCD_TD043MGEA1 +#define LCD_TXD_PIN INVALID_GPIO +#define LCD_CLK_PIN INVALID_GPIO +#define LCD_CS_PIN INVALID_GPIO +/***************************************************************************************** +* frame buffe devices +* author: zyw@rock-chips.com +*****************************************************************************************/ +#define FB_ID 0 +#define FB_DISPLAY_ON_PIN INVALID_GPIO// RK29_PIN6_PD0 +#define FB_LCD_STANDBY_PIN INVALID_GPIO +#define FB_LCD_CABC_EN_PIN RK29_PIN6_PD2 +#define FB_MCU_FMK_PIN INVALID_GPIO + +#define FB_DISPLAY_ON_VALUE GPIO_HIGH +#define FB_LCD_STANDBY_VALUE GPIO_HIGH + +static int rk29_lcd_io_init(void) +{ + int ret = 0; + return ret; +} + +static int rk29_lcd_io_deinit(void) +{ + int ret = 0; + return ret; +} + +static struct rk29lcd_info rk29_lcd_info = { + .txd_pin = LCD_TXD_PIN, + .clk_pin = LCD_CLK_PIN, + .cs_pin = LCD_CS_PIN, + .io_init = rk29_lcd_io_init, + .io_deinit = rk29_lcd_io_deinit, +}; + +int rk29_fb_io_enable(void) +{ + if(FB_DISPLAY_ON_PIN != INVALID_GPIO) + { + gpio_direction_output(FB_DISPLAY_ON_PIN, 0); + gpio_set_value(FB_DISPLAY_ON_PIN, FB_DISPLAY_ON_VALUE); + } + if(FB_LCD_STANDBY_PIN != INVALID_GPIO) + { + gpio_direction_output(FB_LCD_STANDBY_PIN, 0); + gpio_set_value(FB_LCD_STANDBY_PIN, FB_LCD_STANDBY_VALUE); + } + return 0; +} + +int rk29_fb_io_disable(void) +{ + if(FB_DISPLAY_ON_PIN != INVALID_GPIO) + { + gpio_direction_output(FB_DISPLAY_ON_PIN, 0); + gpio_set_value(FB_DISPLAY_ON_PIN, !FB_DISPLAY_ON_VALUE); + } + if(FB_LCD_STANDBY_PIN != INVALID_GPIO) + { + gpio_direction_output(FB_LCD_STANDBY_PIN, 0); + gpio_set_value(FB_LCD_STANDBY_PIN, !FB_LCD_STANDBY_VALUE); + } + return 0; +} + +static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting) +{ + int ret = 0; + if(fb_setting->mcu_fmk_en && (FB_MCU_FMK_PIN != INVALID_GPIO)) + { + ret = gpio_request(FB_MCU_FMK_PIN, NULL); + if(ret != 0) + { + gpio_free(FB_MCU_FMK_PIN); + printk(">>>>>> FB_MCU_FMK_PIN gpio_request err \n "); + } + gpio_direction_input(FB_MCU_FMK_PIN); + } + if(fb_setting->disp_on_en) + { + if(FB_DISPLAY_ON_PIN != INVALID_GPIO) + { + ret = gpio_request(FB_DISPLAY_ON_PIN, NULL); + if(ret != 0) + { + gpio_free(FB_DISPLAY_ON_PIN); + printk(">>>>>> FB_DISPLAY_ON_PIN gpio_request err \n "); + } + } + else + { + ret = gpio_request(TOUCH_SCREEN_DISPLAY_PIN, NULL); + if(ret != 0) + { + gpio_free(TOUCH_SCREEN_DISPLAY_PIN); + printk(">>>>>> TOUCH_SCREEN_DISPLAY_PIN gpio_request err \n "); + } + gpio_direction_output(TOUCH_SCREEN_DISPLAY_PIN, 0); + gpio_set_value(TOUCH_SCREEN_DISPLAY_PIN, TOUCH_SCREEN_DISPLAY_VALUE); + } + } + + if(fb_setting->disp_on_en) + { + if(FB_LCD_STANDBY_PIN != INVALID_GPIO) + { + ret = gpio_request(FB_LCD_STANDBY_PIN, NULL); + if(ret != 0) + { + gpio_free(FB_LCD_STANDBY_PIN); + printk(">>>>>> FB_LCD_STANDBY_PIN gpio_request err \n "); + } + } + else + { + ret = gpio_request(TOUCH_SCREEN_STANDBY_PIN, NULL); + if(ret != 0) + { + gpio_free(TOUCH_SCREEN_STANDBY_PIN); + printk(">>>>>> TOUCH_SCREEN_STANDBY_PIN gpio_request err \n "); + } + gpio_direction_output(TOUCH_SCREEN_STANDBY_PIN, 0); + gpio_set_value(TOUCH_SCREEN_STANDBY_PIN, TOUCH_SCREEN_STANDBY_VALUE); + } + } + + if(FB_LCD_CABC_EN_PIN != INVALID_GPIO) + { + ret = gpio_request(FB_LCD_CABC_EN_PIN, NULL); + if(ret != 0) + { + gpio_free(FB_LCD_CABC_EN_PIN); + printk(">>>>>> FB_LCD_CABC_EN_PIN gpio_request err \n "); + } + gpio_direction_output(FB_LCD_CABC_EN_PIN, 0); + gpio_set_value(FB_LCD_CABC_EN_PIN, GPIO_LOW); + } + + rk29_fb_io_enable(); //enable it + + return ret; +} + +static struct rk29fb_info rk29_fb_info = { + .fb_id = FB_ID, + .mcu_fmk_pin = FB_MCU_FMK_PIN, + .lcd_info = &rk29_lcd_info, + .io_init = rk29_fb_io_init, + .io_enable = rk29_fb_io_enable, + .io_disable = rk29_fb_io_disable, +}; + +/* rk29 fb resource */ +static struct resource rk29_fb_resource[] = { + [0] = { + .name = "lcdc reg", + .start = RK29_LCDC_PHYS, + .end = RK29_LCDC_PHYS + RK29_LCDC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "lcdc irq", + .start = IRQ_LCDC, + .end = IRQ_LCDC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "win1 buf", + .start = MEM_FB_BASE, + .end = MEM_FB_BASE + MEM_FB_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + #ifdef CONFIG_FB_WORK_IPP + [3] = { + .name = "win1 ipp buf", + .start = MEM_FBIPP_BASE, + .end = MEM_FBIPP_BASE + MEM_FBIPP_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + #endif +}; + +/*platform_device*/ +struct platform_device rk29_device_fb = { + .name = "rk29-fb", + .id = 4, + .num_resources = ARRAY_SIZE(rk29_fb_resource), + .resource = rk29_fb_resource, + .dev = { + .platform_data = &rk29_fb_info, + } +}; + +struct platform_device rk29_device_dma_cpy = { + .name = "dma_memcpy", + .id = 4, + +}; + +#endif + +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem", + .start = PMEM_UI_BASE, + .size = PMEM_UI_SIZE, + .no_allocator = 0, + .cached = 1, +}; + +static struct platform_device android_pmem_device = { + .name = "android_pmem", + .id = 0, + .dev = { + .platform_data = &android_pmem_pdata, + }, +}; + + +static struct vpu_mem_platform_data vpu_mem_pdata = { + .name = "vpu_mem", + .start = PMEM_VPU_BASE, + .size = PMEM_VPU_SIZE, + .cached = 1, +}; + +static struct platform_device rk29_vpu_mem_device = { + .name = "vpu_mem", + .id = 2, + .dev = { + .platform_data = &vpu_mem_pdata, + }, +}; +#ifdef CONFIG_VIDEO_RK29XX_VOUT +static struct platform_device rk29_v4l2_output_devce = { + .name = "rk29_vout", +}; +#endif +/*HANNSTAR_P1003 touch*/ +#if defined (CONFIG_HANNSTAR_P1003) +#define TOUCH_RESET_PIN RK29_PIN6_PC3 +#define TOUCH_INT_PIN RK29_PIN0_PA2 + +int p1003_init_platform_hw(void) +{ + if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){ + gpio_free(TOUCH_RESET_PIN); + printk("p1003_init_platform_hw gpio_request error\n"); + return -EIO; + } + + if(gpio_request(TOUCH_INT_PIN,NULL) != 0){ + gpio_free(TOUCH_INT_PIN); + printk("p1003_init_platform_hw gpio_request error\n"); + return -EIO; + } + gpio_pull_updown(TOUCH_INT_PIN, 1); + gpio_direction_output(TOUCH_RESET_PIN, 0); + msleep(500); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + msleep(500); + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + + return 0; +} + + +struct p1003_platform_data p1003_info = { + .model= 1003, + .init_platform_hw= p1003_init_platform_hw, + +}; +#endif +#if defined (CONFIG_EETI_EGALAX) +#define TOUCH_RESET_PIN RK29_PIN6_PC3 +#define TOUCH_INT_PIN RK29_PIN0_PA2 + +static int EETI_EGALAX_init_platform_hw(void) +{ + if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){ + gpio_free(TOUCH_RESET_PIN); + printk("p1003_init_platform_hw gpio_request error\n"); + return -EIO; + } + + if(gpio_request(TOUCH_INT_PIN,NULL) != 0){ + gpio_free(TOUCH_INT_PIN); + printk("p1003_init_platform_hw gpio_request error\n"); + return -EIO; + } + gpio_pull_updown(TOUCH_INT_PIN, 1); + gpio_direction_output(TOUCH_RESET_PIN, 0); + msleep(500); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + msleep(500); + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + + return 0; +} + + +static struct eeti_egalax_platform_data eeti_egalax_info = { + .model= 1003, + .init_platform_hw= EETI_EGALAX_init_platform_hw, + .standby_pin = TOUCH_SCREEN_STANDBY_PIN, + .standby_value = TOUCH_SCREEN_STANDBY_VALUE, + .disp_on_pin = TOUCH_SCREEN_DISPLAY_PIN, + .disp_on_value = TOUCH_SCREEN_DISPLAY_VALUE, +}; +#endif + +#if defined (CONFIG_TOUCHSCREEN_FT5406) +#define TOUCH_RESET_PIN RK29_PIN6_PC3 +#define TOUCH_INT_PIN RK29_PIN0_PA2 + +//#define TOUCH_POER_PIN RK29_PIN6_PB2 + +int ft5406_init_platform_hw(void) +{ + printk("ft5406_init_platform_hw\n"); + + if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){ + gpio_free(TOUCH_RESET_PIN); + printk("ft5406_init_platform_hw gpio_request error\n"); + return -EIO; + } + + if(gpio_request(TOUCH_INT_PIN,NULL) != 0){ + gpio_free(TOUCH_INT_PIN); + printk("ift5406_init_platform_hw gpio_request error\n"); + return -EIO; + } + + // if(gpio_request(TOUCH_POER_PIN,NULL) != 0){ + // gpio_free(TOUCH_POER_PIN); + // printk("ft5406_init_platform_hw gpio_power error\n"); +// return -EIO; + // } + +#if 1 + gpio_direction_output(TOUCH_RESET_PIN, 0); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + msleep(100); + gpio_direction_output(TOUCH_INT_PIN, 0); + gpio_set_value(TOUCH_INT_PIN,GPIO_LOW); + mdelay(10); +// gpio_direction_output(TOUCH_POER_PIN, 0); +// gpio_set_value(TOUCH_POER_PIN,GPIO_HIGH); + + //msleep(3000); + msleep(50); //harry 2011.04.20 + + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + msleep(100); + gpio_direction_output(TOUCH_INT_PIN, 1); + gpio_pull_updown(TOUCH_INT_PIN, 0); +#endif + + + return 0; +} + + +struct ft5406_platform_data ft5406_info = { + + .init_platform_hw= ft5406_init_platform_hw, + +}; +#endif + + + +/*MMA8452 gsensor*/ +#if defined (CONFIG_GS_MMA8452) +#define MMA8452_INT_PIN RK29_PIN0_PA3 + +static int mma8452_init_platform_hw(void) +{ + + if(gpio_request(MMA8452_INT_PIN,NULL) != 0){ + gpio_free(MMA8452_INT_PIN); + printk("mma8452_init_platform_hw gpio_request error\n"); + return -EIO; + } + gpio_pull_updown(MMA8452_INT_PIN, 1); + return 0; +} + + +static struct mma8452_platform_data mma8452_info = { + .model= 8452, + .swap_xy = 0, + .init_platform_hw= mma8452_init_platform_hw, + +}; +#endif + +#if defined (CONFIG_BATTERY_BQ27510) +#define DC_CHECK_PIN RK29_PIN4_PA1 +#define LI_LION_BAT_NUM 2 +static int bq27510_init_dc_check_pin(void){ + if(gpio_request(DC_CHECK_PIN,"dc_check") != 0){ + gpio_free(DC_CHECK_PIN); + printk("bq27510 init dc check pin request error\n"); + return -EIO; + } + gpio_direction_input(DC_CHECK_PIN); + return 0; +} + +struct bq27510_platform_data bq27510_info = { + .init_dc_check_pin = bq27510_init_dc_check_pin, + .dc_check_pin = DC_CHECK_PIN, + .bat_num = LI_LION_BAT_NUM, +}; +#endif + + +/***************************************************************************************** + * i2c devices + * author: kfx@rock-chips.com +*****************************************************************************************/ +static int rk29_i2c0_io_init(void) +{ +#ifdef CONFIG_RK29_I2C0_CONTROLLER + rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_I2C0_SCL); + rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_I2C0_SDA); +#else + rk29_mux_api_set(GPIO2B7_I2C0SCL_NAME, GPIO2L_GPIO2B7); + rk29_mux_api_set(GPIO2B6_I2C0SDA_NAME, GPIO2L_GPIO2B6); +#endif + return 0; +} + +static int rk29_i2c1_io_init(void) +{ +#ifdef CONFIG_RK29_I2C1_CONTROLLER + rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_I2C1_SCL); + rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_I2C1_SDA); +#else + rk29_mux_api_set(GPIO1A7_I2C1SCL_NAME, GPIO1L_GPIO1A7); + rk29_mux_api_set(GPIO1A6_I2C1SDA_NAME, GPIO1L_GPIO1A6); +#endif + return 0; +} +static int rk29_i2c2_io_init(void) +{ +#ifdef CONFIG_RK29_I2C2_CONTROLLER + rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_I2C2_SCL); + rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_I2C2_SDA); +#else + rk29_mux_api_set(GPIO5D4_I2C2SCL_NAME, GPIO5H_GPIO5D4); + rk29_mux_api_set(GPIO5D3_I2C2SDA_NAME, GPIO5H_GPIO5D3); +#endif + return 0; +} + +static int rk29_i2c3_io_init(void) +{ +#ifdef CONFIG_RK29_I2C3_CONTROLLER + rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_I2C3_SCL); + rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_I2C3_SDA); +#else + rk29_mux_api_set(GPIO2B5_UART3RTSN_I2C3SCL_NAME, GPIO2L_GPIO2B5); + rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_GPIO2B4); +#endif + return 0; +} +#ifdef CONFIG_RK29_I2C0_CONTROLLER +struct rk29_i2c_platform_data default_i2c0_data = { + .bus_num = 0, + .flags = 0, + .slave_addr = 0xff, + .scl_rate = 400*1000, + .mode = I2C_MODE_IRQ, + .io_init = rk29_i2c0_io_init, +}; +#else +struct i2c_gpio_platform_data default_i2c0_data = { + .sda_pin = RK29_PIN2_PB6, + .scl_pin = RK29_PIN2_PB7, + .udelay = 5, // clk = 500/udelay = 100Khz + .timeout = 100,//msecs_to_jiffies(200), + .bus_num = 0, + .io_init = rk29_i2c0_io_init, +}; +#endif +#ifdef CONFIG_RK29_I2C1_CONTROLLER +struct rk29_i2c_platform_data default_i2c1_data = { + .bus_num = 1, + .flags = 0, + .slave_addr = 0xff, + .scl_rate = 400*1000, + .mode = I2C_MODE_IRQ, + .io_init = rk29_i2c1_io_init, +}; +#else +struct i2c_gpio_platform_data default_i2c1_data = { + .sda_pin = RK29_PIN1_PA6, + .scl_pin = RK29_PIN1_PA7, + .udelay = 5, // clk = 500/udelay = 100Khz + .timeout = 100,//msecs_to_jiffies(200), + .bus_num = 1, + .io_init = rk29_i2c1_io_init, +}; +#endif +#ifdef CONFIG_RK29_I2C2_CONTROLLER +struct rk29_i2c_platform_data default_i2c2_data = { + .bus_num = 2, + .flags = 0, + .slave_addr = 0xff, + .scl_rate = 400*1000, + .mode = I2C_MODE_IRQ, + .io_init = rk29_i2c2_io_init, +}; +#else +struct i2c_gpio_platform_data default_i2c2_data = { + .sda_pin = RK29_PIN5_PD3, + .scl_pin = RK29_PIN5_PD4, + .udelay = 5, // clk = 500/udelay = 100Khz + .timeout = 100,//msecs_to_jiffies(200), + .bus_num = 2, + .io_init = rk29_i2c2_io_init, +}; +#endif +#ifdef CONFIG_RK29_I2C3_CONTROLLER +struct rk29_i2c_platform_data default_i2c3_data = { + .bus_num = 3, + .flags = 0, + .slave_addr = 0xff, + .scl_rate = 400*1000, + .mode = I2C_MODE_IRQ, + .io_init = rk29_i2c3_io_init, +}; +#else +struct i2c_gpio_platform_data default_i2c3_data = { + .sda_pin = RK29_PIN5_PB5, + .scl_pin = RK29_PIN5_PB4, + .udelay = 5, // clk = 500/udelay = 100Khz + .timeout = 100,//msecs_to_jiffies(200), + .bus_num = 3, + .io_init = rk29_i2c3_io_init, +}; +#endif +#ifdef CONFIG_I2C0_RK29 +static struct i2c_board_info __initdata board_i2c0_devices[] = { +#if defined (CONFIG_RK1000_CONTROL) + { + .type = "rk1000_control", + .addr = 0x40, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_alc5621) + { + .type = "ALC5621", + .addr = 0x1a, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_alc5631) + { + .type = "rt5631", + .addr = 0x1a, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_RK1000) + { + .type = "rk1000_i2c_codec", + .addr = 0x60, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_WM8900) + { + .type = "wm8900", + .addr = 0x1A, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_CS42L52) + { + .type = "cs42l52", + .addr = 0x4A, + .flags = 0, + }, +#endif +#if defined (CONFIG_BATTERY_STC3100) + { + .type = "stc3100", + .addr = 0x70, + .flags = 0, + }, +#endif +#if defined (CONFIG_BATTERY_BQ27510) + { + .type = "bq27510", + .addr = 0x55, + .flags = 0, + .platform_data = &bq27510_info, + }, +#endif +#if defined (CONFIG_RTC_HYM8563) + { + .type = "rtc_hym8563", + .addr = 0x51, + .flags = 0, + .irq = RK29_PIN0_PA1, + }, +#endif +#if defined (CONFIG_RTC_M41T66) +{ +.type = "rtc-M41T62", +.addr = 0xd0>>1, +.flags = 0, +.irq = RK29_PIN0_PA1, +}, +#endif +#if defined (CONFIG_GS_MMA8452) + { + .type = "gs_mma8452", + .addr = 0x1c, + .flags = 0, + .irq = MMA8452_INT_PIN, + .platform_data = &mma8452_info, + }, +#endif +#if defined (CONFIG_COMPASS_AK8973) + { + .type = "ak8973", + .addr = 0x1d, + .flags = 0, + .irq = RK29_PIN0_PA4, + }, +#endif +#if defined (CONFIG_COMPASS_AK8975) + { + .type = "ak8975", + .addr = 0x0d, + .flags = 0, + .irq = RK29_PIN0_PA4, + }, +#endif +}; +#endif + +#ifdef CONFIG_I2C1_RK29 +static struct i2c_board_info __initdata board_i2c1_devices[] = { +#if defined (CONFIG_RK1000_CONTROL1) + { + .type = "rk1000_control", + .addr = 0x40, + .flags = 0, + }, +#endif +#if defined (CONFIG_ANX7150) || defined (CONFIG_ANX7150_NEW) + { + .type = "anx7150", + .addr = 0x39, //0x39, 0x3d + .flags = 0, + .irq = RK29_PIN1_PD7, + }, +#endif + +}; +#endif + +#ifdef CONFIG_I2C2_RK29 +static struct i2c_board_info __initdata board_i2c2_devices[] = { +#if defined (CONFIG_HANNSTAR_P1003) + { + .type = "p1003_touch", + .addr = 0x04, + .flags = 0, //I2C_M_NEED_DELAY + .irq = RK29_PIN0_PA2, + .platform_data = &p1003_info, + //.udelay = 100 + }, +#endif +#if defined (CONFIG_EETI_EGALAX) + { + .type = "egalax_i2c", + .addr = 0x30, + .flags = 0, + .irq = RK29_PIN0_PA2, + .platform_data = &eeti_egalax_info, + }, +#endif + +#if defined (CONFIG_TOUCHSCREEN_FT5406) +{ + .type ="ft5x0x_ts", + .addr = 0x38, //0x70, + .flags =0, + .irq =RK29_PIN0_PA2, + .platform_data = &ft5406_info, +}, + //added by koffu + { + .type ="ft_rw_iic_drv", + .addr = 0x38, //0x70, + .flags =0, + //.irq =RK29_PIN0_PA2, + //.platform_data = &ft5406_info, + }, + +#endif +}; + +#endif + +#ifdef CONFIG_I2C3_RK29 +static struct i2c_board_info __initdata board_i2c3_devices[] = { +}; +#endif + +/***************************************************************************************** + * camera devices + * author: ddl@rock-chips.com + *****************************************************************************************/ +#ifdef CONFIG_VIDEO_RK29 +#define CONFIG_SENSOR_POWER_IOCTL_USR 0 +#define CONFIG_SENSOR_RESET_IOCTL_USR 0 +#define CONFIG_SENSOR_POWERDOWN_IOCTL_USR 0 +#define CONFIG_SENSOR_FLASH_IOCTL_USR 0 + +#if CONFIG_SENSOR_POWER_IOCTL_USR +static int sensor_power_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_POWER_IOCTL_USR is 1, sensor_power_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_RESET_IOCTL_USR +static int sensor_reset_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_RESET_IOCTL_USR is 1, sensor_reset_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_POWERDOWN_IOCTL_USR +static int sensor_powerdown_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_POWERDOWN_IOCTL_USR is 1, sensor_powerdown_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_FLASH_IOCTL_USR +static int sensor_flash_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_FLASH_IOCTL_USR is 1, sensor_flash_usr_cb function must be writed!!"; +} +#endif + +static struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = { + #if CONFIG_SENSOR_POWER_IOCTL_USR + .sensor_power_cb = sensor_power_usr_cb, + #else + .sensor_power_cb = NULL, + #endif + + #if CONFIG_SENSOR_RESET_IOCTL_USR + .sensor_reset_cb = sensor_reset_usr_cb, + #else + .sensor_reset_cb = NULL, + #endif + + #if CONFIG_SENSOR_POWERDOWN_IOCTL_USR + .sensor_powerdown_cb = sensor_powerdown_usr_cb, + #else + .sensor_powerdown_cb = NULL, + #endif + + #if CONFIG_SENSOR_FLASH_IOCTL_USR + .sensor_flash_cb = sensor_flash_usr_cb, + #else + .sensor_flash_cb = NULL, + #endif +}; + +#include "../../../drivers/media/video/rk29_camera.c" +#endif +/***************************************************************************************** + * backlight devices + * author: nzy@rock-chips.com + *****************************************************************************************/ +#ifdef CONFIG_BACKLIGHT_RK29_BL + /* + GPIO1B5_PWM0_NAME, GPIO1L_PWM0 + GPIO5D2_PWM1_UART1SIRIN_NAME, GPIO5H_PWM1 + GPIO2A3_SDMMC0WRITEPRT_PWM2_NAME, GPIO2L_PWM2 + GPIO1A5_EMMCPWREN_PWM3_NAME, GPIO1L_PWM3 + */ + +#define PWM_ID 0 +#define PWM_MUX_NAME GPIO1B5_PWM0_NAME +#define PWM_MUX_MODE GPIO1L_PWM0 +#define PWM_MUX_MODE_GPIO GPIO1L_GPIO1B5 +#define PWM_GPIO RK29_PIN1_PB5 +#define PWM_EFFECT_VALUE 1 + +#define LCD_DISP_ON_PIN + +#ifdef LCD_DISP_ON_PIN +//#define BL_EN_MUX_NAME GPIOF34_UART3_SEL_NAME +//#define BL_EN_MUX_MODE IOMUXB_GPIO1_B34 + +#define BL_EN_PIN RK29_PIN6_PD0 +#define BL_EN_VALUE GPIO_HIGH +#endif +static int rk29_backlight_io_init(void) +{ + int ret = 0; + + rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); + #ifdef LCD_DISP_ON_PIN + // rk29_mux_api_set(BL_EN_MUX_NAME, BL_EN_MUX_MODE); + + ret = gpio_request(BL_EN_PIN, NULL); + if(ret != 0) + { + gpio_free(BL_EN_PIN); + } + + gpio_direction_output(BL_EN_PIN, 0); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); + #endif + return ret; +} + +static int rk29_backlight_io_deinit(void) +{ + int ret = 0; + #ifdef LCD_DISP_ON_PIN + gpio_free(BL_EN_PIN); + #endif + rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + return ret; +} + +static int rk29_backlight_pwm_suspend(void) +{ + int ret = 0; + rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + if (gpio_request(PWM_GPIO, NULL)) { + printk("func %s, line %d: request gpio fail\n", __FUNCTION__, __LINE__); + return -1; + } + gpio_direction_output(PWM_GPIO, GPIO_LOW); + #ifdef LCD_DISP_ON_PIN + gpio_direction_output(BL_EN_PIN, 0); + gpio_set_value(BL_EN_PIN, !BL_EN_VALUE); + #endif + return ret; +} + +static int rk29_backlight_pwm_resume(void) +{ + gpio_free(PWM_GPIO); + rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); + + #ifdef LCD_DISP_ON_PIN + msleep(30); + gpio_direction_output(BL_EN_PIN, 1); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); + #endif + return 0; +} + +struct rk29_bl_info rk29_bl_info = { + .pwm_id = PWM_ID, + .bl_ref = PWM_EFFECT_VALUE, + .io_init = rk29_backlight_io_init, + .io_deinit = rk29_backlight_io_deinit, + .pwm_suspend = rk29_backlight_pwm_suspend, + .pwm_resume = rk29_backlight_pwm_resume, +}; +#endif +/***************************************************************************************** +* pwm voltage regulator devices +******************************************************************************************/ +#if defined (CONFIG_RK29_PWM_REGULATOR) + +#define REGULATOR_PWM_ID 2 +#define REGULATOR_PWM_MUX_NAME GPIO2A3_SDMMC0WRITEPRT_PWM2_NAME +#define REGULATOR_PWM_MUX_MODE GPIO2L_PWM2 +#define REGULATOR_PWM_MUX_MODE_GPIO GPIO2L_GPIO2A3 +#define REGULATOR_PWM_GPIO RK29_PIN2_PA3 + +static struct regulator_consumer_supply pwm_consumers[] = { + { + .supply = "vcore", + } +}; + +static struct regulator_init_data rk29_pwm_regulator_data = { + .constraints = { + .name = "PWM2", + .min_uV = 950000, + .max_uV = 1400000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(pwm_consumers), + .consumer_supplies = pwm_consumers, +}; + +static struct pwm_platform_data rk29_regulator_pwm_platform_data = { + .pwm_id = REGULATOR_PWM_ID, + .pwm_gpio = REGULATOR_PWM_GPIO, + //.pwm_iomux_name[] = REGULATOR_PWM_MUX_NAME; + .pwm_iomux_name = REGULATOR_PWM_MUX_NAME, + .pwm_iomux_pwm = REGULATOR_PWM_MUX_MODE, + .pwm_iomux_gpio = REGULATOR_PWM_MUX_MODE_GPIO, + .init_data = &rk29_pwm_regulator_data, +}; + +static struct platform_device rk29_device_pwm_regulator = { + .name = "pwm-voltage-regulator", + .id = -1, + .dev = { + .platform_data = &rk29_regulator_pwm_platform_data, + }, +}; + +#endif + +/***************************************************************************************** + * SDMMC devices +*****************************************************************************************/ +#ifdef CONFIG_SDMMC0_RK29 +static int rk29_sdmmc0_cfg_gpio(void) +{ + rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD); + rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT); + rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0); + rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1); + rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2); + rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3); + rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2); + rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5); ///GPIO5H_SDMMC0_PWR_EN); ///GPIO5H_GPIO5D5); + gpio_request(RK29_PIN5_PD5,"sdmmc"); +#if 0 + gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH); + mdelay(100); + gpio_set_value(RK29_PIN5_PD5,GPIO_LOW); +#else + gpio_direction_output(RK29_PIN5_PD5,GPIO_LOW); +#endif + return 0; +} + +#define CONFIG_SDMMC0_USE_DMA +struct rk29_sdmmc_platform_data default_sdmmc0_data = { + .host_ocr_avail = (MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30| + MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33| + MMC_VDD_33_34|MMC_VDD_34_35| MMC_VDD_35_36), + .host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED), + .io_init = rk29_sdmmc0_cfg_gpio, + .dma_name = "sd_mmc", +#ifdef CONFIG_SDMMC0_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif + .detect_irq = RK29_PIN2_PA2, // INVALID_GPIO + .enable_sd_wakeup = 0, +}; +#endif +#ifdef CONFIG_SDMMC1_RK29 +#define CONFIG_SDMMC1_USE_DMA +static int rk29_sdmmc1_cfg_gpio(void) +{ + rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD); + rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT); + rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0); + rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_SDMMC1_DATA1); + rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2); + rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3); + //rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_SDMMC1_DETECT_N); + return 0; +} + +#ifdef CONFIG_WIFI_CONTROL_FUNC +static int rk29sdk_wifi_status(struct device *dev); +static int rk29sdk_wifi_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id); +#endif + +#define RK29SDK_WIFI_SDIO_CARD_DETECT_N RK29_PIN1_PD6 + +struct rk29_sdmmc_platform_data default_sdmmc1_data = { + .host_ocr_avail = (MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29| + MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32| + MMC_VDD_32_33|MMC_VDD_33_34), + .host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_SDIO_IRQ| + MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED), + .io_init = rk29_sdmmc1_cfg_gpio, + .dma_name = "sdio", +#ifdef CONFIG_SDMMC1_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif +#ifdef CONFIG_WIFI_CONTROL_FUNC + .status = rk29sdk_wifi_status, + .register_status_notify = rk29sdk_wifi_status_register, +#endif +#if 0 + .detect_irq = RK29SDK_WIFI_SDIO_CARD_DETECT_N, +#endif +}; +#endif + +#ifdef CONFIG_WIFI_CONTROL_FUNC +#define RK29SDK_WIFI_BT_GPIO_POWER_N RK29_PIN5_PD6 +#define RK29SDK_WIFI_GPIO_RESET_N RK29_PIN6_PC0 +#define RK29SDK_BT_GPIO_RESET_N RK29_PIN6_PC4 + +static int rk29sdk_wifi_cd = 0; /* wifi virtual 'card detect' status */ +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; +int rk29sdk_wifi_power_state = 0; +int rk29sdk_bt_power_state = 0; + +static int rk29sdk_wifi_status(struct device *dev) +{ + return rk29sdk_wifi_cd; +} + +static int rk29sdk_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id) +{ + if(wifi_status_cb) + return -EAGAIN; + wifi_status_cb = callback; + wifi_status_cb_devid = dev_id; + return 0; +} + +static int rk29sdk_wifi_bt_gpio_control_init(void) +{ + if (gpio_request(RK29SDK_WIFI_BT_GPIO_POWER_N, "wifi_bt_power")) { + pr_info("%s: request wifi_bt power gpio failed\n", __func__); + return -1; + } + + if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) { + pr_info("%s: request wifi reset gpio failed\n", __func__); + gpio_free(RK29SDK_WIFI_BT_GPIO_POWER_N); + return -1; + } + + if (gpio_request(RK29SDK_BT_GPIO_RESET_N, "bt reset")) { + pr_info("%s: request bt reset gpio failed\n", __func__); + gpio_free(RK29SDK_WIFI_GPIO_RESET_N); + return -1; + } + + gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW); + gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + gpio_direction_output(RK29SDK_BT_GPIO_RESET_N, GPIO_LOW); + + pr_info("%s: init finished\n",__func__); + + return 0; +} + +static int rk29sdk_wifi_power(int on) +{ + pr_info("%s: %d\n", __func__, on); + if (on){ + gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH); + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH); + mdelay(100); + pr_info("wifi turn on power\n"); + }else{ + if (!rk29sdk_bt_power_state){ + gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW); + mdelay(100); + pr_info("wifi shut off power\n"); + }else + { + pr_info("wifi shouldn't shut off power, bt is using it!\n"); + } + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + + } + + rk29sdk_wifi_power_state = on; + return 0; +} + +static int rk29sdk_wifi_reset_state; +static int rk29sdk_wifi_reset(int on) +{ + pr_info("%s: %d\n", __func__, on); + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on); + mdelay(100); + rk29sdk_wifi_reset_state = on; + return 0; +} + +int rk29sdk_wifi_set_carddetect(int val) +{ + pr_info("%s:%d\n", __func__, val); + rk29sdk_wifi_cd = val; + if (wifi_status_cb){ + wifi_status_cb(val, wifi_status_cb_devid); + }else { + pr_warning("%s, nobody to notify\n", __func__); + } + return 0; +} +EXPORT_SYMBOL(rk29sdk_wifi_set_carddetect); + +static struct wifi_mem_prealloc wifi_mem_array[PREALLOC_WLAN_SEC_NUM] = { + {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)} +}; + +static void *rk29sdk_mem_prealloc(int section, unsigned long size) +{ + if (section == PREALLOC_WLAN_SEC_NUM) + return wlan_static_skb; + + if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) + return NULL; + + if (wifi_mem_array[section].size < size) + return NULL; + + return wifi_mem_array[section].mem_ptr; +} + +int __init rk29sdk_init_wifi_mem(void) +{ + int i; + int j; + + for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) { + wlan_static_skb[i] = dev_alloc_skb( + ((i < (WLAN_SKB_BUF_NUM / 2)) ? 4096 : 8192)); + + if (!wlan_static_skb[i]) + goto err_skb_alloc; + } + + for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) { + wifi_mem_array[i].mem_ptr = + kmalloc(wifi_mem_array[i].size, GFP_KERNEL); + + if (!wifi_mem_array[i].mem_ptr) + goto err_mem_alloc; + } + return 0; + +err_mem_alloc: + pr_err("Failed to mem_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + kfree(wifi_mem_array[j].mem_ptr); + + i = WLAN_SKB_BUF_NUM; + +err_skb_alloc: + pr_err("Failed to skb_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + dev_kfree_skb(wlan_static_skb[j]); + + return -ENOMEM; +} + +static struct wifi_platform_data rk29sdk_wifi_control = { + .set_power = rk29sdk_wifi_power, + .set_reset = rk29sdk_wifi_reset, + .set_carddetect = rk29sdk_wifi_set_carddetect, + .mem_prealloc = rk29sdk_mem_prealloc, +}; +static struct platform_device rk29sdk_wifi_device = { + .name = "bcm4329_wlan", + .id = 1, + .dev = { + .platform_data = &rk29sdk_wifi_control, + }, +}; +#endif + + +/* bluetooth rfkill device */ +static struct platform_device rk29sdk_rfkill = { + .name = "rk29sdk_rfkill", + .id = -1, +}; + + +#ifdef CONFIG_VIVANTE +#define GPU_HIGH_CLOCK 552 +#define GPU_LOW_CLOCK 300 +static struct resource resources_gpu[] = { + [0] = { + .name = "gpu_irq", + .start = IRQ_GPU, + .end = IRQ_GPU, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .name = "gpu_base", + .start = RK29_GPU_PHYS, + .end = RK29_GPU_PHYS + RK29_GPU_SIZE, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "gpu_mem", + .start = PMEM_GPU_BASE, + .end = PMEM_GPU_BASE + PMEM_GPU_SIZE, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "gpu_clk", + .start = GPU_LOW_CLOCK, + .end = GPU_HIGH_CLOCK, + .flags = IORESOURCE_IO, + }, +}; +static struct platform_device rk29_device_gpu = { + .name = "galcore", + .id = 0, + .num_resources = ARRAY_SIZE(resources_gpu), + .resource = resources_gpu, +}; +#endif + +#ifdef CONFIG_KEYS_RK29 +extern struct rk29_keys_platform_data rk29_keys_pdata; +static struct platform_device rk29_device_keys = { + .name = "rk29-keypad", + .id = -1, + .dev = { + .platform_data = &rk29_keys_pdata, + }, +}; +#endif + +static void __init rk29_board_iomux_init(void) +{ + #ifdef CONFIG_RK29_PWM_REGULATOR + rk29_mux_api_set(REGULATOR_PWM_MUX_NAME,REGULATOR_PWM_MUX_MODE); + #endif +} + +static struct platform_device *devices[] __initdata = { +#ifdef CONFIG_UART1_RK29 + &rk29_device_uart1, +#endif +#ifdef CONFIG_UART0_RK29 + &rk29_device_uart0, +#endif +#ifdef CONFIG_UART2_RK29 + &rk29_device_uart2, +#endif +#ifdef CONFIG_UART3_RK29 + &rk29_device_uart3, +#endif + +#ifdef CONFIG_RK29_PWM_REGULATOR + &rk29_device_pwm_regulator, +#endif +#ifdef CONFIG_SPIM0_RK29 + &rk29xx_device_spi0m, +#endif +#ifdef CONFIG_SPIM1_RK29 + &rk29xx_device_spi1m, +#endif +#ifdef CONFIG_ADC_RK29 + &rk29_device_adc, +#endif +#ifdef CONFIG_I2C0_RK29 + &rk29_device_i2c0, +#endif +#ifdef CONFIG_I2C1_RK29 + &rk29_device_i2c1, +#endif +#ifdef CONFIG_I2C2_RK29 + &rk29_device_i2c2, +#endif +#ifdef CONFIG_I2C3_RK29 + &rk29_device_i2c3, +#endif + +#ifdef CONFIG_SND_RK29_SOC_I2S_2CH + &rk29_device_iis_2ch, +#endif +#ifdef CONFIG_SND_RK29_SOC_I2S_8CH + &rk29_device_iis_8ch, +#endif + +#ifdef CONFIG_KEYS_RK29 + &rk29_device_keys, +#endif +#ifdef CONFIG_SDMMC0_RK29 + &rk29_device_sdmmc0, +#endif +#ifdef CONFIG_SDMMC1_RK29 + &rk29_device_sdmmc1, +#endif + +#ifdef CONFIG_MTD_NAND_RK29XX + &rk29xx_device_nand, +#endif + +#ifdef CONFIG_WIFI_CONTROL_FUNC + &rk29sdk_wifi_device, +#endif + +#ifdef CONFIG_BT + &rk29sdk_rfkill, +#endif + +#ifdef CONFIG_MTD_NAND_RK29 + &rk29_device_nand, +#endif + +#ifdef CONFIG_FB_RK29 + &rk29_device_fb, + &rk29_device_dma_cpy, +#endif +#ifdef CONFIG_BACKLIGHT_RK29_BL + &rk29_device_backlight, +#endif +#ifdef CONFIG_RK29_VMAC + &rk29_device_vmac, +#endif +#ifdef CONFIG_VIVANTE + &rk29_device_gpu, +#endif +#ifdef CONFIG_VIDEO_RK29 + &rk29_device_camera, /* ddl@rock-chips.com : camera support */ + #if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00) + &rk29_soc_camera_pdrv_0, + #endif + &rk29_soc_camera_pdrv_1, + &android_pmem_cam_device, +#endif + &android_pmem_device, + &rk29_vpu_mem_device, +#ifdef CONFIG_USB20_OTG + &rk29_device_usb20_otg, +#endif +#ifdef CONFIG_USB20_HOST + &rk29_device_usb20_host, +#endif +#ifdef CONFIG_USB11_HOST + &rk29_device_usb11_host, +#endif +#ifdef CONFIG_USB_ANDROID + &android_usb_device, + &usb_mass_storage_device, +#endif +#ifdef CONFIG_RK29_IPP + &rk29_device_ipp, +#endif +#ifdef CONFIG_VIDEO_RK29XX_VOUT + &rk29_v4l2_output_devce, +#endif +}; + +/***************************************************************************************** + * spi devices + * author: cmc@rock-chips.com + *****************************************************************************************/ +static int rk29_vmac_register_set(void) +{ + //config rk29 vmac as rmii, 100MHz + u32 value= readl(RK29_GRF_BASE + 0xbc); + value = (value & 0xfff7ff) | (0x400); + writel(value, RK29_GRF_BASE + 0xbc); + return 0; +} + +static int rk29_rmii_io_init(void) +{ + int err; + + //phy power gpio + err = gpio_request(RK29_PIN6_PB0, "phy_power_en"); + if (err) { + gpio_free(RK29_PIN6_PB0); + printk("-------request RK29_PIN6_PB0 fail--------\n"); + return -1; + } + //phy power down + gpio_direction_output(RK29_PIN6_PB0, GPIO_LOW); + gpio_set_value(RK29_PIN6_PB0, GPIO_LOW); + + return 0; +} + +static int rk29_rmii_io_deinit(void) +{ + //phy power down + gpio_direction_output(RK29_PIN6_PB0, GPIO_LOW); + gpio_set_value(RK29_PIN6_PB0, GPIO_LOW); + //free + gpio_free(RK29_PIN6_PB0); + return 0; +} + +static int rk29_rmii_power_control(int enable) +{ + if (enable) { + //enable phy power + gpio_direction_output(RK29_PIN6_PB0, GPIO_HIGH); + gpio_set_value(RK29_PIN6_PB0, GPIO_HIGH); + } + else { + gpio_direction_output(RK29_PIN6_PB0, GPIO_LOW); + gpio_set_value(RK29_PIN6_PB0, GPIO_LOW); + } + return 0; +} + +struct rk29_vmac_platform_data rk29_vmac_pdata = { + .vmac_register_set = rk29_vmac_register_set, + .rmii_io_init = rk29_rmii_io_init, + .rmii_io_deinit = rk29_rmii_io_deinit, + .rmii_power_control = rk29_rmii_power_control, +}; + +/***************************************************************************************** + * spi devices + * author: cmc@rock-chips.com + *****************************************************************************************/ +#define SPI_CHIPSELECT_NUM 2 +static struct spi_cs_gpio rk29xx_spi0_cs_gpios[SPI_CHIPSELECT_NUM] = { + { + .name = "spi0 cs0", + .cs_gpio = RK29_PIN2_PC1, + .cs_iomux_name = GPIO2C1_SPI0CSN0_NAME, + .cs_iomux_mode = GPIO2H_SPI0_CSN0, + }, + { + .name = "spi0 cs1", + .cs_gpio = RK29_PIN1_PA4, + .cs_iomux_name = GPIO1A4_EMMCWRITEPRT_SPI0CS1_NAME,//if no iomux,set it NULL + .cs_iomux_mode = GPIO1L_SPI0_CSN1, + } +}; + +static struct spi_cs_gpio rk29xx_spi1_cs_gpios[SPI_CHIPSELECT_NUM] = { + { + .name = "spi1 cs0", + .cs_gpio = RK29_PIN2_PC5, + .cs_iomux_name = GPIO2C5_SPI1CSN0_NAME, + .cs_iomux_mode = GPIO2H_SPI1_CSN0, + }, + { + .name = "spi1 cs1", + .cs_gpio = RK29_PIN1_PA3, + .cs_iomux_name = GPIO1A3_EMMCDETECTN_SPI1CS1_NAME,//if no iomux,set it NULL + .cs_iomux_mode = GPIO1L_SPI1_CSN1, + } +}; + +static int spi_io_init(struct spi_cs_gpio *cs_gpios, int cs_num) +{ +#if 1 + int i; + if (cs_gpios) { + for (i=0; inr_banks = 1; + mi->bank[0].start = RK29_SDRAM_PHYS; + mi->bank[0].node = PHYS_TO_NID(RK29_SDRAM_PHYS); + mi->bank[0].size = LINUX_SIZE; +} + +static void __init machine_rk29_mapio(void) +{ + rk29_map_common_io(); + rk29_setup_early_printk(); + rk29_sram_init(); + rk29_clock_init(periph_pll_288mhz); + rk29_iomux_init(); + ddr_init(DDR_TYPE, DDR_FREQ); +} + +MACHINE_START(RK29, "RK29board") + /* UART for LL DEBUG */ + .phys_io = RK29_UART1_PHYS, + .io_pg_offst = ((RK29_UART1_BASE) >> 18) & 0xfffc, + .boot_params = RK29_SDRAM_PHYS + 0x88000, + .fixup = machine_rk29_fixup, + .map_io = machine_rk29_mapio, + .init_irq = machine_rk29_init_irq, + .init_machine = machine_rk29_board_init, + .timer = &rk29_timer, +MACHINE_END diff --git a/arch/arm/mach-rk29/include/mach/board.h b/arch/arm/mach-rk29/include/mach/board.h index ea78e534ec01..02230c5d60ec 100755 --- a/arch/arm/mach-rk29/include/mach/board.h +++ b/arch/arm/mach-rk29/include/mach/board.h @@ -214,6 +214,14 @@ struct it7260_platform_data { void (*exit_platform_hw)(void); }; +struct ft5406_platform_data { + int (*get_pendown_state)(void); + int (*init_platform_hw)(void); + int (*ft5406_platform_sleep)(void); + int (*ft5406_platform_wakeup)(void); + void (*exit_platform_hw)(void); +}; + struct akm8975_platform_data { char layouts[3][3]; char project_name[64]; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9c659b72f389..598ef991253b 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -758,4 +758,13 @@ config TOUCHSCREEN_GT818_IIC config D70_L3188A tristate "D70-L3188A based touchscreens" depends on I2C2_RK29 +config TOUCHSCREEN_FT5406 + tristate "FT5406 based touchscreens: FT5406 Interface" + depends on I2C2_RK29 + help + say Y here if you have a touchscreen interface using the FT5406 + controller,and your board-specific initialization code includes that + in its table of I2C devices. + + If unsure, say N(but it's safe to say "Y"). endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 46ac05c39355..ae6e8fc19f58 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -57,4 +57,5 @@ obj-$(CONFIG_TOUCHSCREEN_GT801_IIC) += gt801_ts.o obj-$(CONFIG_TOUCHSCREEN_GT818_IIC) += gt818_ts.o obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC) += ili2102_ts.o obj-$(CONFIG_D70_L3188A) += goodix_touch.o +obj-$(CONFIG_TOUCHSCREEN_FT5406) += ft5406_ts.o diff --git a/drivers/input/touchscreen/ft5406_ts.c b/drivers/input/touchscreen/ft5406_ts.c new file mode 100755 index 000000000000..d10b744e90f8 --- /dev/null +++ b/drivers/input/touchscreen/ft5406_ts.c @@ -0,0 +1,1039 @@ +/* + * drivers/input/touchscreen/ft5x0x_ts.c + * + * FocalTech ft5x0x TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * note: only support mulititouch Wenfs 2010-10-01 + */ + +#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 +#ifdef CONFIG_ANDROID_POWER +#include +#endif + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include /* ddl@rock-chips.com : camera support */ +#include /* ddl@rock-chips.com : camera support */ +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +//#include +#include "ft5406_ts.h" + + +#ifdef CONFIG_HAS_EARLYSUSPEND +static struct early_suspend ft5406_early_suspend; +#endif + +static struct i2c_client *this_client; + + + +#define CONFIG_FT5X0X_MULTITOUCH 1 + +#define CONFIG_TOUCH_PANEL_KEY 1 //harry 2011.03.15 + +#define M8_TP_KEY 0 // 1 + + +#if 0// M8_TP_KEY +#define HOME_KEY_MIN 260 +#define HOME_KEY_MAX 330 + +#define MENU_KEY_MIN 380 +#define MENU_KEY_MAX 460 + +#define BACK_KEY_MIN 130 +#define BACK_KEY_MAX 210 + +#else +#define HOME_KEY_MIN 115 +#define HOME_KEY_MAX 185 + +#define MENU_KEY_MIN 215 +#define MENU_KEY_MAX 295 + +#define BACK_KEY_MIN 10 +#define BACK_KEY_MAX 85 + + +#endif +#define CONFIG_TOUCH_PANEL_LED 1 + #if CONFIG_TOUCH_PANEL_LED +#define RK29SDK_PANEL_LED_GPIO_SITCH RK29_PIN6_PB4 + #endif + +#define TOUCH_RESET_PIN RK29_PIN6_PC3 + +struct ts_event { + u16 x1; + u16 y1; + u16 x2; + u16 y2; + u16 x3; + u16 y3; + u16 x4; + u16 y4; + u16 x5; + u16 y5; + u16 pressure; + s16 touch_ID1; + s16 touch_ID2; + s16 touch_ID3; + s16 touch_ID4; + s16 touch_ID5; + u8 touch_point; + u8 status; +}; + +struct ft5x0x_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + int irq; + struct ts_event event; + struct work_struct pen_event_work; + struct workqueue_struct *ts_workqueue; +}; + + +//#define FT5X0X_I2C_ADDR 0x70 +#define MAX_POINT 5 +/* +static int ft5x0x_ts_probe(struct i2c_adapter *bus, int address, int kind); +static unsigned short ft5x0x_normal_i2c[] = {FT5X0X_I2C_ADDR>>1, I2C_CLIENT_END}; +static unsigned short ft5x0x_ignore = I2C_CLIENT_END; +static struct i2c_client_address_data ft5x0x_addr_data={ + .normal_i2c = ft5x0x_normal_i2c, + .probe = &ft5x0x_ignore, + .ignore =&ft5x0x_ignore, +}; + +static int ft5x0x_attach_adapter(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &ft5x0x_addr_data, ft5x0x_ts_probe); +} + +static struct i2c_driver ft5x0x_ts_driver = { + .driver = { + .name = FT5X0X_NAME, + .owner = THIS_MODULE, + }, + .id = FT5X0X_I2C_ADDR, + .attach_adapter = &ft5x0x_attach_adapter, +}; + + + +static struct i2c_client ft5x0x_client = { + .driver = &ft5x0x_ts_driver, + .name = "ft5x0x", +}; +*/ +/*read the it7260 register ,used i2c bus*/ + +#define FT5406_IIC_SPEED 200*1000 //300*1000 +static int ft5406_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len) +{ + int ret; + ret = i2c_master_reg8_recv(client, reg, buf, len, FT5406_IIC_SPEED); + return ret; +} + + +/* set the it7260 registe,used i2c bus*/ +static int ft5406_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len) +{ + int ret; + ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5406_IIC_SPEED); + return ret; +} + + + + +/* +static int ft5x0x_i2c_rxdata(u8 reg, u8 rxdata[], int length) +{ + int ret; + struct i2c_msg msg[1]; + + msg->addr = ft5x0x_client.addr; + msg->flags |= I2C_M_RD; + msg->buf = rxdata; + msg->len = length; + + //printk("ft50x0_client.addr = 0x%x\n", ft5x0x_client.addr); + rxdata[0] = reg; + + ret = i2c_transfer(ft5x0x_client.adapter, msg, 1); + if (ret< 0) + { + printk("error at ft5x0x_read_regs !!! \n"); + } + return ret; + +} + +static int ft5x0x_i2c_txdata(u8 reg, u8 txdata[], int length) +{ + int ret; + struct i2c_msg msg[1]; + static u8 i2c_buf[128]; + + msg->addr = ft5x0x_client.addr; + msg->flags = 0; + msg->buf = i2c_buf; + msg->len = length + 1; + + + i2c_buf[0] = reg; + memcpy(&i2c_buf[1], &txdata[0], length); + ret = i2c_transfer(ft5x0x_client.adapter, msg, 1); + if (ret< 0) + { + printk("error at gt800_write_regs !!! \n"); + } + return ret; + +} + +*/ +static void ft5x0x_ts_release(struct ft5x0x_ts_data *data) +{ + //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client); + //struct ts_event *event = &data->event; + +#if CONFIG_FT5X0X_MULTITOUCH // #ifdef + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0); +#else + input_report_abs(data->input_dev, ABS_PRESSURE, 0); + input_report_key(data->input_dev, BTN_TOUCH, 0); +#endif + input_sync(data->input_dev); +} + +static int ft5x0x_read_data(struct ft5x0x_ts_data *data ) +{ + //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client); + struct ts_event *event = &data->event; + u8 start_reg=0x0; + u8 buf[32] = {0}; + int ret = -1; + //int i = 0; + int status = 0; + int cnt = 0; + +#if 0 + start_reg = 0xa6; + ret = ft5x0x_i2c_rxdata(start_reg, buf, 2); + if (ret < 0) { + printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret); + return ret; + } + for (i=0; i<2; i++) { + printk("=========buf[%d] = 0x%x \n", i, buf[i]); + } +#endif + + + start_reg = 0; + + + +#if CONFIG_FT5X0X_MULTITOUCH // #ifdef + if (MAX_POINT == 5) { + ret = ft5406_read_regs(data->client,start_reg, buf, 31); + } else { + ret = ft5406_read_regs(data->client,start_reg, buf, 13); + } +#else + ret = ft5406_read_regs(data->client,start_reg, buf, 7); +#endif + if (ret < 0) { + // printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret); + return ret; + } +#if 0 + for (i=0; i<32; i++) { + printk("buf[%d] = 0x%x \n", i, buf[i]); + } +#endif + + memset(event, 0, sizeof(struct ts_event)); + + if (MAX_POINT == 5) { + event->touch_point = buf[2] & 0x07;// 000 0111 + } else { + event->touch_point = buf[2] & 0x03;// 0000 0011 + } + +// printk("touch_point = %d\n", event->touch_point); + if (event->touch_point == 0) { + // printk("release point !!!!!!!!!!!!!!!!!\n"); + ft5x0x_ts_release(data); + return 1; + } + cnt =0; +#if CONFIG_FT5X0X_MULTITOUCH // #ifdef + switch (event->touch_point) { + if (MAX_POINT == 5) { + case 5: + event->x5 = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c]; + event->y5 = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e]; + status = (s16)((buf[0x1b] & 0xc0) >> 6); + event->touch_ID5=(s16)(buf[0x1D] & 0xF0)>>4; + if(event->x5 > 1024) + cnt ++; + // printk("read ID5 = %d\n",event->touch_ID5,status); + // printk("read status5= %d\n",status); + #if 0 + if (status == 1) { + printk("point 5 release!\n"); + ft5x0x_ts_release(data); + } + #endif + case 4: + event->x4 = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16]; + event->y4 = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18]; + status = (s16)((buf[0x15] & 0xc0) >> 6); + //event->touch_ID4=(s16)(buf[0x17] & 0xF0); + event->touch_ID4=(s16)(buf[0x17] & 0xF0)>>4; + // printk("read ID4 = %d,read status4 = %d\n",event->touch_ID4,status); + #if 0 + if (status == 1) { + printk("point 4 release!\n"); + ft5x0x_ts_release(data); + } + #endif + if(event->x4 >1024) + cnt ++; + case 3: + event->x3 = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10]; + event->y3 = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12]; + status = (s16)((buf[0x0f] & 0xc0) >> 6); + // event->touch_ID3=(s16)(buf[0x11] & 0xF0); + event->touch_ID3=(s16)(buf[0x11] & 0xF0)>>4; + // printk("read ID3 = %d,read status3 = %d\n",event->touch_ID3,status); + #if 0 + if (status == 1) { + printk("point 3 release!\n"); + ft5x0x_ts_release(data); + } + #endif + if(event->x3 > 1024) + cnt ++; + } + case 2: + event->x2 = (s16)(buf[9] & 0x0F)<<8 | (s16)buf[10]; + event->y2 = (s16)(buf[11] & 0x0F)<<8 | (s16)buf[12]; + status = (s16)((buf[0x9] & 0xc0) >> 6); + // event->touch_ID2=(s16)(buf[0x0b] & 0xF0); + event->touch_ID2=(s16)(buf[0x0b] & 0xF0)>>4; + // printk("read ID2 = %d,read status2 = %d\n",event->touch_ID2,status); + #if 0 + if (status == 1) { + printk("point 2 release!\n"); + ft5x0x_ts_release(data); + } + #endif + if(event->x2 > 1024) + cnt ++; + case 1: + event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4]; + event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6]; + status = ((buf[0x3] & 0xc0) >> 6); + event->status= status ; + // event->touch_ID1=(s16)(buf[5] & 0xF0); + event->touch_ID1=(s16)(buf[0x05] & 0xF0)>>4; + //printk("status1= %d\n",event->status); + #if 0 + if (status == 1) { + printk("point 1 release!\n"); + ft5x0x_ts_release(data); + } + #endif + if(event->x1 >1024) + cnt ++; + + break; + default: + return -1; + } + +/* + if((event->touch_point ==1) + &&((event->y1y2>MENU_KEY_MAX))) + { + ft5x0x_ts_release(data); + return 1; + } + + if(((event->touch_point - cnt) ==0)&&(event->touch_point >1)) + { + ft5x0x_ts_release(data); + return 1; + } +*/ +#else + if (event->touch_point == 1) { + event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4]; + event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6]; + } +#endif + event->pressure =200; //200; + + // printk("status2= %d\n",event->status); + + return 0; +} + +static void ft5x0x_report_value(struct ft5x0x_ts_data *data ) +{ + //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client); + struct ts_event *event = &data->event; + + #if CONFIG_TOUCH_PANEL_KEY + u8 key_flag=0; + // static u16 point_data=0; + #endif + + +#if CONFIG_FT5X0X_MULTITOUCH //#ifdef + switch(event->touch_point) { + if (MAX_POINT == 5){ + case 5: + + if(event->x5 <= 1024) + { + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID5); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x5); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y5); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + } + // printk("===x5 = %d,y5 = %d ====\n",event->x5,event->y5); + case 4: + if(event->x4 <= 1024) + { + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID4); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x4); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y4); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + } + // printk("===x4 = %d,y4 = %d ====\n",event->x4, event->y4); + case 3: + if(event->x3 <= 1024) + { + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID3); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x3); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y3); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + } + // printk("===x3 = %d,y3 = %d ====\n",event->x3, event->y3); + } + case 2: + if(event->x2 <= 1024) + { + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID2); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x2); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y2); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + } + // printk("===x2 = %d,y2 = %d ====\n",event->x2,event->y2); + case 1: +#if CONFIG_TOUCH_PANEL_KEY + if(event->status==0) + { + key_flag=1; + } + + if(event->x1 >1024) + { + // printk("point 1 key1\n"); + // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1); + if(key_flag) + { + if((event->y1>BACK_KEY_MIN)&&(event->y1input_dev,KEY_BACK,1); //158 //MENU + input_sync(data->input_dev); + input_report_key(data->input_dev,KEY_BACK,0); //158 //MENU + input_sync(data->input_dev); +#if CONFIG_TOUCH_PANEL_LED //#ifdef + // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){ + // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH); + // printk("panel Key LED error\n"); + // return -EIO; + // } + gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0); + gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH); +#endif + // printk("point 1 key2\n"); + } + else if((event->y1>HOME_KEY_MIN)&&(event->y1input_dev,KEY_HOME,1); //102 //Home + input_sync(data->input_dev); + input_report_key(data->input_dev,KEY_HOME,0); //102 //Home + input_sync(data->input_dev); +#if CONFIG_TOUCH_PANEL_LED // #ifdef + // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){ + // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH); + // printk("panel Key LED error\n"); + // return -EIO; + // } + gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0); + gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH); +#endif + // printk("point 1 key3\n"); + } + else if((event->y1>MENU_KEY_MIN)&&(event->y1input_dev,KEY_MENU,1); //59 //esc + input_sync(data->input_dev); + input_report_key(data->input_dev,KEY_MENU,0); //59 //esc + input_sync(data->input_dev); +#if CONFIG_TOUCH_PANEL_LED // #ifdef + // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){ + // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH); + // printk("panel Key LED error\n"); + // return -EIO; + // } + gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0); + gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH); +#endif + // printk("point 1 key4\n"); + } + else + { + ft5x0x_ts_release(data); + } + + } + else + { + ft5x0x_ts_release(data); + } + + } + else + { + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID1); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1); + } +#else + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID1); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1); + input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1); +#endif + default: + // printk("==touch_point default =\n"); + // printk("read status0= %d\n",event->status); + // if (event->status== 1) { + // printk("point 0 release!\n"); + // ft5x0x_ts_release(data); + // } +#if CONFIG_TOUCH_PANEL_KEY + key_flag=0; +#endif + break; + } +#else /* CONFIG_FT5X0X_MULTITOUCH*/ + if (event->touch_point == 1) { + input_report_abs(data->input_dev, ABS_X, event->x1); + input_report_abs(data->input_dev, ABS_Y, event->y1); + input_report_abs(data->input_dev, ABS_PRESSURE, event->pressure); + } + input_report_key(data->input_dev, BTN_TOUCH, 1); +#endif /* CONFIG_FT5X0X_MULTITOUCH*/ + input_sync(data->input_dev); + + // printk("status3= %d\n",event->status); + + +} /*end ft5x0x_report_value*/ + +static void ft5x0x_ts_pen_irq_work(struct work_struct *work) +{ + int ret = -1; +// printk("==work 1=\n"); + + struct ft5x0x_ts_data *ft5x0x_ts = + container_of(work, struct ft5x0x_ts_data, pen_event_work); + + + ret = ft5x0x_read_data(ft5x0x_ts); + if (ret == 0) { + ft5x0x_report_value(ft5x0x_ts); + // printk("==work 2=\n"); + } +// else printk("data package read error\n"); +// printk("==work 2=\n"); +// msleep(1); + enable_irq(ft5x0x_ts->irq); + //enable_irq(7); +// gpio_irq_enable(TOUCH_INT_IOPIN); +} + +static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) +{ + + struct ft5x0x_ts_data *ft5x0x_ts = dev_id; + + //printk("ft5x0x_ts irq =%d",ft5x0x_ts->irq); + + disable_irq_nosync(ft5x0x_ts->irq); + // disable_irq(ft5x0x_ts->irq); +// disable_irq(7); + //gpio_irq_disable(ft5x0x_ts->irq); + + if (!work_pending(&ft5x0x_ts->pen_event_work)) + { + queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); + // printk("ft5x0x_ts_work!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + return IRQ_HANDLED; +} + + +static int __devexit ft5406_remove(struct i2c_client *client) +{ + struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client); + + // printk("==ft5x0x_ts_remove=\n"); + +// free_irq(client->irq, ft5x0x_ts); +// free_irq(7, ft5x0x_ts); + free_irq(ft5x0x_ts->irq, ft5x0x_ts); + + input_unregister_device(ft5x0x_ts->input_dev); + kfree(ft5x0x_ts); + cancel_work_sync(&ft5x0x_ts->pen_event_work); + destroy_workqueue(ft5x0x_ts->ts_workqueue); + i2c_set_clientdata(client, NULL); +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ft5406_early_suspend); +#endif + this_client = NULL; + + return 0; +} + + +#ifdef CONFIG_HAS_EARLYSUSPEND +static int ft5x0x_ts_suspend(struct early_suspend *h) +{ + +u8 buf[1]; +//u8 buf_r[1]; +int read_data=5; +int err = 0; + +// printk("==ft5x0x_ts_suspend=\n"); + + +// struct ft5x0x_ts_data *ts; +// ts = container_of(handler, struct ft5x0x_ts_data, early_suspend); + #if 0 + struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client); + if (device_may_wakeup(&client->dev)) + enable_irq_wake(ft5x0x_ts->irq); + #endif +// disable_irq(ft5x0x_client->irq); +// cancel_work_sync(&ts->pen_event_work); +// flush_workqueue(ts->ts_workqueue); +// ==set mode ==, + disable_irq(102); + #if 1 + buf[0]=PMODE_HIBERNATE; + while(read_data) + { + err=ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1); + // printk("==ft5406 suspend write 111=%d\n",buf[0]); + if(err==1) + { + read_data=0; + } + else + { + read_data--; + // printk("==ft5406 suspend write222=%d\n",buf[0]); + ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1); + } + } + + // printk("==ft5406 suspend write=%d\n",buf[0]); + // printk("==ft5406 suspend write err=%d\n",err); + // msleep(50); //harry 2011.04.20 + // err = ft5406_read_regs(this_client,FT5X0X_REG_PMODE,buf_r,1); + // printk("==ft5406 suspend read=%d\n",buf_r[0]); + // printk("==ft5406 suspend read err=%d\n",err); + + #endif + + #if CONFIG_TOUCH_PANEL_LED + // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){ + // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH); + // printk("panel Key LED error\n"); + // return -EIO; + // } + gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0); + gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_LOW); + // printk("suspend led 2\n"); + #endif + + return 0; + +} + +static int ft5x0x_ts_resume(struct early_suspend *h) +{ + //printk("==ft5x0x_ts_resume=\n"); + #if 0 + struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client); + if (device_may_wakeup(&client->dev)) + disable_irq_wake(ft5x0x_ts->irq); + #endif + // wake the mode +// __gpio_as_output(GPIO_FT5X0X_WAKE); +// __gpio_clear_pin(GPIO_FT5X0X_WAKE); //set wake = 0,base on system +// msleep(100); +// __gpio_set_pin(GPIO_FT5X0X_WAKE); //set wake = 1,base on system +// msleep(100); +// enable_irq(IRQ_EINT(6)); + enable_irq(102); + #if 1 + gpio_direction_output(TOUCH_RESET_PIN, 0); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + msleep(20); //harry 2011.04.20 + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + #endif + + return 0; +} +#endif + +static int ft5406_probe(struct i2c_client *client ,const struct i2c_device_id *id) +{ + struct ft5x0x_ts_data *ft5x0x_ts; + struct input_dev *input_dev; + struct ft5406_platform_data *pdata = pdata = client->dev.platform_data; + + int err = 0; + int ret = 0; + u8 buf_w[1]; + u8 buf_r[1]; + + //printk("==ft5x0x_ts_probe=\n"); + + if (!pdata) { + dev_err(&client->dev, "platform data is required!\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EIO; + + + ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL); + if (!ft5x0x_ts) { + err = -ENOMEM; + goto exit_alloc_data_failed; + } +/* + ft5x0x_client.adapter = bus; + ft5x0x_client.addr= address; + ft5x0x_client.mode = NORMALMODE; //NORMALNOSTOPMODE;// DIRECTMODE; + ft5x0x_client.Channel = I2C_CH0; + ft5x0x_client.speed = 300; + ft5x0x_client.addressBit=I2C_7BIT_ADDRESS_8BIT_REG; + ft5x0x_ts->client=&ft5x0x_client; + + i2c_set_clientdata(&ft5x0x_client, ft5x0x_ts); + + err = i2c_attach_client(&ft5x0x_client); + if (err < 0) + { + printk("ft5x0x attach client failed!!!!\n"); + goto exit_alloc_data_failed; + } + + INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work); + ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts"); + if (!ft5x0x_ts->ts_workqueue) { + err = -ESRCH; + goto exit_create_singlethread; + } + + rockchip_mux_api_set(TOUCH_INT_IOMUX_PINNAME,TOUCH_INT_IOMUX_PINDIR); + GPIOSetPinDirection(TOUCH_INT_IOPIN, GPIO_IN); + GPIOPullUpDown(TOUCH_INT_IOPIN, GPIOPullUp); + err = request_gpio_irq(TOUCH_INT_IOPIN, ft5x0x_ts_interrupt, GPIOEdgelFalling, ft5x0x_ts); + if(err < 0) + { + printk("ft5x0x_probe: request irq failed\n"); + goto exit_irq_request_failed; + } +*/ + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + printk("failed to allocate input device\n"); + goto exit_input_dev_alloc_failed; + } + + this_client = client; + ft5x0x_ts->client = client; + ft5x0x_ts->irq = client->irq; + ft5x0x_ts->input_dev = input_dev; + + #if CONFIG_FT5X0X_MULTITOUCH //#ifdef + set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit); + set_bit(ABS_MT_POSITION_X, input_dev->absbit); + set_bit(ABS_MT_POSITION_Y, input_dev->absbit); + set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit); + + //input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN); //harry 03.21 + #if CONFIG_TOUCH_PANEL_KEY + set_bit(KEY_HOME, input_dev->keybit); + set_bit(KEY_MENU, input_dev->keybit); + set_bit(KEY_BACK, input_dev->keybit); + #endif + + input_set_abs_params(input_dev, + ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(input_dev, + ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); + input_set_abs_params(input_dev, + ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0); + input_set_abs_params(input_dev, + ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0); +#else + set_bit(ABS_X, input_dev->absbit); + set_bit(ABS_Y, input_dev->absbit); + set_bit(ABS_PRESSURE, input_dev->absbit); + set_bit(BTN_TOUCH, input_dev->keybit); + + input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0); + input_set_abs_params(input_dev, + ABS_PRESSURE, 0, PRESS_MAX, 0 , 0); +#endif + + + set_bit(EV_ABS, input_dev->evbit); + set_bit(EV_KEY, input_dev->evbit); + + #if CONFIG_TOUCH_PANEL_KEY + set_bit(EV_SYN, input_dev->evbit); //harry 03.21 + #endif + + input_dev->name = FT5X0X_NAME; //dev_name(&client->dev) + err = input_register_device(input_dev); + if (err) { + // printk("ft5x0x_ts_probe: failed to register input device: \n"); + goto exit_input_register_device_failed; + } + +// printk("==probe over =\n"); + if (pdata->init_platform_hw) + pdata->init_platform_hw(); + + if (!ft5x0x_ts->irq) { + dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n"); + return -ENODEV; + }else{ + ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq); + } + +//printk("ft5x0x_ts irq =%d", ft5x0x_ts->irq); + + + INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work); + ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts"); + if (!ft5x0x_ts->ts_workqueue) { + err = -ESRCH; + goto exit_create_singlethread; + } + + + + //printk("client->dev.driver->name %s ,%d \n",client->dev.driver->name,ft5x0x_ts->irq); + + + ret = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, /*IRQF_TRIGGER_LOW*/IRQF_TRIGGER_FALLING, //IRQF_DISABLED|IRQF_TRIGGER_FALLING, + client->dev.driver->name, ft5x0x_ts); + + if (ret < 0) { + dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq); + goto fail3; + } + //harry 03.23 + #if 0 + ret = input_register_device(input_dev); + if(ret<0) + { + // printk("ft5406 register input device failed!!!!\n"); + goto exit_irq_request_failed; + } + #endif + +#ifdef CONFIG_HAS_EARLYSUSPEND + ft5406_early_suspend.suspend =ft5x0x_ts_suspend; + ft5406_early_suspend.resume =ft5x0x_ts_resume; + ft5406_early_suspend.level = 0x2; + register_early_suspend(&ft5406_early_suspend); +#endif + + //buf_w[0] = 6; //harry 04.07 + buf_w[0] = 6; + + err = ft5406_set_regs(client,0x88,buf_w,1); + //ft5x0x_i2c_txdata(0x88, buf_w, 1); /* adjust frequency 60Hz */ + + buf_r[0] = 0; + err = ft5406_read_regs(client,0x88,buf_r,1); + //ft5x0x_i2c_rxdata(0x88, buf_r, 1); +// printk("read buf[0x88] = %d\n", buf_r[0]); + + return 0; +fail3: + free_irq(ft5x0x_ts->irq,ft5x0x_ts); + i2c_set_clientdata(client, NULL); //harry + destroy_workqueue(ft5x0x_ts->ts_workqueue); //harry +exit_input_register_device_failed: + input_free_device(input_dev); +// i2c_set_clientdata(client, NULL); +// kfree(ft5x0x_ts); + +exit_input_dev_alloc_failed: +// free_irq(7, ft5x0x_ts); + free_irq(ft5x0x_ts->irq, ft5x0x_ts); +exit_irq_request_failed: +exit_platform_data_null: + cancel_work_sync(&ft5x0x_ts->pen_event_work); + destroy_workqueue(ft5x0x_ts->ts_workqueue); +exit_create_singlethread: + printk("==singlethread error =\n"); + kfree(ft5x0x_ts); +exit_alloc_data_failed: + return err; +} + + + +static struct i2c_device_id ft5406_idtable[] = { + { FT5X0X_NAME, 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, ft5406_idtable); + +static struct i2c_driver ft5406_driver = { + .driver = { + .owner = THIS_MODULE, + .name = FT5X0X_NAME + }, + .id_table = ft5406_idtable, + .probe = ft5406_probe, +#ifndef CONFIG_HAS_EARLYSUSPEND + .suspend = ft5x0x_ts_suspend, + .resume = ft5x0x_ts_resume, +#endif + .remove = __devexit_p(ft5406_remove), +}; + +static int __init ft5x0x_ts_init(void) +{ + return i2c_add_driver(&ft5406_driver); +} + +static void __exit ft5x0x_ts_exit(void) +{ + i2c_del_driver(&ft5406_driver); +} + +module_init(ft5x0x_ts_init); +module_exit(ft5x0x_ts_exit); + +MODULE_AUTHOR(""); +MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver"); + diff --git a/drivers/input/touchscreen/ft5406_ts.h b/drivers/input/touchscreen/ft5406_ts.h new file mode 100755 index 000000000000..c9435c5846fc --- /dev/null +++ b/drivers/input/touchscreen/ft5406_ts.h @@ -0,0 +1,41 @@ +#ifndef __LINUX_FT5X0X_TS_H__ +#define __LINUX_FT5X0X_TS_H__ + +#define SCREEN_MAX_X 1024 //800 +#define SCREEN_MAX_Y 768 //480 +#define PRESS_MAX 255 + +#define FT5X0X_NAME "ft5x0x_ts"//"synaptics_i2c_rmi"//"synaptics-rmi-ts"// + +struct ft5x0x_ts_platform_data{ + u16 intr; /* irq number */ +}; + +enum ft5x0x_ts_regs { + FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode */ +}; + +//FT5X0X_REG_PMODE +#define PMODE_ACTIVE 0x00 +#define PMODE_MONITOR 0x01 +#define PMODE_STANDBY 0x02 +#define PMODE_HIBERNATE 0x03 + + + #ifndef ABS_MT_TOUCH_MAJOR + #define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */ + #define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */ + #define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */ + #define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */ + #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ + #define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */ + #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ + #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ + #define ABS_MT_BLOB_ID 0x38 /* Group set of pkts as blob */ + #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ + + #endif /* ABS_MT_TOUCH_MAJOR */ + + +#endif + diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3c6c44b138ac..f555e68d602c 100755 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -155,6 +155,13 @@ config RTC_HYM8563 This driver can also be built as a module. If so, the module will be called rtc-HYM8563. +config RTC_DRV_M41T66 + tristate "ST M41T66" + help + If you say Y here you will get support for the ST M41T66. + This driver can also be built as a module. If so, the module + will be called rtc-m41t80. + config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 984c79a95049..cacd3255468c 100755 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -90,3 +90,5 @@ obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_HYM8563) += rtc-HYM8563.o +obj-$(CONFIG_RTC_DRV_M41T66) += rtc-m41t66.o + diff --git a/drivers/rtc/rtc-m41t66.c b/drivers/rtc/rtc-m41t66.c new file mode 100755 index 000000000000..2e1b4b6a4c29 --- /dev/null +++ b/drivers/rtc/rtc-m41t66.c @@ -0,0 +1,813 @@ +/* + * I2C client/driver for the ST M41T62 family of i2c rtc chips. + * + * Author: lhh + *Port to rk29 by yxj + * + * Based on m41t00.c by Mark A. Greer + * + * 2010 (c) rockchip + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + + + + +#define M41T62_REG_SSEC 0 +#define M41T62_REG_SEC 1 +#define M41T62_REG_MIN 2 +#define M41T62_REG_HOUR 3 +#define M41T62_REG_SQWDAY 4 +#define M41T62_REG_DAY 5 +#define M41T62_REG_MON 6 +#define M41T62_REG_YEAR 7 +#define M41T62_REG_ALARM_MON 0xa +#define M41T62_REG_ALARM_DAY 0xb +#define M41T62_REG_ALARM_HOUR 0xc +#define M41T62_REG_ALARM_MIN 0xd +#define M41T62_REG_ALARM_SEC 0xe +#define M41T62_REG_FLAGS 0xf +#define M41T62_REG_SQW 0x13 + +#define M41T62_REG_SEC_INDEX (M41T62_REG_SEC - 1) +#define M41T62_REG_MIN_INDEX (M41T62_REG_MIN - 1) +#define M41T62_REG_HOUR_INDEX (M41T62_REG_HOUR - 1) +#define M41T62_REG_SQWDAY_INDEX (M41T62_REG_SQWDAY - 1) +#define M41T62_REG_DAY_INDEX (M41T62_REG_DAY - 1) +#define M41T62_REG_MON_INDEX (M41T62_REG_MON - 1) +#define M41T62_REG_YEAR_INDEX (M41T62_REG_YEAR - 1) + +#define M41T62_DATETIME_REG_SIZE (M41T62_REG_YEAR ) + +#define M41T62_REG_ALARM_MON_INDEX (M41T62_REG_ALARM_MON-0x0a) +#define M41T62_REG_ALARM_DAY_INDEX (M41T62_REG_ALARM_DAY-0x0a) +#define M41T62_REG_ALARM_HOUR_INDEX (M41T62_REG_ALARM_HOUR-0x0a) +#define M41T62_REG_ALARM_MIN_INDEX (M41T62_REG_ALARM_MIN-0x0a) +#define M41T62_REG_ALARM_SEC_INDEX (M41T62_REG_ALARM_SEC-0x0a) +#define M41T62_REG_FLAGS_INDEX (M41T62_REG_FLAGS-0x0a) + + +#define M41T62_ALARM_REG_SIZE \ + (M41T62_REG_FLAGS + 1 - M41T62_REG_ALARM_MON) + + +#define M41T62_SEC_ST (1 << 7) /* ST: Stop Bit */ +#define M41T62_ALMON_AFE (1 << 7) /* AFE: alarm flag Enable Bit */ +#define M41T62_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */ +//#define M41T62_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */ +#define M41T62_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */ +//#define M41T62_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */ +#define M41T62_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */ +#define M41T62_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */ +#define M41T62_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */ + +//#define M41T62_FEATURE_HT (1 << 0) /* Halt feature */ +//#define M41T62_FEATURE_BL (1 << 1) /* Battery low indicator */ +//#define M41T62_FEATURE_SQ (1 << 2) /* Squarewave feature */ +//#define M41T62_FEATURE_WD (1 << 3) /* Extra watchdog resolution */ +//#define M41T62_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */ + +#define REPEAT_SEC 5 +#define REPEAT_MIN 4 +#define REPEAT_HOUR 3 +#define REPEAT_DAY 2 +#define REPEAT_MON 1 +#define REPEAT_YEAR 0 +#define RTC_SPEED 100 * 1000 + + + +#define DRV_VERSION "0.05" +#define DRV_NAME "rtc-M41T62" +#if 0 +#define DBG(x...) printk(KERN_INFO "rtc-M41T62:" x) +#else +#define DBG(x...) +#endif + +//static struct semaphore rtc_sem;//Ryan + + +struct rock_rtc { + int irq; + struct i2c_client *client; + struct work_struct work; + struct mutex mutex; + struct rtc_device *rtc; + int exiting; + struct rtc_wkalrm alarm; + struct wake_lock wake_lock; +}; + + +static int rtc_alarm_repeat_set(int mod) +{ + return 0; +} + + +static irqreturn_t rtc_wakeup_irq(int irq, void *dev_id) +{ + struct rock_rtc *rk_rtc = (struct rock_rtc *)dev_id; + DBG("enter %s\n",__func__); + disable_irq_nosync(irq); + schedule_work(&rk_rtc->work); + return IRQ_HANDLED; +} + + +static int m41t62_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len) +{ + int ret; + + + ret = i2c_master_reg8_recv(client, reg, buf, len, RTC_SPEED); + if(ret < 0 ) + { + printk("%s:rtc m41t62 read reg error\n\n\n",__func__); + } + + return ret; +} + +static int m41t62_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len) +{ + int ret; + ret = i2c_master_reg8_send(client, reg, buf, (int)len, RTC_SPEED); + if(ret < 0) + { + printk("%s error>>>>>\n",__func__); + } + return ret; +} + +static int m41t62_init_device(struct i2c_client *client) +{ + //DBG("%s\n",__func__); + + u8 alarmbuf[M41T62_ALARM_REG_SIZE]; + u8 sqwdayreg; + + //read alarm register current value + m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmbuf,M41T62_ALARM_REG_SIZE); + + + /*DBG("init alarm mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n", + alarmbuf[M41T62_REG_ALARM_MON_INDEX], + alarmbuf[M41T62_REG_ALARM_DAY_INDEX], + alarmbuf[M41T62_REG_ALARM_HOUR_INDEX], + alarmbuf[M41T62_REG_ALARM_MIN_INDEX], + alarmbuf[M41T62_REG_ALARM_SEC_INDEX], + alarmbuf[M41T62_REG_FLAGS_INDEX]);*/ + + //clear alarm register + alarmbuf[M41T62_REG_ALARM_MON_INDEX] &= ~(0x1f | M41T62_ALMON_AFE); + alarmbuf[M41T62_REG_ALARM_DAY_INDEX] = 0; + alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] = 0; + alarmbuf[M41T62_REG_ALARM_MIN_INDEX] = 0; + alarmbuf[M41T62_REG_ALARM_SEC_INDEX] = 0; + alarmbuf[M41T62_REG_FLAGS_INDEX] = 0; + + //write alarm register + m41t62_i2c_set_regs(client,M41T62_REG_ALARM_MON,alarmbuf,M41T62_ALARM_REG_SIZE); + + //set outclk to 32768HZ + m41t62_i2c_read_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1); + sqwdayreg =(sqwdayreg|0x10)&0x1f; + m41t62_i2c_set_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1); + //m41t62_i2c_read_regs(client,M41T62_REG_SQWDAY,&sqwdayreg,1); + //printk("sqwdayreg:0x%x\n",sqwdayreg); + #if 0 + sqwdayreg =0; + m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&sqwdayreg,1); //YLZ++ + + printk("%s:rtc m41t2 flag_reg = 0x%x\n",__func__,sqwdayreg); + // if(sqwdayreg & 0x04) + { + + m41t62_i2c_read_regs(client,M41T62_REG_SEC,&sqwdayreg,1); //YLZ++ + printk("%s:rtc m41t2 sec_reg = 0x%x\n",__func__,sqwdayreg); + sqwdayreg |= 0x80; + m41t62_i2c_set_regs(client,M41T62_REG_SEC,&sqwdayreg,1); + sqwdayreg =0x7f; + m41t62_i2c_set_regs(client,M41T62_REG_SEC,&sqwdayreg,1); + m41t62_i2c_read_regs(client,M41T62_REG_SEC,&sqwdayreg,1); //YLZ++ + printk("%s:rtc m41t2 sec_reg = 0x%x\n",__func__,sqwdayreg); + + + } + sqwdayreg =0; + m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&sqwdayreg,1); //YLZ++ + printk("%s:rtc m41t2 atfer flag_reg = 0x%x\n",__func__,sqwdayreg); + #endif + + return 0; +} + +static int m41t62_get_datetime(struct i2c_client *client, + struct rtc_time *tm) +{ + + + struct rock_rtc *rk_rtc = i2c_get_clientdata(client); + u8 datetime[M41T62_DATETIME_REG_SIZE]; + int ret = 0; + + mutex_lock(&rk_rtc->mutex); + ret = m41t62_i2c_read_regs(client,M41T62_REG_SEC,datetime,M41T62_DATETIME_REG_SIZE); + if(ret < 0) + { + printk("%s:read date time from rtc m41t2 error\n",__func__); + } + else + { + ret = 0; + } + mutex_unlock(&rk_rtc->mutex); + /*DBG("-------M41T62_REG_SEC=%x--",datetime[M41T62_REG_SEC_INDEX]); + DBG("-------M41T62_REG_MIN=%x--",datetime[M41T62_REG_MIN_INDEX]); + DBG("-------M41T62_REG_HOUR=%x--",datetime[M41T62_REG_HOUR_INDEX]); + DBG("-------M41T62_REG_SQWDAY=%x--",datetime[M41T62_REG_SQWDAY_INDEX]); + DBG("-------M41T62_REG_DAY=%x--",datetime[M41T62_REG_DAY_INDEX]); + DBG("-------M41T62_REG_MON=%x--",datetime[M41T62_REG_MON_INDEX]); + DBG("-------M41T62_REG_YEAR=%x--",datetime[M41T62_REG_YEAR_INDEX]);*/ + + tm->tm_sec = bcd2bin(datetime[M41T62_REG_SEC_INDEX]& 0x7f); + tm->tm_min = bcd2bin(datetime[M41T62_REG_MIN_INDEX] & 0x7f); + tm->tm_hour = bcd2bin(datetime[M41T62_REG_HOUR_INDEX] & 0x3f); + tm->tm_mday = bcd2bin(datetime[M41T62_REG_DAY_INDEX] & 0x3f); + tm->tm_wday = bcd2bin(datetime[M41T62_REG_SQWDAY_INDEX] & 0x07); + tm->tm_mon = bcd2bin(datetime[M41T62_REG_MON_INDEX] & 0x1f) - 1; + // assume 20YY not 19YY, and ignore the Century Bit + tm->tm_year = bcd2bin(datetime[M41T62_REG_YEAR_INDEX]) + 100; + DBG("%s>>>>%4d-%02d-%02d>>wday:%d>>%02d:%02d:%02d>>\n", + __func__,tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_wday, + tm->tm_hour,tm->tm_min,tm->tm_sec); + + if(tm->tm_year < 100) + { + printk(KERN_INFO "%s:the time read from the rtc M41T62 is illegal ,\ + we will use the default time:2010.8.2\n",__func__); + tm->tm_sec = 1; + tm->tm_min = 7; + tm->tm_hour = 7; + tm->tm_mday = 2; + tm->tm_wday = 4; + tm->tm_mon = 7; + tm->tm_year = 110; + } + + + return ret; +} + +/* Sets the given date and time to the real time clock. */ +static int m41t62_set_datetime(struct i2c_client *client, struct rtc_time *tm) +{ + + struct rock_rtc *rk_rtc = i2c_get_clientdata(client); + int ret = 0; + u8 datetime[M41T62_DATETIME_REG_SIZE]; + + datetime[M41T62_REG_SEC_INDEX] = bin2bcd(tm->tm_sec); + datetime[M41T62_REG_MIN_INDEX] = bin2bcd(tm->tm_min); + datetime[M41T62_REG_HOUR_INDEX] =bin2bcd(tm->tm_hour) ; + datetime[M41T62_REG_SQWDAY_INDEX] =(tm->tm_wday & 0x07) |0x10; + datetime[M41T62_REG_DAY_INDEX] = bin2bcd(tm->tm_mday); + datetime[M41T62_REG_MON_INDEX] = bin2bcd(tm->tm_mon + 1) ; + /* assume 20YY not 19YY */ + datetime[M41T62_REG_YEAR_INDEX] = bin2bcd(tm->tm_year % 100); + printk(KERN_INFO "%s:set time %4d-%02d-%02d %02d:%02d:%02d to rtc \n",__func__, + tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); + + mutex_lock(&rk_rtc->mutex); + ret = m41t62_i2c_set_regs(client,M41T62_REG_SEC,datetime, M41T62_DATETIME_REG_SIZE); + if(ret < 0) + { + printk(KERN_INFO "%s:set time to rtc m41t62 error\n",__func__); + } + else + { + ret = 0; + } + + mutex_unlock(&rk_rtc->mutex); + + return ret; +} + +static int m41t62_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + //DBG("%s>>>>>>>>>>>\n",__func__); + return m41t62_get_datetime(to_i2c_client(dev), tm); +} + +static int m41t62_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + //DBG("%s\n",__func__); + return m41t62_set_datetime(to_i2c_client(dev), tm); +} + +#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) +static int m41t62_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + int rc; + struct i2c_client *client = to_i2c_client(dev); + + DBG("%s>>>>>>>>>%d\n",__func__ ,cmd); + switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: + break; + default: + DBG("RTC func m41t62_rtc_ioctl -ENOIOCTLCMD\n"); + return -ENOIOCTLCMD; + } + DBG("RTC func m41t62_rtc_ioctl 1\n"); + rc = i2c_smbus_read_byte_data(client, M41T62_REG_ALARM_MON); + if (rc < 0) + goto err; + switch (cmd) { + case RTC_AIE_OFF: + rc &= ~M41T62_ALMON_AFE; + break; + case RTC_AIE_ON: + rc |= M41T62_ALMON_AFE; + break; + } + DBG("\n@@@@@@@@@@@RTC func m41t62_rtc_ioctl 2@@@@@@@@@@@@@\n"); + if (i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON, rc) < 0) + goto err; + DBG("\n@@@@@@@@@@@RTC func m41t62_rtc_ioctl 3@@@@@@@@@@@@@\n"); + return 0; +err: + return -EIO; +} +#else +#define m41t62_rtc_ioctl NULL +#endif + +static int m41t62_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + //DBG("%s>>>>>>>>>>>>\n",__func__); + struct i2c_client *client = to_i2c_client(dev); + struct rock_rtc *rk_rtc = i2c_get_clientdata(client); + struct rtc_time current_time ; + u8 alarmbuf[M41T62_ALARM_REG_SIZE]; + int ret = 0; + + + + mutex_lock(&rk_rtc->mutex); + //read the current value of alarm register + m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmbuf, M41T62_ALARM_REG_SIZE); + mutex_unlock(&rk_rtc->mutex); + + //clear alarm register + alarmbuf[M41T62_REG_ALARM_MON_INDEX] &= ~(0x1f | M41T62_ALMON_AFE); + alarmbuf[M41T62_REG_ALARM_DAY_INDEX] = 0; + alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] &= ~(0x3f | 0x80); + alarmbuf[M41T62_REG_ALARM_MIN_INDEX] = 0; + alarmbuf[M41T62_REG_ALARM_SEC_INDEX] = 0; + + + rk_rtc->alarm = *alarm; + DBG("time write to alarm :%4d-%02d-%02d %02d:%02d:%02d>>enable:%d\n", + alarm->time.tm_year+1900, + alarm->time.tm_mon, + alarm->time.tm_mday, + alarm->time.tm_hour, + alarm->time.tm_min, + alarm->time.tm_sec, + alarm->enabled); + //get current time + m41t62_get_datetime(client,¤t_time); + DBG("current time :%4d-%02d-%02d %02d:%02d:%02d>>\n", + current_time.tm_year+1900, + current_time.tm_mon, + current_time.tm_mday, + current_time.tm_hour, + current_time.tm_min, + current_time.tm_sec); + + /* offset into rtc's regs */ + alarmbuf[M41T62_REG_ALARM_SEC_INDEX] |= alarm->time.tm_sec >= 0 ?bin2bcd(alarm->time.tm_sec) : 0x80; + alarmbuf[M41T62_REG_ALARM_MIN_INDEX] |= alarm->time.tm_min >= 0 ?bin2bcd(alarm->time.tm_min) : 0x80; + alarmbuf[M41T62_REG_ALARM_HOUR_INDEX] |= alarm->time.tm_hour >= 0 ?bin2bcd(alarm->time.tm_hour) : 0x80; + alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= alarm->time.tm_mday >= 0 ?bin2bcd(alarm->time.tm_mday) : 0x80; + if (alarm->time.tm_mon >= 0) + alarmbuf[M41T62_REG_ALARM_MON_INDEX] |= bin2bcd(alarm->time.tm_mon + 1); + else + alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= 0x40; + + //Ryan@... + //DBG("enable mon day"); + alarmbuf[M41T62_REG_ALARM_MON_INDEX] |= M41T62_ALMON_AFE ; + alarmbuf[M41T62_REG_ALARM_DAY_INDEX] |= 0xc0;//mon, day repeat + //reg[M41T62_REG_ALARM_HOUR] |= 0x80;//hour repeat + //reg[M41T62_REG_ALARM_MIN] |= 0x80;//min repeat + + + + + //write alarm register + mutex_lock(&rk_rtc->mutex); + ret = m41t62_i2c_set_regs(client,M41T62_REG_ALARM_MON,alarmbuf, M41T62_DATETIME_REG_SIZE); + if(ret < 0) + { + printk(KERN_INFO "%s:set rtc m41t62 alarm error\n",__func__); + } + else + { + ret = 0; + } + + + mutex_unlock(&rk_rtc->mutex); + return ret; + +} + +static int m41t62_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) +{ + //DBG("%s>>>>>>>>>>>>>\n",__func__); + + struct i2c_client *client = to_i2c_client(dev); + struct rock_rtc *rk_rtc = i2c_get_clientdata(client); + u8 alarmreg[M41T62_ALARM_REG_SIZE ]; // all alarm regs and flags + int ret = 0; + + + mutex_lock(&rk_rtc->mutex); + m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmreg, M41T62_ALARM_REG_SIZE); + mutex_unlock(&rk_rtc->mutex); + + //printk("read alarm mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n", + // reg[M41T62_REG_ALARM_MON], + // reg[M41T62_REG_ALARM_DAY], + // reg[M41T62_REG_ALARM_HOUR], + // reg[M41T62_REG_ALARM_MIN], + // reg[M41T62_REG_ALARM_SEC], + // reg[M41T62_REG_FLAGS]); + t->time.tm_sec = -1; + t->time.tm_min = -1; + t->time.tm_hour = -1; + t->time.tm_mday = -1; + t->time.tm_mon = -1; + if (!(alarmreg[M41T62_REG_ALARM_SEC_INDEX] & 0x80)) + t->time.tm_sec = bcd2bin(alarmreg[M41T62_REG_ALARM_SEC_INDEX] & 0x7f); + if (!(alarmreg[M41T62_REG_ALARM_MIN_INDEX] & 0x80)) + t->time.tm_min = bcd2bin(alarmreg[M41T62_REG_ALARM_MIN_INDEX] & 0x7f); + if (!(alarmreg[M41T62_REG_ALARM_HOUR_INDEX] & 0x80)) + t->time.tm_hour = bcd2bin(alarmreg[M41T62_REG_ALARM_HOUR_INDEX] & 0x3f); + if (!(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x80)) + t->time.tm_mday = bcd2bin(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x3f); + if (!(alarmreg[M41T62_REG_ALARM_DAY_INDEX] & 0x40)) + t->time.tm_mon = bcd2bin(alarmreg[M41T62_REG_ALARM_MON_INDEX] & 0x1f) - 1; + t->time.tm_year = -1; + t->time.tm_wday = -1; + t->time.tm_yday = -1; + t->time.tm_isdst = -1; + t->enabled = !!(alarmreg[M41T62_REG_ALARM_MON_INDEX] & M41T62_ALMON_AFE); + t->pending = !!(alarmreg[M41T62_REG_FLAGS_INDEX] & M41T62_FLAGS_AF); + + + mutex_lock(&rk_rtc->mutex); + ret = m41t62_i2c_read_regs(client,M41T62_REG_ALARM_MON,alarmreg, M41T62_ALARM_REG_SIZE ); + if(ret < 0) + { + printk(KERN_INFO "%s:read rtc m41t62 alarm error\n",__func__); + } + else + { + ret = 0; + } + mutex_unlock(&rk_rtc->mutex); + //printk("read alarm2 mon=0x%x, day=0x%x, hour=0x%x, min=0x%x, sec=0x%x, flags=0x%x\n", + // reg[M41T62_REG_ALARM_MON], + // reg[M41T62_REG_ALARM_DAY], + // reg[M41T62_REG_ALARM_HOUR], + // reg[M41T62_REG_ALARM_MIN], + // reg[M41T62_REG_ALARM_SEC], + // reg[M41T62_REG_FLAGS]); + + + return ret; +} + +static void rockrtc_work_func(struct work_struct *work) +{ + struct rock_rtc *rk_rtc = container_of(work, struct rock_rtc, work); + struct i2c_client *client = rk_rtc->client; + struct rtc_time now; + u8 flagreg; + + DBG("enter %s\n",__func__); + + mutex_lock(&rk_rtc->mutex); + m41t62_i2c_read_regs(client,M41T62_REG_FLAGS,&flagreg, 1 ); + flagreg &=~M41T62_FLAGS_AF ; + m41t62_i2c_set_regs(client,M41T62_REG_FLAGS,&flagreg, 1 ); + mutex_unlock(&rk_rtc->mutex); + + m41t62_get_datetime(client ,&now); + mutex_lock(&rk_rtc->mutex); + if (rk_rtc->alarm.enabled && rk_rtc->alarm.time.tm_sec > now.tm_sec) + { + long timeout = rk_rtc->alarm.time.tm_sec - now.tm_sec + 1; + pr_info("stay awake %lds\n", timeout); + wake_lock_timeout(&rk_rtc->wake_lock, timeout * HZ); + } + if (!rk_rtc->exiting) + enable_irq(rk_rtc->irq); + mutex_unlock(&rk_rtc->mutex); +} + + +static struct rtc_class_ops m41t62_rtc_ops = { + .read_time = m41t62_rtc_read_time, + .set_time = m41t62_rtc_set_time, + .read_alarm = m41t62_rtc_read_alarm, + .set_alarm = m41t62_rtc_set_alarm, + .ioctl = m41t62_rtc_ioctl, +}; + +#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) +static ssize_t m41t62_sysfs_show_flags(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + int val; + + val = i2c_smbus_read_byte_data(client, M41T62_REG_FLAGS); + if (val < 0) + return -EIO; + return sprintf(buf, "%#x\n", val); +} +static DEVICE_ATTR(flags, S_IRUGO, m41t62_sysfs_show_flags, NULL); + +static ssize_t m41t62_sysfs_show_sqwfreq(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + int val; + + val = i2c_smbus_read_byte_data(client, M41T62_REG_SQW); + if (val < 0) + return -EIO; + val = (val >> 4) & 0xf; + switch (val) { + case 0: + break; + case 1: + val = 32768; + break; + default: + val = 32768 >> val; + } + return sprintf(buf, "%d\n", val); +} +static ssize_t m41t62_sysfs_set_sqwfreq(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int almon, sqw; + int val = simple_strtoul(buf, NULL, 0); + + if (val) { + if (!is_power_of_2(val)) + return -EINVAL; + val = ilog2(val); + if (val == 15) + val = 1; + else if (val < 14) + val = 15 - val; + else + return -EINVAL; + } + /* disable SQW, set SQW frequency & re-enable */ + almon = i2c_smbus_read_byte_data(client, M41T62_REG_ALARM_MON); + if (almon < 0) + return -EIO; + sqw = i2c_smbus_read_byte_data(client, M41T62_REG_SQW); + if (sqw < 0) + return -EIO; + sqw = (sqw & 0x0f) | (val << 4); + if (i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON, + almon & ~M41T62_ALMON_SQWE) < 0 || + i2c_smbus_write_byte_data(client, M41T62_REG_SQW, sqw) < 0) + return -EIO; + if (val && i2c_smbus_write_byte_data(client, M41T62_REG_ALARM_MON, + almon | M41T62_ALMON_SQWE) < 0) + return -EIO; + return count; +} +static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR, + m41t62_sysfs_show_sqwfreq, m41t62_sysfs_set_sqwfreq); + +static struct attribute *attrs[] = { + &dev_attr_flags.attr, + &dev_attr_sqwfreq.attr, + NULL, +}; +static struct attribute_group attr_group = { + .attrs = attrs, +}; + +static int m41t62_sysfs_register(struct device *dev) +{ + DBG("\n@@@@@@@@@@@m41t62_sysfs_register@@@@@@@@@@@@@\n"); + return sysfs_create_group(&dev->kobj, &attr_group); +} +#else +static int m41t62_sysfs_register(struct device *dev) +{ + DBG("\n@@@@@@@@@@@m41t62_sysfs_register@@@@@@@@@@@@@\n"); + return 0; +} +#endif + + + + +/* + ***************************************************************************** + * + * Driver Interface + * + ***************************************************************************** + */ +static int __devinit m41t62_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + //DBG("%s>>>>>>>>>>>>>client->flags:%d\n",__func__,client->flags); + int rc = 0; + struct rock_rtc *rk_rtc = NULL; + struct rtc_device *rtc = NULL; + struct rtc_time tm_read, tm = { + .tm_year = 111, + .tm_mon = 2, + .tm_mday = 7, + .tm_wday = 7, + .tm_hour = 12, + .tm_min = 1, + .tm_sec = 8 + }; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ){ + rc = -ENODEV; + printk("i2c_check_functionality fail\n"); + goto exit; + } + + rk_rtc = kzalloc(sizeof(struct rock_rtc), GFP_KERNEL); + if (!rk_rtc) { + return -ENOMEM; + } + + rtc = rtc_device_register(client->name, &client->dev, + &m41t62_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + rc = PTR_ERR(rtc); + rtc = NULL; + printk("\nm41t62_probe err3\n"); + goto exit; + } + + rk_rtc->client = client; + rk_rtc->rtc = rtc; + + mutex_init(&rk_rtc->mutex); + wake_lock_init(&rk_rtc->wake_lock, WAKE_LOCK_SUSPEND, "rtc_m41t62"); + INIT_WORK(&rk_rtc->work, rockrtc_work_func); + + i2c_set_clientdata(client, rk_rtc); + + rc = m41t62_sysfs_register(&client->dev); + if (rc) + { + printk("\nm41t62_probe err4\n"); + goto exit; + } + + + m41t62_init_device(client);//0323 + m41t62_get_datetime(client, &tm_read); + if((tm_read.tm_year < 111 ) |(tm_read.tm_year > 120 ) |(tm_read.tm_mon > 11)) + { + m41t62_set_datetime(client, &tm); + printk("%s [%d]run set time \n",__FUNCTION__,__LINE__); + } + + if(gpio_request(client->irq, "rtc gpio")) + { + dev_err(&client->dev, "gpio request fail\n"); + gpio_free(client->irq); + goto exit; + } + + rk_rtc->irq = gpio_to_irq(client->irq); + gpio_pull_updown(client->irq,GPIOPullUp); + if (request_irq(rk_rtc->irq, rtc_wakeup_irq, IRQF_TRIGGER_FALLING, client->dev.driver->name, rk_rtc) < 0) + { + printk("unable to request rtc irq\n"); + goto exit; + } + enable_irq_wake(rk_rtc->irq); + + return 0; + +exit: + if (rtc) + rtc_device_unregister(rtc); + if (rk_rtc) + kfree(rk_rtc); + return rc; + +} + + + +static int __devexit m41t62_remove(struct i2c_client *client) +{ + + struct rock_rtc *rk_rtc = i2c_get_clientdata(client); + + if (rk_rtc->irq > 0) { + mutex_lock(&rk_rtc->mutex); + rk_rtc->exiting = 1; + mutex_unlock(&rk_rtc->mutex); + + free_irq(rk_rtc->irq, rk_rtc); + cancel_work_sync(&rk_rtc->work); + } + + rtc_device_unregister(rk_rtc->rtc); + wake_lock_destroy(&rk_rtc->wake_lock); + kfree(rk_rtc); + rk_rtc = NULL; + + return 0; +} + +static const struct i2c_device_id m41t62_id[] = { + { DRV_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, m41t62_id); + + +static struct i2c_driver m41t62_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = m41t62_probe, + .remove = __devexit_p(m41t62_remove), + .id_table = m41t62_id, + +}; + + +static int __init m41t62_rtc_init(void) +{ + DBG("%s>>>>>>>>>\n",__func__); + return i2c_add_driver(&m41t62_driver); +} + +static void __exit m41t62_rtc_exit(void) +{ + DBG("%s>>>>>>>>>\n",__func__); + i2c_del_driver(&m41t62_driver); +} + +MODULE_AUTHOR("rockchip lhh"); +MODULE_DESCRIPTION("ST Microelectronics M41T62 series RTC I2C Client Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(m41t62_rtc_init); +module_exit(m41t62_rtc_exit); diff --git a/drivers/video/display/screen/Kconfig b/drivers/video/display/screen/Kconfig index 0dea8eb9d0db..85dae4ff13f6 100755 --- a/drivers/video/display/screen/Kconfig +++ b/drivers/video/display/screen/Kconfig @@ -54,6 +54,8 @@ config DEFAULT_OUT_HDMI if you want set HDMI for default panel, android UI size is HDMI default resolution. config LCD_AT070TNA2 bool "RGB AT070TNA2" +config LCD_AT070TN93 + bool "RGB AT070TN93" endchoice diff --git a/drivers/video/display/screen/Makefile b/drivers/video/display/screen/Makefile index f75d34a0f3b4..f20c2b04792d 100755 --- a/drivers/video/display/screen/Makefile +++ b/drivers/video/display/screen/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_LCD_LS035Y8DX02A) += lcd_ls035y8dx02a.o obj-$(CONFIG_LCD_IPS1P5680_V1_E) += lcd_ips1p5680_v1_e.o obj-$(CONFIG_LCD_MCU_TFT480800_25_E) += lcd_mcu_tft480800_25_e.o obj-$(CONFIG_LCD_AT070TNA2) += lcd_AT070TNA2.o +obj-$(CONFIG_LCD_AT070TN93) += lcd_at070tn93.o \ No newline at end of file diff --git a/drivers/video/display/screen/lcd_at070tn93.c b/drivers/video/display/screen/lcd_at070tn93.c new file mode 100755 index 000000000000..b214697d0ad7 --- /dev/null +++ b/drivers/video/display/screen/lcd_at070tn93.c @@ -0,0 +1,76 @@ +#include +#include +#include "../../rk29_fb.h" +#include +#include +#include +#include "screen.h" + + +/* Base */ +#define OUT_TYPE SCREEN_RGB + +#define OUT_FACE OUT_D888_P666 +#define OUT_CLK 58500000 // 65000000 +#define LCDC_ACLK 500000000//312000000 //29 lcdc axi DMA ƵÂÊ + +/* Timing */ +#define H_PW 10 +#define H_BP 100 +#define H_VD 800 +#define H_FP 210 + +#define V_PW 10 +#define V_BP 10 +#define V_VD 480 +#define V_FP 18 + +#define LCD_WIDTH 202 +#define LCD_HEIGHT 152 +/* Other */ +#define DCLK_POL 0 +#define SWAP_RB 0 + +void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) +{ + /* screen type & face */ + screen->type = OUT_TYPE; + screen->face = OUT_FACE; + + /* Screen size */ + screen->x_res = H_VD; + screen->y_res = V_VD; + + screen->width = LCD_WIDTH; + screen->height = LCD_HEIGHT; + + /* Timing */ + screen->lcdc_aclk = LCDC_ACLK; + screen->pixclock = OUT_CLK; + screen->left_margin = H_BP; + screen->right_margin = H_FP; + screen->hsync_len = H_PW; + screen->upper_margin = V_BP; + screen->lower_margin = V_FP; + screen->vsync_len = V_PW; + + /* Pin polarity */ + screen->pin_hsync = 0; + screen->pin_vsync = 0; + screen->pin_den = 0; + screen->pin_dclk = DCLK_POL; + + /* Swap rule */ + screen->swap_rb = SWAP_RB; + screen->swap_rg = 0; + screen->swap_gb = 0; + screen->swap_delta = 0; + screen->swap_dumy = 0; + + /* Operation function*/ + screen->init = NULL; + screen->standby = NULL; +} + + + diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ec6669f9ed72..d1be5eaa1833 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -53,6 +53,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8974 if I2C select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8990 if I2C + select SND_SOC_CS42L52 if I2C select SND_SOC_WM8993 if I2C select SND_SOC_WM8994 if SND_SOC_I2C_AND_SPI select SND_SOC_WM9081 if I2C @@ -217,6 +218,9 @@ config SND_SOC_WM8988 config SND_SOC_WM8990 tristate +config SND_SOC_CS42L52 + tristate + config SND_SOC_WM8993 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index cef035f1cb3e..8b9bbc44b0bd 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -33,6 +33,7 @@ snd-soc-wm8900-objs := wm8900.o snd-soc-alc5621-objs := alc5621.o snd-soc-alc5631-objs := rt5631.o snd-soc-rt5625-objs := rt5625.o +snd-soc-cs42l52-objs := cs42l52.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8940-objs := wm8940.o snd-soc-wm8960-objs := wm8960.o @@ -89,6 +90,7 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_alc5621) += snd-soc-alc5621.o obj-$(CONFIG_SND_SOC_alc5631) += snd-soc-alc5631.o obj-$(CONFIG_SND_SOC_RT5625) += snd-soc-rt5625.o +obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c new file mode 100755 index 000000000000..77d5d7d828c1 --- /dev/null +++ b/sound/soc/codecs/cs42l52.c @@ -0,0 +1,1400 @@ +/* + * cs42l52.c -- CS42L52 ALSA SoC audio driver + * + * Copyright 2007 CirrusLogic, Inc. + * + * Author: Bo Liu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * Revision history + * Nov 2007 Initial version. + * Oct 2008 Updated to 2.6.26 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "cs42l52.h" +//#include "cs42L52_control.h" +#define DEBUG +#ifdef DEBUG +#define SOCDBG(fmt, arg...) printk(KERN_ERR "%s: %s() " fmt, SOC_CS42L52_NAME, __FUNCTION__, ##arg) +#else +#define SOCDBG(fmt, arg...) +#endif +#define SOCINF(fmt, args...) printk(KERN_INFO "%s: " fmt, SOC_CS42L52_NAME, ##args) +#define SOCERR(fmt, args...) printk(KERN_ERR "%s: " fmt, SOC_CS42L52_NAME, ##args) + +static void soc_cs42l52_work(struct work_struct *work); +static int soc_cs42l52_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level); +static int soc_cs42l52_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai); +static int soc_cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, u_int freq, int dir); + +static int soc_cs42l52_set_dai_clkdiv(struct snd_soc_dai *codec_dai, + int div_id, int div); + +static int soc_cs42l52_digital_mute(struct snd_soc_dai *dai, int mute); +static int soc_cs42l52_set_fmt(struct snd_soc_dai *codec_dai, + u_int fmt); +static unsigned int soc_cs42l52_read(struct snd_soc_codec *codec, + u_int reg); + +/** + * snd_soc_get_volsw - single mixer get callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to get the value of a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_cs42l5x_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0x0f; + int rshift = (kcontrol->private_value >> 12) & 0x0f; + int max = (kcontrol->private_value >> 16) & 0xff; + int mask = (1 << fls(max)) - 1; + int min = (kcontrol->private_value >> 24) & 0xff; + + ucontrol->value.integer.value[0] = + ((snd_soc_read(codec, reg) >> shift) - min) & mask; + if (shift != rshift) + ucontrol->value.integer.value[1] = + ((snd_soc_read(codec, reg) >> rshift) - min) & mask; + + return 0; +} + +/** + * snd_soc_put_volsw - single mixer put callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to set the value of a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_cs42l5x_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0x0f; + int rshift = (kcontrol->private_value >> 12) & 0x0f; + int max = (kcontrol->private_value >> 16) & 0xff; + int mask = (1 << fls(max)) - 1; + int min = (kcontrol->private_value >> 24) & 0xff; + unsigned short val, val2, val_mask; + + val = ((ucontrol->value.integer.value[0] + min) & mask); + + val_mask = mask << shift; + val = val << shift; + if (shift != rshift) { + val2 = ((ucontrol->value.integer.value[1] + min) & mask); + val_mask |= mask << rshift; + val |= val2 << rshift; + } + return snd_soc_update_bits(codec, reg, val_mask, val); +} + +/** + * snd_soc_info_volsw_2r - double mixer info callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information about a double mixer control that + * spans 2 codec registers. + * + * Returns 0 for success. + */ +int snd_soc_cs42l5x_info_volsw_2r(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int max = (kcontrol->private_value >> 8) & 0xff; + + if (max == 1) + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = max; + return 0; +} + +/** + * snd_soc_get_volsw_2r - double mixer get callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to get the value of a double mixer control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_cs42l5x_get_volsw_2r(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int reg2 = (kcontrol->private_value >> 24) & 0xff; + int max = (kcontrol->private_value >> 8) & 0xff; + int min = (kcontrol->private_value >> 16) & 0xff; + int mask = (1<value.integer.value[0] = (val - min) & mask; + ucontrol->value.integer.value[1] = (val2 - min) & mask; +/* + SOCDBG("reg[%02x:%02x] = %02x:%02x ucontrol[%02x:%02x], min = %02x, max = %02x, mask %02x\n", + reg, reg2, val,val2, + ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], + min, max, mask); +*/ + return 0; +} + +/** + * snd_soc_put_volsw_2r - double mixer set callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to set the value of a double mixer control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_cs42l5x_put_volsw_2r(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int reg2 = (kcontrol->private_value >> 24) & 0xff; + int max = (kcontrol->private_value >> 8) & 0xff; + int min = (kcontrol->private_value >> 16) & 0xff; + int mask = (1 << fls(max)) - 1; + int err; + unsigned short val, val2; + + val = (ucontrol->value.integer.value[0] + min) & mask; + val2 = (ucontrol->value.integer.value[1] + min) & mask; + + if ((err = snd_soc_update_bits(codec, reg, mask, val)) < 0) + return err; + + err = snd_soc_update_bits(codec, reg2, mask, val2); +/* + SOCDBG("reg[%02x:%02x] = %02x:%02x, ucontrol[%02x:%02x], min = %02x, max = %02x, mask = %02x\n", + reg, reg2, val, val2, + ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], + min, max, mask); +*/ + return err; +} + +#define SOC_SINGLE_CS42L52(xname, reg, shift, max, min) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, .get = snd_soc_cs42l5x_get_volsw,\ + .put = snd_soc_cs42l5x_put_volsw, \ + .private_value = SOC_SINGLE_VALUE(reg, shift, max, min) } + +#define SOC_DOUBLE_CS42L52(xname, reg, shift_left, shift_right, max, min) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .info = snd_soc_info_volsw, .get = snd_soc_cs42l5x_get_volsw, \ + .put = snd_soc_cs42l5x_put_volsw, \ + .private_value = (reg) | ((shift_left) << 8) | \ + ((shift_right) << 12) | ((max) << 16) | ((min) << 24) } + +/* No shifts required */ +#define SOC_DOUBLE_R_CS42L52(xname, reg_left, reg_right, max, min) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .info = snd_soc_cs42l5x_info_volsw_2r, \ + .get = snd_soc_cs42l5x_get_volsw_2r, .put = snd_soc_cs42l5x_put_volsw_2r, \ + .private_value = (reg_left) | ((max) << 8) | ((min) << 16) | \ + ((reg_right) << 24) } + + +/* + * CS42L52 register default value + */ + +static const u8 soc_cs42l52_reg_default[] = { + 0x00, 0xE0, 0x01, 0x07, 0x05, /*4*/ + 0xa0, 0x00, 0x00, 0x81, /*8*/ + 0x81, 0xa5, 0x00, 0x00, /*12*/ + 0x60, 0x02, 0x00, 0x00, /*16*/ + 0x00, 0x00, 0x00, 0x00, /*20*/ + 0x00, 0x00, 0x00, 0x80, /*24*/ + 0x80, 0x00, 0x00, 0x00, /*28*/ + 0x00, 0x00, 0x88, 0x00, /*32*/ + 0x00, 0x00, 0x00, 0x00, /*36*/ + 0x00, 0x00, 0x00, 0x7f, /*40*/ + 0xc0, 0x00, 0x3f, 0x00, /*44*/ + 0x00, 0x00, 0x00, 0x00, /*48*/ + 0x00, 0x3b, 0x00, 0x5f, /*52*/ +}; + +static inline int soc_cs42l52_read_reg_cache(struct snd_soc_codec *codec, + u_int reg) +{ + u8 *cache = codec->reg_cache; + + return reg > SOC_CS42L52_REG_NUM ? -EINVAL : cache[reg]; +} + +static inline void soc_cs42l52_write_reg_cache(struct snd_soc_codec *codec, + u_int reg, u_int val) +{ + u8 *cache = codec->reg_cache; + + if(reg > SOC_CS42L52_REG_NUM) + return; + cache[reg] = val & 0xff; +} + +static int soc_cs42l52_write(struct snd_soc_codec *codec, + unsigned reg, u_int val) +{ +#if 1 + u8 datas[2]; + int i,num, ret = 0; + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*)codec->private_data; + + datas[0] = reg & 0xff; /*reg addr*/ + datas[1] = val & 0xff; /*reg val*/ + codec->num_dai = 1; + if(info->flags & SOC_CS42L52_ALL_IN_ONE) + { + for(i = 0; i < codec->num_dai; i++) + { + if(codec->hw_write(codec->control_data, datas, 2) != 2) + { + ret = -EIO; + break; + } + } + } + else + { + if(info->flags & SOC_CS42L52_CHIP_SWICTH) + { + num = info->flags & SOC_CS42L52_CHIP_MASK; + } + + if(codec->hw_write(codec->control_data, datas, 2) != 2) + ret = -EIO; + } + + printk(KERN_INFO"soc_cs42l52_write---reg=%d--val=%d\n",reg,val); + if(ret >= 0) + soc_cs42l52_write_reg_cache(codec, reg, val); + + return ret; +#else + return codec->write(codec, reg, val); +#endif +} + +static unsigned int soc_cs42l52_read(struct snd_soc_codec *codec, + u_int reg) +{ +#if 1 + u8 data; + u8 addr; + int i, ret = 0; + + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*)codec->private_data; +#ifndef CONFIG_CS42L52_DEBUG + if(reg == CODEC_CS42L52_SPK_STATUS) + { +#endif + addr = reg & 0xff; + if(info->flags & SOC_CS42L52_ALL_IN_ONE) + { + codec->num_dai = 1; + for(i = 0; i < codec->num_dai; i++) + { + if(codec->hw_write(codec->control_data, &addr, 1) == 1) + { +// if(codec->hw_read(codec->control_data, &data, 1) == 1) + { +// ret |= data << (i * 8); + } + } + else{ + ret = -EIO; + break; + } + + } + } +#ifndef CONFIG_CS42L52_DEBUG + } + else{ + + + u8 *cache = codec->reg_cache; + u8 retval; + retval = reg > SOC_CS42L52_REG_NUM ? -EINVAL : cache[reg]; +/* SOCDBG("%s (cache) 0x%x = %02x (%d)\n", reg, retval, retval); */ + return retval; + } +#endif +// SOCDBG("0x%x = %02x (%d)\n", reg, ret, ret); + return ret; +#else + return codec->read(codec, reg); +#endif +} + +static const char *cs42l52_mic_bias[] = {"0.5VA", "0.6VA", "0.7VA", "0.8VA", "0.83VA", "0.91VA"}; +static const char *cs42l52_hpf_freeze[] = {"Continuous DC Subtraction", "Frozen DC Subtraction"}; +static const char *cs42l52_hpf_corner_freq[] = {"Normal", "119Hz", "236Hz", "464Hz"}; +static const char *cs42l52_adc_sum[] = {"Normal", "Sum half", "Sub half", "Inverted"}; +static const char *cs42l52_sig_polarity[] = {"Normal", "Inverted"}; +static const char *cs42l52_spk_mono_channel[] = {"ChannelA", "ChannelB"}; +static const char *cs42l52_beep_type[] = {"Off", "Single", "Multiple", "Continuous"}; +static const char *cs42l52_treble_freq[] = {"5kHz", "7kHz", "10kHz", "15kHz"}; +static const char *cs42l52_bass_freq[] = {"50Hz", "100Hz", "200Hz", "250Hz"}; +static const char *cs42l52_target_sel[] = {"Apply Specific", "Apply All"}; +static const char *cs42l52_noise_gate_delay[] = {"50ms", "100ms", "150ms", "200ms"}; +static const char *cs42l52_adc_mux[] = {"AIN1", "AIN2", "AIN3", "AIN4", "PGA"}; +static const char *cs42l52_mic_mux[] = {"MIC1", "MIC2"}; +static const char *cs42l52_stereo_mux[] = {"Mono", "Stereo"}; +static const char *cs42l52_off[] = {"On", "Off"}; +static const char *cs42l52_hpmux[] = {"Off", "On"}; + +static const struct soc_enum soc_cs42l52_enum[] = { +SOC_ENUM_DOUBLE(CODEC_CS42L52_ANALOG_HPF_CTL, 4, 6, 2, cs42l52_hpf_freeze), /*0*/ +SOC_ENUM_SINGLE(CODEC_CS42L52_ADC_HPF_FREQ, 0, 4, cs42l52_hpf_corner_freq), +SOC_ENUM_SINGLE(CODEC_CS42L52_ADC_MISC_CTL, 4, 4, cs42l52_adc_sum), +SOC_ENUM_DOUBLE(CODEC_CS42L52_ADC_MISC_CTL, 2, 3, 2, cs42l52_sig_polarity), +SOC_ENUM_DOUBLE(CODEC_CS42L52_PB_CTL1, 2, 3, 2, cs42l52_sig_polarity), +SOC_ENUM_SINGLE(CODEC_CS42L52_PB_CTL2, 2, 2, cs42l52_spk_mono_channel), /*5*/ +SOC_ENUM_SINGLE(CODEC_CS42L52_BEEP_TONE_CTL, 6, 4, cs42l52_beep_type), +SOC_ENUM_SINGLE(CODEC_CS42L52_BEEP_TONE_CTL, 3, 4, cs42l52_treble_freq), +SOC_ENUM_SINGLE(CODEC_CS42L52_BEEP_TONE_CTL, 1, 4, cs42l52_bass_freq), +SOC_ENUM_SINGLE(CODEC_CS42L52_LIMITER_CTL2, 6, 2, cs42l52_target_sel), +SOC_ENUM_SINGLE(CODEC_CS42L52_NOISE_GATE_CTL, 7, 2, cs42l52_target_sel), /*10*/ +SOC_ENUM_SINGLE(CODEC_CS42L52_NOISE_GATE_CTL, 0, 4, cs42l52_noise_gate_delay), +SOC_ENUM_SINGLE(CODEC_CS42L52_ADC_PGA_A, 5, 5, cs42l52_adc_mux), +SOC_ENUM_SINGLE(CODEC_CS42L52_ADC_PGA_B, 5, 5, cs42l52_adc_mux), +SOC_ENUM_SINGLE(CODEC_CS42L52_MICA_CTL, 6, 2, cs42l52_mic_mux), +SOC_ENUM_SINGLE(CODEC_CS42L52_MICB_CTL, 6, 2, cs42l52_mic_mux), /*15*/ +SOC_ENUM_SINGLE(CODEC_CS42L52_MICA_CTL, 5, 2, cs42l52_stereo_mux), +SOC_ENUM_SINGLE(CODEC_CS42L52_MICB_CTL, 5, 2, cs42l52_stereo_mux), +SOC_ENUM_SINGLE(CODEC_CS42L52_IFACE_CTL2, 0, 6, cs42l52_mic_bias), /*18*/ +SOC_ENUM_SINGLE(CODEC_CS42L52_PWCTL2, 0, 2, cs42l52_off), +SOC_ENUM_SINGLE(CODEC_CS42L52_MISC_CTL, 6, 2, cs42l52_hpmux), +SOC_ENUM_SINGLE(CODEC_CS42L52_MISC_CTL, 7, 2, cs42l52_hpmux), +}; + +static const struct snd_kcontrol_new soc_cs42l52_controls[] = { + +SOC_ENUM("Mic VA Capture Switch", soc_cs42l52_enum[18]), /*0*/ +SOC_DOUBLE("HPF Capture Switch", CODEC_CS42L52_ANALOG_HPF_CTL, 5, 7, 1, 0), +SOC_ENUM("HPF Freeze Capture Switch", soc_cs42l52_enum[0]), + +SOC_DOUBLE("Analog SR Capture Switch", CODEC_CS42L52_ANALOG_HPF_CTL, 1, 3, 1, 1), +SOC_DOUBLE("Analog ZC Capture Switch", CODEC_CS42L52_ANALOG_HPF_CTL, 0, 2, 1, 1), +SOC_ENUM("HPF corner freq Capture Switch", soc_cs42l52_enum[1]), /*5*/ + +SOC_SINGLE("Ganged Ctl Capture Switch", CODEC_CS42L52_ADC_MISC_CTL, 7, 1, 1), /* should be enabled init */ +SOC_ENUM("Mix/Swap Capture Switch",soc_cs42l52_enum[2]), +SOC_ENUM("Signal Polarity Capture Switch", soc_cs42l52_enum[3]), + +SOC_SINGLE("HP Analog Gain Playback Volume", CODEC_CS42L52_PB_CTL1, 5, 7, 0), +SOC_SINGLE("Playback B=A Volume Playback Switch", CODEC_CS42L52_PB_CTL1, 4, 1, 0), /*10*/ /*should be enabled init*/ +SOC_ENUM("PCM Signal Polarity Playback Switch",soc_cs42l52_enum[4]), + +SOC_SINGLE("Digital De-Emphasis Playback Switch", CODEC_CS42L52_MISC_CTL, 2, 1, 0), +SOC_SINGLE("Digital SR Playback Switch", CODEC_CS42L52_MISC_CTL, 1, 1, 0), +SOC_SINGLE("Digital ZC Playback Switch", CODEC_CS42L52_MISC_CTL, 0, 1, 0), + +SOC_SINGLE("Spk Volume Equal Playback Switch", CODEC_CS42L52_PB_CTL2, 3, 1, 0) , /*15*/ /*should be enabled init*/ +SOC_SINGLE("Spk Mute 50/50 Playback Switch", CODEC_CS42L52_PB_CTL2, 0, 1, 0), +SOC_ENUM("Spk Swap Channel Playback Switch", soc_cs42l52_enum[5]), +SOC_SINGLE("Spk Full-Bridge Playback Switch", CODEC_CS42L52_PB_CTL2, 1, 1, 0), +SOC_DOUBLE_R("Mic Gain Capture Volume", CODEC_CS42L52_MICA_CTL, CODEC_CS42L52_MICB_CTL, 0, 31, 0), + +SOC_DOUBLE_R("ALC SR Capture Switch", CODEC_CS42L52_PGAA_CTL, CODEC_CS42L52_PGAB_CTL, 7, 1, 1), /*20*/ +SOC_DOUBLE_R("ALC ZC Capture Switch", CODEC_CS42L52_PGAA_CTL, CODEC_CS42L52_PGAB_CTL, 6, 1, 1), +SOC_DOUBLE_R_CS42L52("PGA Capture Volume", CODEC_CS42L52_PGAA_CTL, CODEC_CS42L52_PGAB_CTL, 0x30, 0x18), + +SOC_DOUBLE_R_CS42L52("Passthru Playback Volume", CODEC_CS42L52_PASSTHRUA_VOL, CODEC_CS42L52_PASSTHRUB_VOL, 0x90, 0x88), +SOC_DOUBLE("Passthru Playback Switch", CODEC_CS42L52_MISC_CTL, 4, 5, 1, 1), +SOC_DOUBLE_R_CS42L52("ADC Capture Volume", CODEC_CS42L52_ADCA_VOL, CODEC_CS42L52_ADCB_VOL, 0x80, 0xA0), +SOC_DOUBLE("ADC Capture Switch", CODEC_CS42L52_ADC_MISC_CTL, 0, 1, 1, 1), +SOC_DOUBLE_R_CS42L52("ADC Mixer Capture Volume", CODEC_CS42L52_ADCA_MIXER_VOL, CODEC_CS42L52_ADCB_MIXER_VOL, 0x7f, 0x19), +SOC_DOUBLE_R("ADC Mixer Capture Switch", CODEC_CS42L52_ADCA_MIXER_VOL, CODEC_CS42L52_ADCB_MIXER_VOL, 7, 1, 1), +SOC_DOUBLE_R_CS42L52("PCM Mixer Playback Volume", CODEC_CS42L52_PCMA_MIXER_VOL, CODEC_CS42L52_PCMB_MIXER_VOL, 0x7f, 0x19), +SOC_DOUBLE_R("PCM Mixer Playback Switch", CODEC_CS42L52_PCMA_MIXER_VOL, CODEC_CS42L52_PCMB_MIXER_VOL, 7, 1, 1), + +SOC_SINGLE("Beep Freq", CODEC_CS42L52_BEEP_FREQ, 4, 15, 0), +SOC_SINGLE("Beep OnTime", CODEC_CS42L52_BEEP_FREQ, 0, 15, 0), /*30*/ +SOC_SINGLE_CS42L52("Beep Volume", CODEC_CS42L52_BEEP_VOL, 0, 0x1f, 0x07), +SOC_SINGLE("Beep OffTime", CODEC_CS42L52_BEEP_VOL, 5, 7, 0), +SOC_ENUM("Beep Type", soc_cs42l52_enum[6]), +SOC_SINGLE("Beep Mix Switch", CODEC_CS42L52_BEEP_TONE_CTL, 5, 1, 1), + +SOC_ENUM("Treble Corner Freq Playback Switch", soc_cs42l52_enum[7]), /*35*/ +SOC_ENUM("Bass Corner Freq Playback Switch",soc_cs42l52_enum[8]), +SOC_SINGLE("Tone Control Playback Switch", CODEC_CS42L52_BEEP_TONE_CTL, 0, 1, 0), +SOC_SINGLE("Treble Gain Playback Volume", CODEC_CS42L52_TONE_CTL, 4, 15, 1), +SOC_SINGLE("Bass Gain Playback Volume", CODEC_CS42L52_TONE_CTL, 0, 15, 1), + +SOC_DOUBLE_R_CS42L52("Master Playback Volume", CODEC_CS42L52_MASTERA_VOL, CODEC_CS42L52_MASTERB_VOL,0xe4, 0x34), /*40*/ +SOC_DOUBLE_R_CS42L52("HP Digital Playback Volume", CODEC_CS42L52_HPA_VOL, CODEC_CS42L52_HPB_VOL, 0xff, 0x1), +SOC_DOUBLE("HP Digital Playback Switch", CODEC_CS42L52_PB_CTL2, 6, 7, 1, 1), +SOC_DOUBLE_R_CS42L52("Speaker Playback Volume", CODEC_CS42L52_SPKA_VOL, CODEC_CS42L52_SPKB_VOL, 0xff, 0x1), +SOC_DOUBLE("Speaker Playback Switch", CODEC_CS42L52_PB_CTL2, 4, 5, 1, 1), + +SOC_SINGLE("Limiter Max Threshold Playback Volume", CODEC_CS42L52_LIMITER_CTL1, 5, 7, 0), +SOC_SINGLE("Limiter Cushion Threshold Playback Volume", CODEC_CS42L52_LIMITER_CTL1, 2, 7, 0), +SOC_SINGLE("Limiter SR Playback Switch", CODEC_CS42L52_LIMITER_CTL1, 1, 1, 0), /*45*/ +SOC_SINGLE("Limiter ZC Playback Switch", CODEC_CS42L52_LIMITER_CTL1, 0, 1, 0), +SOC_SINGLE("Limiter Playback Switch", CODEC_CS42L52_LIMITER_CTL2, 7, 1, 0), +SOC_ENUM("Limiter Attnenuate Playback Switch", soc_cs42l52_enum[9]), +SOC_SINGLE("Limiter Release Rate Playback Volume", CODEC_CS42L52_LIMITER_CTL2, 0, 63, 0), +SOC_SINGLE("Limiter Attack Rate Playback Volume", CODEC_CS42L52_LIMITER_AT_RATE, 0, 63, 0), /*50*/ + +SOC_DOUBLE("ALC Capture Switch",CODEC_CS42L52_ALC_CTL, 6, 7, 1, 0), +SOC_SINGLE("ALC Attack Rate Capture Volume", CODEC_CS42L52_ALC_CTL, 0, 63, 0), +SOC_SINGLE("ALC Release Rate Capture Volume", CODEC_CS42L52_ALC_RATE, 0, 63, 0), +SOC_SINGLE("ALC Max Threshold Capture Volume", CODEC_CS42L52_ALC_THRESHOLD, 5, 7, 0), +SOC_SINGLE("ALC Min Threshold Capture Volume", CODEC_CS42L52_ALC_THRESHOLD, 2, 7, 0), /*55*/ + +SOC_ENUM("Noise Gate Type Capture Switch", soc_cs42l52_enum[10]), +SOC_SINGLE("Noise Gate Capture Switch", CODEC_CS42L52_NOISE_GATE_CTL, 6, 1, 0), +SOC_SINGLE("Noise Gate Boost Capture Switch", CODEC_CS42L52_NOISE_GATE_CTL, 5, 1, 1), +SOC_SINGLE("Noise Gate Threshold Capture Volume", CODEC_CS42L52_NOISE_GATE_CTL, 2, 7, 0), +SOC_ENUM("Noise Gate Delay Time Capture Switch", soc_cs42l52_enum[11]), /*60*/ + +SOC_SINGLE("Batt Compensation Switch", CODEC_CS42L52_BATT_COMPEN, 7, 1, 0), +SOC_SINGLE("Batt VP Monitor Switch", CODEC_CS42L52_BATT_COMPEN, 6, 1, 0), +SOC_SINGLE("Batt VP ref", CODEC_CS42L52_BATT_COMPEN, 0, 0x0f, 0), +SOC_SINGLE("Playback Charge Pump Freq", CODEC_CS42L52_CHARGE_PUMP, 4, 15, 0), /*64*/ + +}; + +static int soc_cs42l52_add_controls(struct snd_soc_codec *codec) +{ + int i,ret = 0; + + for(i = 0; i < ARRAY_SIZE(soc_cs42l52_controls); i++) + { + ret = snd_ctl_add(codec->card, + snd_soc_cnew(&soc_cs42l52_controls[i], codec, NULL)); + if(ret < 0) + { + SOCDBG("add cs42l52 controls failed\n"); + break; + } + } + return ret; +} + +static const struct snd_kcontrol_new cs42l52_adca_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[12]); + +static const struct snd_kcontrol_new cs42l52_adcb_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[13]); + +static const struct snd_kcontrol_new cs42l52_mica_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[14]); + +static const struct snd_kcontrol_new cs42l52_micb_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[15]); + +static const struct snd_kcontrol_new cs42l52_mica_stereo_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[16]); + +static const struct snd_kcontrol_new cs42l52_micb_stereo_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[17]); + +static const struct snd_kcontrol_new cs42l52_passa_switch = +SOC_DAPM_SINGLE("Switch", CODEC_CS42L52_MISC_CTL, 6, 1, 0); + +static const struct snd_kcontrol_new cs42l52_passb_switch = +SOC_DAPM_SINGLE("Switch", CODEC_CS42L52_MISC_CTL, 7, 1, 0); + +static const struct snd_kcontrol_new cs42l52_micbias_switch = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[19]); + +static const struct snd_kcontrol_new cs42l52_hpa_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[20]); + +static const struct snd_kcontrol_new cs42l52_hpb_mux = +SOC_DAPM_ENUM("Route", soc_cs42l52_enum[21]); + +static const struct snd_soc_dapm_widget soc_cs42l52_dapm_widgets[] = { + /* Input path */ + SND_SOC_DAPM_ADC("ADC Left", "Capture", CODEC_CS42L52_PWCTL1, 1, 1), + SND_SOC_DAPM_ADC("ADC Right", "Capture", CODEC_CS42L52_PWCTL1, 2, 1), + + SND_SOC_DAPM_MUX("MICA Mux Capture Switch", SND_SOC_NOPM, 0, 0, &cs42l52_mica_mux), + SND_SOC_DAPM_MUX("MICB Mux Capture Switch", SND_SOC_NOPM, 0, 0, &cs42l52_micb_mux), + SND_SOC_DAPM_MUX("MICA Stereo Mux Capture Switch", SND_SOC_NOPM, 1, 0, &cs42l52_mica_stereo_mux), + SND_SOC_DAPM_MUX("MICB Stereo Mux Capture Switch", SND_SOC_NOPM, 2, 0, &cs42l52_micb_stereo_mux), + + SND_SOC_DAPM_MUX("ADC Mux Left Capture Switch", SND_SOC_NOPM, 1, 1, &cs42l52_adca_mux), + SND_SOC_DAPM_MUX("ADC Mux Right Capture Switch", SND_SOC_NOPM, 2, 1, &cs42l52_adcb_mux), + + /* Sum switches */ + SND_SOC_DAPM_PGA("AIN1A Switch", CODEC_CS42L52_ADC_PGA_A, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN2A Switch", CODEC_CS42L52_ADC_PGA_A, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN3A Switch", CODEC_CS42L52_ADC_PGA_A, 2, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN4A Switch", CODEC_CS42L52_ADC_PGA_A, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA("MICA Switch" , CODEC_CS42L52_ADC_PGA_A, 4, 0, NULL, 0), + + SND_SOC_DAPM_PGA("AIN1B Switch", CODEC_CS42L52_ADC_PGA_B, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN2B Switch", CODEC_CS42L52_ADC_PGA_B, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN3B Switch", CODEC_CS42L52_ADC_PGA_B, 2, 0, NULL, 0), + SND_SOC_DAPM_PGA("AIN4B Switch", CODEC_CS42L52_ADC_PGA_B, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA("MICB Switch" , CODEC_CS42L52_ADC_PGA_B, 4, 0, NULL, 0), + + /* MIC PGA Power */ + SND_SOC_DAPM_PGA("PGA MICA", CODEC_CS42L52_PWCTL2, PWCTL2_PDN_MICA_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_PGA("PGA MICB", CODEC_CS42L52_PWCTL2, PWCTL2_PDN_MICB_SHIFT, 1, NULL, 0), + + /* MIC bias switch */ + SND_SOC_DAPM_MUX("Mic Bias Capture Switch", SND_SOC_NOPM, 0, 0, &cs42l52_micbias_switch), + SND_SOC_DAPM_PGA("Mic-Bias", CODEC_CS42L52_PWCTL2, 0, 1, NULL, 0), + + /* PGA Power */ + SND_SOC_DAPM_PGA("PGA Left", CODEC_CS42L52_PWCTL1, PWCTL1_PDN_PGAA_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_PGA("PGA Right", CODEC_CS42L52_PWCTL1, PWCTL1_PDN_PGAB_SHIFT, 1, NULL, 0), + + /* Output path */ + SND_SOC_DAPM_MUX("Passthrough Left Playback Switch", SND_SOC_NOPM, 0, 0, &cs42l52_hpa_mux), + SND_SOC_DAPM_MUX("Passthrough Right Playback Switch", SND_SOC_NOPM, 0, 0, &cs42l52_hpb_mux), + + SND_SOC_DAPM_DAC("DAC Left", "Playback", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC Right", "Playback", SND_SOC_NOPM, 0, 0), + + // SND_SOC_DAPM_PGA("HP Amp Left", CODEC_CS42L52_PWCTL3, 4, 1, NULL, 0), + // SND_SOC_DAPM_PGA("HP Amp Right", CODEC_CS42L52_PWCTL3, 6, 1, NULL, 0), + + // SND_SOC_DAPM_PGA("SPK Pwr Left", CODEC_CS42L52_PWCTL3, 0, 1, NULL, 0), + // SND_SOC_DAPM_PGA("SPK Pwr Right", CODEC_CS42L52_PWCTL3, 2, 1, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HPA"), + SND_SOC_DAPM_OUTPUT("HPB"), + SND_SOC_DAPM_OUTPUT("SPKA"), + SND_SOC_DAPM_OUTPUT("SPKB"), + SND_SOC_DAPM_OUTPUT("MICBIAS"), + + SND_SOC_DAPM_INPUT("INPUT1A"), + SND_SOC_DAPM_INPUT("INPUT2A"), + SND_SOC_DAPM_INPUT("INPUT3A"), + SND_SOC_DAPM_INPUT("INPUT4A"), + SND_SOC_DAPM_INPUT("INPUT1B"), + SND_SOC_DAPM_INPUT("INPUT2B"), + SND_SOC_DAPM_INPUT("INPUT3B"), + SND_SOC_DAPM_INPUT("INPUT4B"), + SND_SOC_DAPM_INPUT("MICA"), + SND_SOC_DAPM_INPUT("MICB"), +}; + +static const struct snd_soc_dapm_route soc_cs42l52_audio_map[] = { + + /* adc select path */ + {"ADC Mux Left Capture Switch", "AIN1", "INPUT1A"}, + {"ADC Mux Right Capture Switch", "AIN1", "INPUT1B"}, + {"ADC Mux Left Capture Switch", "AIN2", "INPUT2A"}, + {"ADC Mux Right Capture Switch", "AIN2", "INPUT2B"}, + {"ADC Mux Left Capture Switch", "AIN3", "INPUT3A"}, + {"ADC Mux Right Capture Switch", "AIN3", "INPUT3B"}, + {"ADC Mux Left Capture Switch", "AIN4", "INPUT4A"}, + {"ADC Mux Right Capture Switch", "AIN4", "INPUT4B"}, + + /* left capture part */ + {"AIN1A Switch", NULL, "INPUT1A"}, + {"AIN2A Switch", NULL, "INPUT2A"}, + {"AIN3A Switch", NULL, "INPUT3A"}, + {"AIN4A Switch", NULL, "INPUT4A"}, + {"MICA Switch", NULL, "MICA"}, + {"PGA MICA", NULL, "MICA Switch"}, + + {"PGA Left", NULL, "AIN1A Switch"}, + {"PGA Left", NULL, "AIN2A Switch"}, + {"PGA Left", NULL, "AIN3A Switch"}, + {"PGA Left", NULL, "AIN4A Switch"}, + {"PGA Left", NULL, "PGA MICA"}, + + /* right capture part */ + {"AIN1B Switch", NULL, "INPUT1B"}, + {"AIN2B Switch", NULL, "INPUT2B"}, + {"AIN3B Switch", NULL, "INPUT3B"}, + {"AIN4B Switch", NULL, "INPUT4B"}, + {"MICB Switch", NULL, "MICB"}, + {"PGA MICB", NULL, "MICB Switch"}, + + {"PGA Right", NULL, "AIN1B Switch"}, + {"PGA Right", NULL, "AIN2B Switch"}, + {"PGA Right", NULL, "AIN3B Switch"}, + {"PGA Right", NULL, "AIN4B Switch"}, + {"PGA Right", NULL, "PGA MICB"}, + + {"ADC Mux Left Capture Switch", "PGA", "PGA Left"}, + {"ADC Mux Right Capture Switch", "PGA", "PGA Right"}, + {"ADC Left", NULL, "ADC Mux Left Capture Switch"}, + {"ADC Right", NULL, "ADC Mux Right Capture Switch"}, + + /* Mic Bias */ + {"Mic Bias Capture Switch", "On", "PGA MICA"}, + {"Mic Bias Capture Switch", "On", "PGA MICB"}, + {"Mic-Bias", NULL, "Mic Bias Capture Switch"}, + {"Mic-Bias", NULL, "Mic Bias Capture Switch"}, + {"ADC Mux Left Capture Switch", "PGA", "Mic-Bias"}, + {"ADC Mux Right Capture Switch", "PGA", "Mic-Bias"}, + {"Passthrough Left Playback Switch", "On", "Mic-Bias"}, + {"Passthrough Right Playback Switch", "On", "Mic-Bias"}, + + /* loopback path */ + {"Passthrough Left Playback Switch", "On", "PGA Left"}, + {"Passthrough Right Playback Switch", "On", "PGA Right"}, + {"Passthrough Left Playback Switch", "Off", "DAC Left"}, + {"Passthrough Right Playback Switch", "Off", "DAC Right"}, + +/* Output map */ + /* Headphone */ + {"HP Amp Left", NULL, "Passthrough Left Playback Switch"}, + {"HP Amp Right", NULL, "Passthrough Right Playback Switch"}, + {"HPA", NULL, "HP Amp Left"}, + {"HPB", NULL, "HP Amp Right"}, + + /* Speakers */ + + {"SPK Pwr Left", NULL, "DAC Left"}, + {"SPK Pwr Right", NULL, "DAC Right"}, + {"SPKA", NULL, "SPK Pwr Left"}, + {"SPKB", NULL, "SPK Pwr Right"}, + + /* terminator */ + // {NULL, NULL, NULL}, +}; + +static int soc_cs42l52_add_widgets(struct snd_soc_codec *soc_codec) +{ + snd_soc_dapm_new_controls(soc_codec, soc_cs42l52_dapm_widgets, + ARRAY_SIZE(soc_cs42l52_dapm_widgets)); + + snd_soc_dapm_add_routes(soc_codec, soc_cs42l52_audio_map, + ARRAY_SIZE(soc_cs42l52_audio_map)); + + snd_soc_dapm_new_widgets(soc_codec); + return 0; +} + +#define SOC_CS42L52_RATES ( SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 ) /*refer to cs42l52 datasheet page35*/ + +#define SOC_CS42L52_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE ) + +static struct snd_soc_dai_ops cs42l52_ops = { + .hw_params = soc_cs42l52_pcm_hw_params, + .set_sysclk = soc_cs42l52_set_sysclk, + .set_fmt = soc_cs42l52_set_fmt, + .digital_mute = soc_cs42l52_digital_mute, + .set_clkdiv = soc_cs42l52_set_dai_clkdiv, +}; + + +struct snd_soc_dai soc_cs42l52_dai = { + .name = SOC_CS42L52_NAME, + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = SOC_CS42L52_DEFAULT_MAX_CHANS, + .rates = SOC_CS42L52_RATES, + .formats = SOC_CS42L52_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = SOC_CS42L52_DEFAULT_MAX_CHANS, + .rates = SOC_CS42L52_RATES, + .formats = SOC_CS42L52_FORMATS, + }, + .ops = &cs42l52_ops, +#if 0 + .ops = { + .hw_params = soc_cs42l52_pcm_hw_params, + .set_sysclk = soc_cs42l52_set_sysclk, + .set_fmt = soc_cs42l52_set_fmt, + .digital_mute = soc_cs42l52_digital_mute, + }, +#endif +}; + +EXPORT_SYMBOL_GPL(soc_cs42l52_dai); + +/* #define CONFIG_MANUAL_CLK */ + +/* page 37 from cs42l52 datasheet */ +static void soc_cs42l52_required_setup(struct snd_soc_codec *codec) +{ + u8 data; + soc_cs42l52_write(codec, 0x00, 0x99); + soc_cs42l52_write(codec, 0x3e, 0xba); + soc_cs42l52_write(codec, 0x47, 0x80); + data = soc_cs42l52_read(codec, 0x32); + soc_cs42l52_write(codec, 0x32, data | 0x80); + soc_cs42l52_write(codec, 0x32, data & 0x7f); + soc_cs42l52_write(codec, 0x00, 0x00); +} + + +static struct snd_soc_codec *cs42l52_codec; + +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + +static int cs42l52_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + struct snd_soc_codec *soc_codec; + struct soc_codec_cs42l52 * info; + unsigned int reg; + int i, ret = 0; + printk(KERN_INFO"cs42l52_i2c_probe\n"); + + soc_codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (soc_codec == NULL) + return -ENOMEM; + + soc_codec->name = SOC_CS42L52_NAME; + soc_codec->owner = THIS_MODULE; + soc_codec->write = soc_cs42l52_write; + soc_codec->read = soc_cs42l52_read; + soc_codec->hw_write = (hw_write_t)i2c_master_send; + mutex_init(&soc_codec->mutex); + INIT_LIST_HEAD(&soc_codec->dapm_widgets); + INIT_LIST_HEAD(&soc_codec->dapm_paths); + + soc_codec->set_bias_level = soc_cs42l52_set_bias_level; + soc_codec->dai = &soc_cs42l52_dai; + soc_codec->dai->playback.channels_max = 2; + soc_codec->dai->capture.channels_max = 2; + soc_codec->num_dai = 1; + soc_codec->control_data = i2c; + soc_codec->dev = &i2c->dev; + soc_codec->pcm_devs = 0; /*pcm device num index*/ + soc_codec->pop_time = 2; + soc_codec->dai[0].codec = soc_codec; + + soc_codec->reg_cache_size = sizeof(soc_cs42l52_reg_default); + + soc_codec->reg_cache = kmemdup(soc_cs42l52_reg_default, sizeof(soc_cs42l52_reg_default), GFP_KERNEL); + + info = (struct soc_codec_cs42l52 *)kmalloc(sizeof(struct soc_codec_cs42l52),GFP_KERNEL); + + if (info == NULL) { + kfree(soc_codec); + return -ENOMEM; + } + + info->sysclk = SOC_CS42L52_DEFAULT_CLK; + info->format = SOC_CS42L52_DEFAULT_FORMAT; + + soc_codec->private_data =(void*)info; + + printk(KERN_INFO"soc_cs42l52_setup1\n"); + if(!soc_codec->reg_cache) + { + SOCERR("%s: err out of memory\n", __FUNCTION__); + ret = -ENOMEM; + goto err; + } + + /*initialize codec*/ + for(i = 0; i < soc_codec->num_dai; i++) //while(1) // + { + + SOCINF("Cirrus CS42L52 codec , revision %d\n", ret & CHIP_REV_MASK); + /*set hp default volume*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_HPA_VOL, DEFAULT_HP_VOL); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_HPB_VOL, DEFAULT_HP_VOL); + + + /*set spk default volume*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_SPKA_VOL, DEFAULT_SPK_VOL); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_SPKB_VOL, DEFAULT_SPK_VOL); + + + /*set output default powerstate*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PWCTL3, 5); +#ifdef CONFIG_MANUAL_CLK + soc_cs42l52_write(soc_codec, CODEC_CS42L52_CLK_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_CLK_CTL) + & ~CLK_CTL_AUTODECT_ENABLE)); +#else + soc_cs42l52_write(soc_codec, CODEC_CS42L52_CLK_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_CLK_CTL) + |CLK_CTL_AUTODECT_ENABLE)); +#endif + + /*default output stream configure*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PB_CTL1, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_PB_CTL1) + | (PB_CTL1_HP_GAIN_07099 << PB_CTL1_HP_GAIN_SHIFT))); + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_MISC_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_MISC_CTL)) + | (MISC_CTL_DEEMPH | MISC_CTL_DIGZC | MISC_CTL_DIGSFT)); + + /*default input stream configure*/ + //soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADC_PGA_A, info->adc_sel1); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADC_PGA_A, 0<<6); + + //soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADC_PGA_B, info->adc_sel2); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADC_PGA_B, 1<<7); + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_MICA_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_MICA_CTL) + | 0<<6));/*pre-amplifer 16db*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_MICB_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_MICB_CTL) + | 0<<6)); + /*default input stream path configure*/ + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ANALOG_HPF_CTL, + (soc_cs42l52_read(soc_codec, CODEC_CS42L52_ANALOG_HPF_CTL) + | HPF_CTL_ANLGSFTB | HPF_CTL_ANLGSFTA)); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PGAA_CTL, PGAX_CTL_VOL_6DB); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PGAB_CTL, PGAX_CTL_VOL_6DB); /*PGA volume*/ + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADCA_VOL, ADCX_VOL_12DB); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADCB_VOL, ADCX_VOL_12DB); /*ADC volume*/ + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ALC_CTL, + (ALC_CTL_ALCB_ENABLE | ALC_CTL_ALCA_ENABLE)); /*enable ALC*/ + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ALC_THRESHOLD, + ((ALC_RATE_0DB << ALC_MAX_RATE_SHIFT) + | (ALC_RATE_3DB << ALC_MIN_RATE_SHIFT)));/*ALC max and min threshold*/ + + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_NOISE_GATE_CTL, + (NG_ENABLE | (NG_MIN_70DB << NG_THRESHOLD_SHIFT) + | (NG_DELAY_100MS << NG_DELAY_SHIFT))); /*Noise Gate enable*/ + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_BEEP_VOL, BEEP_VOL_12DB); + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADCA_MIXER_VOL, 0x80 | ADC_MIXER_VOL_12DB); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_ADCB_MIXER_VOL, 0x80 | ADC_MIXER_VOL_12DB); + } + soc_cs42l52_dai.dev = &i2c->dev; + + cs42l52_codec = soc_codec; + + ret = snd_soc_register_codec(soc_codec); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); + goto err; + } + + INIT_DELAYED_WORK(&soc_codec->delayed_work, soc_cs42l52_work); + + ret = snd_soc_register_dai(&soc_cs42l52_dai); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret); + goto err_codec; + } + + return ret; + +err_codec: + snd_soc_unregister_codec(soc_codec); +err: + kfree(cs42l52_codec); + cs42l52_codec = NULL; + return ret; +} + +static int cs42l52_i2c_remove(struct i2c_client *client) +{ + + snd_soc_unregister_dai(&soc_cs42l52_dai); + snd_soc_unregister_codec(cs42l52_codec); + + soc_cs42l52_set_bias_level(cs42l52_codec, SND_SOC_BIAS_OFF); + + soc_cs42l52_dai.dev = NULL; + if(cs42l52_codec->reg_cache) + kfree(cs42l52_codec->reg_cache); + if(cs42l52_codec->private_data) + kfree(cs42l52_codec->private_data); + kfree(cs42l52_codec); + cs42l52_codec = NULL; + + return 0; +} + +static const struct i2c_device_id cs42l52_i2c_id[] = { + { "cs42l52", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cs42l52_i2c_id); + +static struct i2c_driver cs42l52_i2c_drv = { + .driver = { + .name = "CS42L52", + .owner = THIS_MODULE, + }, + .probe = cs42l52_i2c_probe, + .remove = cs42l52_i2c_remove, + .id_table = cs42l52_i2c_id, + +}; + +#endif +#if 1 +static int soc_cs42l52_set_dai_clkdiv(struct snd_soc_dai *codec_dai, + int div_id, int div) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + + printk("soc_cs42l52_set_dai_clkdiv\n"); + return 0; +} + +#endif +static int soc_cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, u_int freq, int dir) +{ + int ret = 0; + struct snd_soc_codec *soc_codec = codec_dai->codec; + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*)soc_codec->private_data; + + if((freq >= SOC_CS42L52_MIN_CLK) && (freq <= SOC_CS42L52_MAX_CLK)) + { + info->sysclk = freq; + SOCDBG("sysclk %d\n", info->sysclk); + } + else{ + SOCDBG("invalid paramter\n"); + ret = -EINVAL; + } + return ret; +} + +static int soc_cs42l52_set_fmt(struct snd_soc_dai *codec_dai, + u_int fmt) +{ + struct snd_soc_codec *soc_codec = codec_dai->codec; + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*)soc_codec->private_data; + int ret = 0; + u8 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + + case SND_SOC_DAIFMT_CBM_CFM: + SOCDBG("codec dai fmt master\n"); + iface = IFACE_CTL1_MASTER; + break; + case SND_SOC_DAIFMT_CBS_CFS: + SOCDBG("codec dai fmt slave\n"); + break; + default: + SOCDBG("invaild formate\n"); + ret = -EINVAL; + goto done; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + + case SND_SOC_DAIFMT_I2S: + SOCDBG("codec dai fmt i2s\n"); + iface |= (IFACE_CTL1_ADC_FMT_I2S | IFACE_CTL1_DAC_FMT_I2S); + break; + case SND_SOC_DAIFMT_RIGHT_J: + SOCDBG("codec dai fmt right justified\n"); + iface |= IFACE_CTL1_DAC_FMT_RIGHT_J; + SOCINF("warning only playback stream support this format\n"); + break; + case SND_SOC_DAIFMT_LEFT_J: + SOCDBG("codec dai fmt left justified\n"); + iface |= (IFACE_CTL1_ADC_FMT_LEFT_J | IFACE_CTL1_DAC_FMT_LEFT_J); + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= IFACE_CTL1_DSP_MODE_EN; + break; + case SND_SOC_DAIFMT_DSP_B: + SOCINF("unsupported format\n"); + ret = -EINVAL; + goto done; + default: + SOCINF("invaild format\n"); + ret = -EINVAL; + goto done; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { /*tonyliu*/ + + case SND_SOC_DAIFMT_NB_NF: + SOCDBG("codec dai fmt normal sclk\n"); + break; + case SND_SOC_DAIFMT_IB_IF: + SOCDBG("codec dai fmt inversed sclk\n"); + iface |= IFACE_CTL1_INV_SCLK; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= IFACE_CTL1_INV_SCLK; + break; + case SND_SOC_DAIFMT_NB_IF: + break; + default: + SOCDBG("unsupported format\n"); + ret = -EINVAL; + } + + info->format = iface; +done: + return ret; + +} + +static int soc_cs42l52_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *soc_codec = dai->codec; + u8 mute_val = soc_cs42l52_read(soc_codec, CODEC_CS42L52_PB_CTL1) & PB_CTL1_MUTE_MASK; + + if(mute) + { + printk(KERN_INFO"soc_cs42l52_digital_mute=1 %d\n",mute_val); + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PB_CTL1, mute_val | PB_CTL1_MSTB_MUTE | PB_CTL1_MSTA_MUTE); + } + else{ + printk(KERN_INFO"soc_cs42l52_digital_mute=0 %d\n",mute_val); + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PB_CTL1, mute_val ); + } + + return 0; +} + +struct soc_cs42l52_clk_para { + u32 mclk; + u32 rate; + u8 speed; + u8 group; + u8 videoclk; + u8 ratio; + u8 mclkdiv2; +}; + +static const struct soc_cs42l52_clk_para clk_map_table[] = { + /*8k*/ + {12288000, 8000, CLK_CTL_S_QS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {18432000, 8000, CLK_CTL_S_QS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {12000000, 8000, CLK_CTL_S_QS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 0}, + {24000000, 8000, CLK_CTL_S_QS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 1}, + {27000000, 8000, CLK_CTL_S_QS_MODE, CLK_CTL_32K_SR, CLK_CTL_27M_MCLK, CLK_CTL_RATIO_125, 0}, /*4*/ + + /*11.025k*/ + {11289600, 11025, CLK_CTL_S_QS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {16934400, 11025, CLK_CTL_S_QS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + + /*16k*/ + {12288000, 16000, CLK_CTL_S_HS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {18432000, 16000, CLK_CTL_S_HS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {12000000, 16000, CLK_CTL_S_HS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 0},/*9*/ + {24000000, 16000, CLK_CTL_S_HS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 1}, + {27000000, 16000, CLK_CTL_S_HS_MODE, CLK_CTL_32K_SR, CLK_CTL_27M_MCLK, CLK_CTL_RATIO_125, 1}, + + /*22.05k*/ + {11289600, 22050, CLK_CTL_S_HS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {16934400, 22050, CLK_CTL_S_HS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + + /* 32k */ + {12288000, 32000, CLK_CTL_S_SS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0},/*14*/ + {18432000, 32000, CLK_CTL_S_SS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {12000000, 32000, CLK_CTL_S_SS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 0}, + {24000000, 32000, CLK_CTL_S_SS_MODE, CLK_CTL_32K_SR, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 1}, + {27000000, 32000, CLK_CTL_S_SS_MODE, CLK_CTL_32K_SR, CLK_CTL_27M_MCLK, CLK_CTL_RATIO_125, 0}, + + /* 44.1k */ + {11289600, 44100, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0},/*19*/ + {16934400, 44100, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + + /* 48k */ + {12288000, 48000, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {18432000, 48000, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {12000000, 48000, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 0}, + {24000000, 48000, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 1},/*24*/ + {27000000, 48000, CLK_CTL_S_SS_MODE, CLK_CTL_NOT_32K, CLK_CTL_27M_MCLK, CLK_CTL_RATIO_125, 1}, + + /* 88.2k */ + {11289600, 88200, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {16934400, 88200, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + + /* 96k */ + {12288000, 96000, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0}, + {18432000, 96000, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_128, 0},/*29*/ + {12000000, 96000, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 0}, + {24000000, 96000, CLK_CTL_S_DS_MODE, CLK_CTL_NOT_32K, CLK_CTL_NOT_27M, CLK_CTL_RATIO_125, 1}, +}; + +static int soc_cs42l52_get_clk(int mclk, int rate) +{ + + int i , ret = 0; + u_int mclk1, mclk2 = 0; + + for(i = 0; i < ARRAY_SIZE(clk_map_table); i++) + { + if(clk_map_table[i].rate == rate) + { + mclk1 = clk_map_table[i].mclk; + { + if(abs(mclk - mclk1) < abs(mclk - mclk2)) + { + mclk2 = mclk1; + ret = i; + } + } + } + } + + return ret < ARRAY_SIZE(clk_map_table) ? ret : -EINVAL; +} + +static int soc_cs42l52_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *soc_dev = rtd->socdev; + struct snd_soc_codec *soc_codec = soc_dev->card->codec; + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*)soc_codec->private_data; + + info->format = SOC_CS42L52_DEFAULT_FORMAT; + u32 clk = 0; + int index = soc_cs42l52_get_clk(info->sysclk, params_rate(params)); + + if(index >= 0) + { + info->sysclk = clk_map_table[index].mclk; + clk |= (clk_map_table[index].speed << CLK_CTL_SPEED_SHIFT) | + (clk_map_table[index].group << CLK_CTL_32K_SR_SHIFT) | + (clk_map_table[index].videoclk << CLK_CTL_27M_MCLK_SHIFT) | + (clk_map_table[index].ratio << CLK_CTL_RATIO_SHIFT) | + clk_map_table[index].mclkdiv2; +#ifdef CONFIG_MANUAL_CLK + soc_cs42l52_write(soc_codec, CODEC_CS42L52_CLK_CTL, clk); +#else + soc_cs42l52_write(soc_codec, CODEC_CS42L52_CLK_CTL, 0xa0); +#endif + soc_cs42l52_write(soc_codec, CODEC_CS42L52_IFACE_CTL1, info->format); + + } + else{ + SOCDBG("can't find out right mclk\n"); + ret = -EINVAL; + } + + return ret; +} + +int soc_cs42l52_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) +{ + u8 pwctl1 = soc_cs42l52_read(codec, CODEC_CS42L52_PWCTL1) & 0x9f; + u8 pwctl2 = soc_cs42l52_read(codec, CODEC_CS42L52_PWCTL2) & 0x07; + + switch (level) { + case SND_SOC_BIAS_ON: /* full On */ + SOCDBG("full on\n"); + break; + case SND_SOC_BIAS_PREPARE: /* partial On */ + SOCDBG("partial on\n"); + pwctl1 &= ~(PWCTL1_PDN_CHRG | PWCTL1_PDN_CODEC); + soc_cs42l52_write(codec, CODEC_CS42L52_PWCTL1, pwctl1); + break; + case SND_SOC_BIAS_STANDBY: /* Off, with power */ + SOCDBG("off with power\n"); + pwctl1 &= ~(PWCTL1_PDN_CHRG | PWCTL1_PDN_CODEC); + soc_cs42l52_write(codec, CODEC_CS42L52_PWCTL1, pwctl1); + break; + case SND_SOC_BIAS_OFF: /* Off, without power */ + SOCDBG("off without power\n"); + soc_cs42l52_write(codec, CODEC_CS42L52_PWCTL1, pwctl1 | 0x9f); + soc_cs42l52_write(codec, CODEC_CS42L52_PWCTL2, pwctl2 | 0x07); + break; + } + codec->bias_level = level; + return 0; +} + +static void soc_cs42l52_work(struct work_struct *work) +{ + struct snd_soc_codec *codec = + container_of(work, struct snd_soc_codec, delayed_work.work); + + soc_cs42l52_set_bias_level(codec, codec->bias_level); +} + +static int soc_cs42l52_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *soc_dev = (struct snd_soc_device*)platform_get_drvdata(pdev); + struct snd_soc_codec *soc_codec = soc_dev->card->codec; + + soc_cs42l52_write(soc_codec, CODEC_CS42L52_PWCTL1, PWCTL1_PDN_CODEC); + soc_cs42l52_set_bias_level(soc_codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int soc_cs42l52_resume(struct platform_device *pdev) +{ + struct snd_soc_device *soc_dev = (struct snd_soc_device*) platform_get_drvdata(pdev); + struct snd_soc_codec *soc_codec = soc_dev->card->codec; + struct soc_codec_cs42l52 *info = (struct soc_codec_cs42l52*) soc_codec->private_data; + int i, reg; + u8 data[2]; + u8 *reg_cache = (u8*) soc_codec->reg_cache; + soc_codec->num_dai = 1; + /* Sync reg_cache with the hardware */ + for(i = 0; i < soc_codec->num_dai; i++) { + + for(reg = 0; reg < ARRAY_SIZE(soc_cs42l52_reg_default); reg++) { + data[0] = reg; + data[1] = reg_cache[reg]; + if(soc_codec->hw_write(soc_codec->control_data, data, 2) != 2) + break; + } + } + + soc_cs42l52_set_bias_level(soc_codec, SND_SOC_BIAS_STANDBY); + + /*charge cs42l52 codec*/ + if(soc_codec->suspend_bias_level == SND_SOC_BIAS_ON) + { + soc_cs42l52_set_bias_level(soc_codec, SND_SOC_BIAS_PREPARE); + soc_codec->bias_level = SND_SOC_BIAS_ON; + schedule_delayed_work(&soc_codec->delayed_work, msecs_to_jiffies(1000)); + } + + return 0; + +} + +static int soc_cs42l52_probe(struct platform_device *pdev) +{ + struct snd_soc_device *soc_dev = platform_get_drvdata(pdev); + struct snd_soc_codec *soc_codec; + int ret = 0; + + if (cs42l52_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + soc_dev->card->codec = cs42l52_codec; + soc_codec = cs42l52_codec; + + ret = snd_soc_new_pcms(soc_dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if(ret) + { + SOCERR("%s: add new pcms failed\n",__FUNCTION__); + goto pcm_err; + } + /*init done*/ + + soc_cs42l52_add_controls(soc_codec); + + soc_cs42l52_add_widgets(soc_codec); + + ret = snd_soc_init_card(soc_dev); + + INIT_DELAYED_WORK(&soc_codec->delayed_work, soc_cs42l52_work); + + if(ret) + { + SOCERR("add snd card failed\n"); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(soc_dev); + snd_soc_dapm_free(soc_dev); +pcm_err: + return ret; + +} + +static int soc_cs42l52_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_cs42l52 = { + .probe = soc_cs42l52_probe, + .remove = soc_cs42l52_remove, + .suspend = soc_cs42l52_suspend, + .resume = soc_cs42l52_resume, +}; + +EXPORT_SYMBOL_GPL(soc_codec_dev_cs42l52); + +static int __init cs42l52_modinit(void) +{ + printk(KERN_INFO"cs42l52_i2c_probe\n"); + return i2c_add_driver(&cs42l52_i2c_drv); +} +module_init(cs42l52_modinit); + +static void __exit cs42l52_exit(void) +{ + printk(KERN_INFO"cs42l52_i2c_probe\n"); + i2c_del_driver(&cs42l52_i2c_drv); +} +module_exit(cs42l52_exit); + +MODULE_DESCRIPTION("ALSA SoC CS42L52 Codec"); +MODULE_AUTHOR("Bo Liu, Bo.Liu@cirrus.com, www.cirrus.com"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l52.h b/sound/soc/codecs/cs42l52.h new file mode 100755 index 000000000000..1c6568c8f25e --- /dev/null +++ b/sound/soc/codecs/cs42l52.h @@ -0,0 +1,323 @@ +/* + * cs42l52.h -- CS42L52 ALSA SoC audio driver + * + * Copyright 2007 CirrusLogic, Inc. + * + * Author: Bo Liu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * Revision history + * Nov 2007 Initial version. + */ + +#ifndef __CS42L52_H__ +#define __CS42L52_H__ + +#include +#include + + +#define SOC_CS42L52_NAME "CS42L52" +#define SOC_CS42L52_DEFAULT_CLK 12000000 +#define SOC_CS42L52_MIN_CLK 11000000 +#define SOC_CS42L52_MAX_CLK 27000000 +#define SOC_CS42L52_DEFAULT_FORMAT SNDRV_PCM_FMTBIT_S16_LE +#define SOC_CS42L52_DEFAULT_MAX_CHANS 2 +#define CS42L52_SYSCLK 1 + + +#define SOC_CS42L52_CHIP_SWICTH (1 << 17) +#define SOC_CS42L52_ALL_IN_ONE (1 << 16) +#define SOC_CS42L52_CHIP_ONE 0x00 +#define SOC_CS42L52_CHIP_TWO 0x01 +#define SOC_CS42L52_CHIP_THR 0x02 +#define SOC_CS42L52_CHIP_MASK 0x0f +#define CS42L52_PB_PIN_INVERRTED (1 << 3) +#define CS42L52_PB_PIN_LOW 0 +#define CS42L52_PB_PIN_HIGN 1 +#define CS42L52_PB_ALL_ON 2 +#define CS42L52_PB_ALL_OFF 3 + +struct soc_codec_cs42l52 { + void (*machine_handler)(unsigned int codec_num); + u_int max_playback_stream; + u_int max_capture_stream; + u_int num_dai; + u_int pb_pin_sel; + u_int pb_sel; + u_int adc_sel1; + u_int adc_sel2; + u_int mic_sel; + u_int sysclk; + u_int format; + u_int flags; +}; + +struct soc_codec_cs42l52_data{ + int i2c_bus; + u_short i2c_addr; +}; +/* + *CS42L52 internal registers + */ +#define CODEC_CS42L52_CHIP 0x01 +#define CHIP_ID 0xE0 +#define CHIP_ID_MASK 0xF8 +#define CHIP_REV_A0 0x00 +#define CHIP_REV_A1 0x01 +#define CHIP_REV_B0 0x02 +#define CHIP_REV_MASK 0x03 + +#define CODEC_CS42L52_PWCTL1 0x02 //0x01 +#define PWCTL1_PDN_CHRG (1 << 7) +#define PWCTL1_PDN_PGAB (1 << 4) +#define PWCTL1_PDN_PGAB_SHIFT 4 +#define PWCTL1_PDN_PGAA (1 << 3) +#define PWCTL1_PDN_PGAA_SHIFT 3 +#define PWCTL1_PDN_ADCB (1 << 2) +#define PWCTL1_PDN_ADCB_SHIFT 2 +#define PWCTL1_PDN_ADCA (1 << 1) +#define PWCTL1_PDN_ADCA_SHIFT 1 +#define PWCTL1_PDN_CODEC (1 << 0) + +#define CODEC_CS42L52_PWCTL2 0x03 //0x07 +#define PWCTL2_OVRDB (1 << 4) +#define PWCTL2_OVRDA (1 << 3) +#define PWCTL2_PDN_MICB (1 << 2) +#define PWCTL2_PDN_MICB_SHIFT 2 +#define PWCTL2_PDN_MICA (1 << 1) +#define PWCTL2_PDN_MICA_SHIFT 1 +#define PWCTL2_PDN_MICBIAS (1 << 0) +#define PWCTL2_PDN_MICBIAS_SHIFT 0 + +#define CODEC_CS42L52_PWCTL3 0x04 //0x08 +#define PWCTL3_HPB_PDN_SHIFT 6 +#define PWCTL3_HPB_ON_LOW 0x00 +#define PWCTL3_HPB_ON_HIGH 0x01 +#define PWCTL3_HPB_ALWAYS_ON 0x02 +#define PWCTL3_HPB_ALWAYS_OFF 0x03 +#define PWCTL3_HPA_PDN_SHIFT 4 +#define PWCTL3_HPA_ON_LOW 0x00 +#define PWCTL3_HPA_ON_HIGH 0x01 +#define PWCTL3_HPA_ALWAYS_ON 0x02 +#define PWCTL3_HPA_ALWAYS_OFF 0x03 +#define PWCTL3_SPKB_PDN_SHIFT 2 +#define PWCTL3_SPKB_ON_LOW 0x00 +#define PWCTL3_SPKB_ON_HIGH 0x01 +#define PWCTL3_SPKB_ALWAYS_ON 0x02 +#define PWCTL3_SPKB_ALWAYS_OFF 0x03 +#define PWCTL3_SPKA_PDN_SHIFT 0 +#define PWCTL3_SPKA_ON_LOW 0x00 +#define PWCTL3_SPKA_ON_HIGH 0x01 +#define PWCTL3_SPKA_ALWAYS_ON 0x02 +#define PWCTL3_SPKA_ALWAYS_OFF 0x03 +#define DEFAULT_OUTPUT_STATE 0x05 +#define PWCTL3_CONF_MASK 0x03 + + + +#define CODEC_CS42L52_CLK_CTL 0x05 //0xa0 +#define CLK_CTL_AUTODECT_ENABLE (1 << 7) +#define CLK_CTL_SPEED_SHIFT 5 +#define CLK_CTL_S_DS_MODE 0x00 +#define CLK_CTL_S_SS_MODE 0x01 +#define CLK_CTL_S_HS_MODE 0x02 +#define CLK_CTL_S_QS_MODE 0x03 +#define CLK_CTL_32K_SR_SHIFT 4 +#define CLK_CTL_32K_SR 1 +#define CLK_CTL_NOT_32K 0 +#define CLK_CTL_27M_MCLK_SHIFT 3 +#define CLK_CTL_27M_MCLK 1 +#define CLK_CTL_NOT_27M 0 +#define CLK_CTL_RATIO_SHIFT 1 +#define CLK_CTL_RATIO_128 0x00 +#define CLK_CTL_RATIO_125 0x01 +#define CLK_CTL_RATIO_132 0x02 +#define CLK_CTL_RATIO_136 0x03 +#define CLK_CTL_MCLKDIV2 1 +#define CLK_CTL_NOT_MCLKDIV2 0 + + +#define CODEC_CS42L52_IFACE_CTL1 0x06 //0 +#define IFACE_CTL1_MASTER (1 << 7) +#define IFACE_CTL1_INV_SCLK (1 << 6) +#define IFACE_CTL1_ADC_FMT_I2S (1 << 5) +#define IFACE_CTL1_ADC_FMT_LEFT_J (0 << 5) +#define IFACE_CTL1_DSP_MODE_EN (1 << 4) +#define IFACE_CTL1_DAC_FMT_LEFT_J (0 << 2) +#define IFACE_CTL1_DAC_FMT_I2S (1 << 2) +#define IFACE_CTL1_DAC_FMT_RIGHT_J (2 << 2) +#define IFACE_CTL1_WL_32BIT (0x00) +#define IFACE_CTL1_WL_24BIT (0x01) +#define IFACE_CTL1_WL_20BIT (0x02) +#define IFACE_CTL1_WL_16BIT (0x03) +#define IFACE_CTL1_WL_MASK 0xFFFF + + +#define CODEC_CS42L52_IFACE_CTL2 0x07 //0 +#define IFACE_CTL2_SC_MC_EQ (1 << 6) +#define IFACE_CTL2_LOOPBACK (1 << 5) +#define IFACE_CTL2_S_MODE_OUTPUT_EN (0 << 4) +#define IFACE_CTL2_S_MODE_OUTPUT_HIZ (1 << 4) +#define IFACE_CTL2_HP_SW_INV (1 << 3) +#define IFACE_CTL2_MIC_BIAS_5X 0x00 +#define IFACE_CTL2_MIC_BIAS_6X 0x01 +#define IFACE_CTL2_MIC_BIAS_7X 0x02 +#define IFACE_CTL2_MIC_BIAS_8X 0x03 +#define IFACE_CTL2_MIC_BIAS_83X 0x04 +#define IFACE_CTL2_MIC_BIAS_91X 0x05 + +#define CODEC_CS42L52_ADC_PGA_A 0x08 //0x81 +#define CODEC_CS42L52_ADC_PGA_B 0x09 //0x81 +#define ADC_SEL_SHIFT 5 +#define PGA_SEL_SHIFT 0 +#define ADC_SEL_AIN1 0x00 +#define ADC_SEL_AIN2 0x01 +#define ADC_SEL_AIN3 0x02 +#define ADC_SEL_AIN4 0x03 +#define ADC_SEL_PGA 0x04 +#define PGA_SEL_NONE 0x00 +#define PGA_SEL_AIN1 0x01 +#define PGA_SEL_AIN2 0x02 +#define PGA_SEL_AIN3 0x04 +#define PGA_SEL_AIN4 0x08 +#define PGA_SEL_MIC 0x10 +#define PGA_SEL_MIC_AIN1 0x11 +#define PGA_SEL_MIC_AIN1_AIN2 0x13 + +#define CODEC_CS42L52_ANALOG_HPF_CTL 0x0A //0xa5 +#define HPF_CTL_ANLGSFTB (1 << 3) +#define HPF_CTL_ANLGSFTA (1 << 0) + + +#define CODEC_CS42L52_ADC_HPF_FREQ 0x0B //0 +#define CODEC_CS42L52_ADC_MISC_CTL 0x0C //0 +#define ADC_MISC_CTL_SOURCE_DSP (1 << 6) + + +#define CODEC_CS42L52_PB_CTL1 0x0D //0x60 +#define PB_CTL1_HP_GAIN_SHIFT 5 +#define PB_CTL1_HP_GAIN_03959 0x00 +#define PB_CTL1_HP_GAIN_04571 0x01 +#define PB_CTL1_HP_GAIN_05111 0x02 +#define PB_CTL1_HP_GAIN_06047 0x03 +#define PB_CTL1_HP_GAIN_07099 0x04 +#define PB_CTL1_HP_GAIN_08399 0x05 +#define PB_CTL1_HP_GAIN_10000 0x06 +#define PB_CTL1_HP_GAIN_11430 0x07 +#define PB_CTL1_INV_PCMB (1 << 3) +#define PB_CTL1_INV_PCMA (1 << 2) +#define PB_CTL1_MSTB_MUTE (1 << 1) +#define PB_CTL1_MSTA_MUTE (1 << 0) +#define PB_CTL1_MUTE_MASK 0xFFFC + +#define CODEC_CS42L52_MISC_CTL 0x0E //0x02 +#define MISC_CTL_DEEMPH (1 << 2) +#define MISC_CTL_DIGSFT (1 << 1) +#define MISC_CTL_DIGZC (1 << 0) + + +#define CODEC_CS42L52_PB_CTL2 0x0F //0 +#define PB_CTL2_HPB_MUTE (1 << 7) +#define PB_CTL2_HPA_MUTE (1 << 6) +#define PB_CTL2_SPKB_MUTE (1 << 5) +#define PB_CTL2_SPKA_MUTE (1 << 4) +#define PB_CTL2_SPK_SWAP (1 << 2) +#define PB_CTL2_SPK_MONO (1 << 1) +#define PB_CTL2_SPK_MUTE50 (1 << 0) + +#define CODEC_CS42L52_MICA_CTL 0x10 //0 +#define CODEC_CS42L52_MICB_CTL 0x11 //0 +#define MIC_CTL_SEL_MIC1 (0 << 6) +#define MIC_CTL_SEL_MIC2 (1 << 6) +#define MIC_CTL_SEL_DIFF (1 << 5) + +#define CODEC_CS42L52_PGAA_CTL 0x12 //0 +#define CODEC_CS42L52_PGAB_CTL 0x13 //0 +#define PGAX_CTL_VOL_12DB 24 +#define PGAX_CTL_VOL_6DB 12 /*step size 0.5db*/ + +#define CODEC_CS42L52_PASSTHRUA_VOL 0x14 //0 +#define CODEC_CS42L52_PASSTHRUB_VOL 0x15 //0 + +#define CODEC_CS42L52_ADCA_VOL 0x16 //0 +#define CODEC_CS42L52_ADCB_VOL 0x17 //0 +#define ADCX_VOL_24DB 24 /*step size 1db*/ +#define ADCX_VOL_12DB 12 +#define ADCX_VOL_6DB 6 + +#define CODEC_CS42L52_ADCA_MIXER_VOL 0x18 // 0x80 +#define CODEC_CS42L52_ADCB_MIXER_VOL 0x19 //0x80 +#define ADC_MIXER_VOL_12DB 0x18 + +#define CODEC_CS42L52_PCMA_MIXER_VOL 0x1A //0 +#define CODEC_CS42L52_PCMB_MIXER_VOL 0x1B //0 + +#define CODEC_CS42L52_BEEP_FREQ 0x1C //0 +#define CODEC_CS42L52_BEEP_VOL 0x1D //0 +#define BEEP_VOL_12DB 0x06 + + +#define CODEC_CS42L52_BEEP_TONE_CTL 0x1E //0 + +#define CODEC_CS42L52_TONE_CTL 0x1F //0x88 + +#define CODEC_CS42L52_MASTERA_VOL 0x20 //0 +#define CODEC_CS42L52_MASTERB_VOL 0x21 //0 + +#define CODEC_CS42L52_HPA_VOL 0x22 //0 +#define CODEC_CS42L52_HPB_VOL 0x23 //0 +#define DEFAULT_HP_VOL 0x00 + +#define CODEC_CS42L52_SPKA_VOL 0x24 //0 +#define CODEC_CS42L52_SPKB_VOL 0x25 //0 +#define DEFAULT_SPK_VOL 0x00 + +#define CODEC_CS42L52_ADC_PCM_MIXER 0x26 //0 + +#define CODEC_CS42L52_LIMITER_CTL1 0x27 //0 +#define CODEC_CS42L52_LIMITER_CTL2 0x28 //0x7f +#define CODEC_CS42L52_LIMITER_AT_RATE 0x29 //0xc0 + +#define CODEC_CS42L52_ALC_CTL 0x2A //0 +#define ALC_CTL_ALCB_ENABLE (1 << 7) +#define ALC_CTL_ALCA_ENABLE (1 << 6) +#define ALC_CTL_FASTEST_ATTACK 0 + +#define CODEC_CS42L52_ALC_RATE 0x2B //0x3f +#define ALC_SLOWEST_RELEASE 0x3F + +#define CODEC_CS42L52_ALC_THRESHOLD 0x2C //0 +#define ALC_MAX_RATE_SHIFT 5 +#define ALC_MIN_RATE_SHIFT 2 +#define ALC_RATE_0DB 0 +#define ALC_RATE_3DB 1 +#define ALC_RATE_6DB 2 + +#define CODEC_CS42L52_NOISE_GATE_CTL 0x2D //0 +#define NG_ENABLE (1 << 6) +#define NG_THRESHOLD_SHIFT 2 +#define NG_MIN_70DB 2 +#define NG_DELAY_SHIFT 0 +#define NG_DELAY_100MS 1 + +#define CODEC_CS42L52_CLK_STATUS 0x2E //0 +#define CODEC_CS42L52_BATT_COMPEN 0x2F //0 + +#define CODEC_CS42L52_BATT_LEVEL 0x30 //0 +#define CODEC_CS42L52_SPK_STATUS 0x31 //0 +#define SPK_STATUS_PIN_SHIFT 3 +#define SPK_STATUS_PIN_HIGH 1 + +#define CODEC_CS42L52_TEM_CTL 0x32 //0x3b +#define CODEC_CS42L52_THE_FOLDBACK 0x33 //0 +#define CODEC_CS42L52_CHARGE_PUMP 0x34 //0x5f + + +#define SOC_CS42L52_REG_NUM 56 + +extern struct snd_soc_codec_device soc_codec_dev_cs42l52; +extern struct snd_soc_dai soc_cs42l52_dai; +#endif diff --git a/sound/soc/rk29/Kconfig b/sound/soc/rk29/Kconfig index 7d5c97f7066c..a6ac20ef8214 100644 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -74,6 +74,15 @@ config SND_RK29_SOC_WM8994 help Say Y if you want to add support for SoC audio on rockchip with the WM8994. + +config SND_RK29_SOC_CS42L52 + tristate "SoC I2S Audio support for rockchip - CS42L52" + depends on SND_RK29_SOC && I2C_RK29 + select SND_RK29_SOC_I2S + select SND_SOC_CS42L52 + help + Say Y if you want to add support for SoC audio on rockchip + with the CS42L52. config SND_RK29_SOC_RK1000 tristate "SoC I2S Audio support for rockchip - RK1000" @@ -84,7 +93,7 @@ config SND_RK29_SOC_RK1000 Say Y if you want to add support for SoC audio on rockchip with the RK1000. -if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_alc5621 || SND_RK29_SOC_alc5631 || SND_RK29_SOC_RT5625 +if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_alc5621 || SND_RK29_SOC_alc5631 || SND_RK29_SOC_RT5625 || SND_RK29_SOC_CS42L52 choice prompt "Set i2s type" config SND_RK29_CODEC_SOC_MASTER diff --git a/sound/soc/rk29/Makefile b/sound/soc/rk29/Makefile index f4a9f8c4e333..f10294f7f32a 100644 --- a/sound/soc/rk29/Makefile +++ b/sound/soc/rk29/Makefile @@ -10,6 +10,7 @@ snd-soc-wm8900-objs := rk29_wm8900.o snd-soc-alc5621-objs := rk29_alc5621.o snd-soc-alc5631-objs := rk29_rt5631.o snd-soc-rt5625-objs := rk29_rt5625.o +snd-soc-cs42l52-objs := rk29_cs42l52.o snd-soc-wm8988-objs := rk29_wm8988.o snd-soc-rk1000-objs := rk29_rk1000codec.o snd-soc-wm8994-objs := rk29_wm8994.o @@ -21,3 +22,4 @@ obj-$(CONFIG_SND_RK29_SOC_alc5621) += snd-soc-alc5621.o obj-$(CONFIG_SND_RK29_SOC_alc5631) += snd-soc-alc5631.o obj-$(CONFIG_SND_RK29_SOC_RT5625) += snd-soc-rt5625.o obj-$(CONFIG_SND_RK29_SOC_RK1000) += snd-soc-rk1000.o +obj-$(CONFIG_SND_RK29_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/rk29/rk29_cs42l52.c b/sound/soc/rk29/rk29_cs42l52.c new file mode 100755 index 000000000000..2e61bf26cba2 --- /dev/null +++ b/sound/soc/rk29/rk29_cs42l52.c @@ -0,0 +1,218 @@ +/* + * rk29_cs42l52.c -- SoC audio for rockchip + * + * Driver for rockchip cs42l52 audio + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../codecs/cs42l52.h" +#include "rk29_pcm.h" +#include "rk29_i2s.h" + +#if 1 +#define DBG(x...) printk(KERN_INFO x) +#else +#define DBG(x...) +#endif + +static int rk29_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + unsigned int pll_out = 0; + unsigned int lrclk = 0; + int ret; + + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + /*by Vincent Hsiung for EQ Vol Change*/ + #define HW_PARAMS_FLAG_EQVOL_ON 0x21 + #define HW_PARAMS_FLAG_EQVOL_OFF 0x22 + if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF)) + { + ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + } + else + { + + /* set codec DAI configuration */ + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + #endif + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); + #endif + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + #endif + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + #endif + if (ret < 0) + return ret; + + } + + + switch(params_rate(params)) { + case 8000: + case 16000: + case 24000: + case 32000: + case 48000: + pll_out = 12288000; + break; + case 11025: + case 22050: + case 44100: + pll_out = 11289600; + break; + default: + DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params)); + return -EINVAL; + break; + } + DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params)); + + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + // + // + #endif + + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3); + #endif + DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params)); + + return 0; +} + +static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { + SND_SOC_DAPM_LINE("Audio Out", NULL), + SND_SOC_DAPM_LINE("Line in", NULL), + SND_SOC_DAPM_MIC("Micn", NULL), + SND_SOC_DAPM_MIC("Micp", NULL), +}; + +static const struct snd_soc_dapm_route audio_map[]= { + + {"Audio Out", NULL, "HPA"}, + {"Audio Out", NULL, "HPB"}, + {"Line in", NULL, "INPUT1A"}, + {"Line in", NULL, "INPUT1B"}, + {"Micn", NULL, "INPUT2A"}, + {"Micp", NULL, "INPUT2B"}, +}; + +/* + * Logic for a cs42l52 as connected on a rockchip board. + */ +static int rk29_cs42l52_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dai *codec_dai = &codec->dai[0]; + int ret; + + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + + /* Add specific widgets */ + snd_soc_dapm_new_controls(codec, cs42l52_dapm_widgets, + ARRAY_SIZE(cs42l52_dapm_widgets)); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + /* Set up specific audio path audio_mapnects */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + snd_soc_dapm_nc_pin(codec, "HPA"); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + snd_soc_dapm_nc_pin(codec, "HPB"); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + snd_soc_dapm_sync(codec); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + return 0; +} + +static struct snd_soc_ops rk29_ops = { + .hw_params = rk29_hw_params, +}; + +static struct snd_soc_dai_link rk29_dai = { + .name = "CS42L52", + .stream_name = "CS42L52 PCM", + .cpu_dai = &rk29_i2s_dai[0], + .codec_dai = &soc_cs42l52_dai, + .init = rk29_cs42l52_init, + .ops = &rk29_ops, +}; + +static struct snd_soc_card snd_soc_card_rk29 = { + .name = "RK29_CS42L52", + .platform = &rk29_soc_platform, + .dai_link = &rk29_dai, + .num_links = 1, +}; + + +static struct snd_soc_device rk29_snd_devdata = { + .card = &snd_soc_card_rk29, + .codec_dev = &soc_codec_dev_cs42l52, +}; + +static struct platform_device *rk29_snd_device; + +static int __init audio_card_init(void) +{ + int ret =0; + DBG("Enter::%s----%d\n",__FUNCTION__, __LINE__); + rk29_snd_device = platform_device_alloc("soc-audio", -1); + if (!rk29_snd_device) { + DBG("platform device allocation failed\n"); + ret = -ENOMEM; + return ret; + } + platform_set_drvdata(rk29_snd_device, &rk29_snd_devdata); + rk29_snd_devdata.dev = &rk29_snd_device->dev; + ret = platform_device_add(rk29_snd_device); + if (ret) { + DBG("platform device add failed\n"); + platform_device_put(rk29_snd_device); + } + return ret; +} + +static void __exit audio_card_exit(void) +{ + platform_device_unregister(rk29_snd_device); +} + +module_init(audio_card_init); +module_exit(audio_card_exit); +/* Module information */ +MODULE_AUTHOR("rockchip"); +MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface"); +MODULE_LICENSE("GPL"); -- 2.34.1