diff --git a/Makefile b/Makefile index 39516bf..d6bc839 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,9 @@ SUBLEVEL = 25 EXTRAVERSION = NAME = Funky Weasel is Jiggy wit it +ARCH=arm +CROSS_COMPILE=arm-none-linux-gnueabi- + # *DOCUMENTATION* # To see a list of typical targets execute "make help" # More info can be located in ./README diff --git a/arch/arm/configs/htckaiser_defconfig b/arch/arm/configs/htckaiser_defconfig new file mode 100644 index 0000000..a418c6e --- /dev/null +++ b/arch/arm/configs/htckaiser_defconfig @@ -0,0 +1,769 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24 +# Sun May 18 17:21:36 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_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_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# 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=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +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=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +# CONFIG_ASHMEM is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_GOLDFISH 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_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# 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_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_ARCH_MSM7X00A=y + +# +# Boot options +# + +# +# Power management +# + +# +# MSM7X00A Board Type +# +# CONFIG_MACH_HALIBUT is not set +CONFIG_MSM7X00=y +# CONFIG_MACH_HTCVOGUE is not set +CONFIG_MACH_HTCKAISER=y +# CONFIG_MACH_HTCTITAN is not set +CONFIG_MSM_KAISERSMD=y +# CONFIG_MSM_7X00SMD is not set +# CONFIG_MSM_LL_DEBUG_UART1 is not set +# CONFIG_MSM_LL_DEBUG_UART2 is not set +# CONFIG_MSM_LL_DEBUG_UART3 is not set +CONFIG_MSM_LL_DEBUG_NONE=y +# CONFIG_MSM7X00A_IDLE is not set +# CONFIG_MSM7X00A_SLEEP_MODE_POWER_COLLAPSE_SUSPEND is not set +# CONFIG_MSM7X00A_SLEEP_MODE_POWER_COLLAPSE is not set +# CONFIG_MSM7X00A_SLEEP_MODE_APPS_SLEEP is not set +# CONFIG_MSM7X00A_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT is not set +CONFIG_MSM7X00A_SLEEP_WAIT_FOR_INTERRUPT=y +CONFIG_MSM7X00A_SLEEP_MODE=4 +CONFIG_MSM_FIQ_SUPPORT=y +# CONFIG_MSM_SERIAL_DEBUGGER is not set +# CONFIG_MSM_SMD is not set +# CONFIG_MSM_HW3D is not set +# CONFIG_MSM_ADSP is not set +# CONFIG_MSM_PERF is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_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_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_ISDN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +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_SLIP is not set +CONFIG_SLHC=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_MSM_RMNET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_GOLDFISH_EVENTS 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_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_GPIO=y + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=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_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DEVMEM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_GOLDFISH_TTY is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_MSM=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +CONFIG_HTC_EGPIO=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC 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_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_MSM=y +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Android +# +CONFIG_ANDROID_PMEM=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=y +# CONFIG_ANDROID_RAM_CONSOLE is not set +# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# Miscellaneous filesystems +# +# 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_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set +# CONFIG_INSTRUMENTATION is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y \ No newline at end of file diff --git a/arch/arm/configs/htcpolaris_defconfig b/arch/arm/configs/htcpolaris_defconfig new file mode 100644 index 0000000..ce109f1 --- /dev/null +++ b/arch/arm/configs/htcpolaris_defconfig @@ -0,0 +1,789 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24 +# Sun May 18 17:21:36 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_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_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# 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=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +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=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_ASHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_GOLDFISH 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_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# 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_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_ARCH_MSM7X00A=y + +# +# Boot options +# + +# +# Power management +# + +# +# MSM7X00A Board Type +# +# CONFIG_MACH_HALIBUT is not set +CONFIG_MSM7X00=y +# CONFIG_MACH_HTCVOGUE is not set +# CONFIG_MACH_HTCKAISER is not set +# CONFIG_MACH_HTCTITAN is not set +CONFIG_MACH_HTCPOLARIS=y +# CONFIG_MSM_KAISERSMD is not set +# CONFIG_MSM_7X00SMD is not set +# CONFIG_MSM_LL_DEBUG_UART1 is not set +# CONFIG_MSM_LL_DEBUG_UART2 is not set +# CONFIG_MSM_LL_DEBUG_UART3 is not set +CONFIG_MSM_LL_DEBUG_NONE=y +# CONFIG_MSM7X00A_IDLE is not set +# CONFIG_MSM7X00A_SLEEP_MODE_POWER_COLLAPSE_SUSPEND is not set +# CONFIG_MSM7X00A_SLEEP_MODE_POWER_COLLAPSE is not set +# CONFIG_MSM7X00A_SLEEP_MODE_APPS_SLEEP is not set +# CONFIG_MSM7X00A_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT is not set +CONFIG_MSM7X00A_SLEEP_WAIT_FOR_INTERRUPT=y +CONFIG_MSM7X00A_SLEEP_MODE=4 +CONFIG_MSM_FIQ_SUPPORT=y +# CONFIG_MSM_SERIAL_DEBUGGER is not set +# CONFIG_MSM_SMD is not set +# CONFIG_MSM_HW3D is not set +# CONFIG_MSM_ADSP is not set +# CONFIG_MSM_PERF is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_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_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_ISDN is not set + +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +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_SLIP is not set +CONFIG_SLHC=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_MSM_RMNET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_GOLDFISH_EVENTS 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_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_GPIO=y + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=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_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DEVMEM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_GOLDFISH_TTY is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_MSM=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +CONFIG_HTC_EGPIO=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC 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_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_MSM=y +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_EMBEDDED_SDIO=y + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_MSM7X00A=y +CONFIG_MSMSDCC_TRACE=y +#CONFIG_NEW_LEDS is not set + +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Android +# +CONFIG_ANDROID_PMEM=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=y +# CONFIG_ANDROID_RAM_CONSOLE is not set +# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# Miscellaneous filesystems +# +# 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_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set +# CONFIG_INSTRUMENTATION is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-msm/7x00-irq.c b/arch/arm/mach-msm/7x00-irq.c new file mode 100644 index 0000000..20e0581 --- /dev/null +++ b/arch/arm/mach-msm/7x00-irq.c @@ -0,0 +1,306 @@ +/* linux/arch/arm/mach-msm/7x00-irq.c + * Author: Martin Johnson + * Based on irq.c by Brian Swetland + * + * 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 + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +// just a guess but it works + +#define VIC_INT_0 VIC_REG(0x0000) +#define VIC_INT_1 VIC_REG(0x0004) + +#define VIC_INT_EN0 VIC_REG(0x0028) +#define VIC_INT_EN1 VIC_REG(0x002c) + +#define VIC_INT_CLEAR0 VIC_REG(0x0018) +#define VIC_INT_CLEAR1 VIC_REG(0x001c) + +#define VIC_INT_MASK0 VIC_REG(0x0040) +#define VIC_INT_MASK1 VIC_REG(0x0044) + +// these are wrong +// #define VIC_INT_POLARITY0 VIC_REG(0x0070) +// #define VIC_INT_POLARITY1 VIC_REG(0x0074) + +#define VIC_INT_TYPE0 VIC_REG(0x0070) +#define VIC_INT_TYPE1 VIC_REG(0x0074) + +#define VIC_INT_MASTEREN VIC_REG(0x0060) + +#define VIC_INT_SELECT0 VIC_REG(0x0020) +#define VIC_INT_SELECT1 VIC_REG(0x0024) + +#define VIC_INT_FIQ0 VIC_REG(0x08) +#define VIC_INT_FIQ1 VIC_REG(0x0c) + +#define VIC_SOFTINT0 VIC_REG(0x50) +#define VIC_SOFTINT1 VIC_REG(0x54) + +enum { + IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0, + IRQ_DEBUG_SLEEP_INT = 1U << 1, + IRQ_DEBUG_SLEEP_ABORT = 1U << 2, + IRQ_DEBUG_SLEEP = 1U << 3, + IRQ_DEBUG_SLEEP_REQUEST = 1U << 4, +}; +static int msm_irq_debug_mask=0x1f; +module_param_named(debug_mask, msm_irq_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +static uint32_t msm_irq_smsm_wake_enable[2]; + + +static uint32_t msm_irq_wake_enable[2]; + +static struct { + uint32_t int_en[2]; + uint32_t int_type; + uint32_t int_polarity; + uint32_t int_select; +} msm_irq_shadow_reg[2]; + +static void msm_irq_ack(unsigned int irq) +{ + unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0); + irq = 1 << (irq & 31); + writel(irq, reg); +} + +static void msm_irq_mask(unsigned int irq) +{ + unsigned reg = VIC_INT_MASK0 + ((irq & 32) ? 4 : 0); + unsigned index = (irq >> 5) & 1; + uint32_t mask = 1UL << (irq & 31); + msm_irq_shadow_reg[index].int_en[0] &= ~mask; + writel(mask, reg); +} + +static void msm_irq_unmask(unsigned int irq) +{ + unsigned reg = VIC_INT_EN0 + ((irq & 32) ? 4 : 0); + unsigned index = (irq >> 5) & 1; + uint32_t mask = 1UL << (irq & 31); + msm_irq_shadow_reg[index].int_en[0] |= mask; + writel(readl(reg) | mask, reg); +} + +static int msm_irq_set_wake(unsigned int irq, unsigned int on) +{ + unsigned index = (irq >> 5) & 1; + uint32_t mask = 1UL << (irq & 31); + if (on) + { + msm_irq_wake_enable[index] |= mask; + msm_irq_smsm_wake_enable[index] |= mask; + } + else + { + msm_irq_wake_enable[index] &= ~mask; + msm_irq_smsm_wake_enable[index] &= ~mask; + } + return 0; +} + +static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0); + unsigned index = (irq >> 5) & 1; + int b = 1 << (irq & 31); + uint32_t polarity; + uint32_t type; + + printk("set_type %d %d\n",irq,flow_type); + polarity = msm_irq_shadow_reg[index].int_polarity; + if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) + polarity |= b; + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) + polarity &= ~b; + //writel(polarity, preg); + msm_irq_shadow_reg[index].int_polarity = polarity; + + type = msm_irq_shadow_reg[index].int_type; + if (flow_type & (IRQF_TRIGGER_RISING)) { // | IRQF_TRIGGER_FALLING)) { + type |= b; + // irq_desc[irq].handle_irq = handle_edge_irq; + } + /* + if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { + type &= ~b; + irq_desc[irq].handle_irq = handle_level_irq; + } + */ + writel(type, treg); + msm_irq_shadow_reg[index].int_type = type; + return 0; +} + +void msm_irq_enter_sleep(bool arm9_wake) +{ + writel(0, VIC_INT_EN0); + writel(0, VIC_INT_EN1); + + /* + if (arm9_wake) { + msm_irq_set_type(INT_A9_M2A_6, IRQF_TRIGGER_RISING); + writel(1U << INT_A9_M2A_6, VIC_INT_EN0); + } else { + writel(msm_irq_wake_enable[0], VIC_INT_EN0); + writel(msm_irq_wake_enable[1], VIC_INT_EN1); + } + */ + writel(1U<<3, VIC_INT_EN0); // enable modem irq + writel(2,VIC_INT_EN1); // enable gpio irq +// disable_irq(33+64); +} + +void msm_irq_exit_sleep(void) +{ + int i; + msm_irq_ack(INT_A9_M2A_6); + for (i = 0; i < 2; i++) { +// writel(msm_irq_shadow_reg[i].int_type, VIC_INT_TYPE0 + i * 4); +// writel(msm_irq_shadow_reg[i].int_polarity, VIC_INT_POLARITY0 + i * 4); + writel(msm_irq_shadow_reg[i].int_en, VIC_INT_EN0 + i * 4); +// writel(msm_irq_shadow_reg[i].int_select, VIC_INT_SELECT0 + i * 4); + } +// enable_irq(33+64); +} + +#if defined(CONFIG_MSM_FIQ_SUPPORT) +void msm_trigger_irq(int irq) +{ + unsigned reg = VIC_SOFTINT0 + ((irq & 32) ? 4 : 0); + uint32_t mask = 1UL << (irq & 31); + unsigned long flags; + writel(mask, reg); +} + +void msm_fiq_enable(int irq) +{ + unsigned long flags; + local_irq_save(flags); + msm_irq_unmask(irq); + local_irq_restore(flags); +} + +void msm_fiq_disable(int irq) +{ + unsigned long flags; + local_irq_save(flags); + msm_irq_mask(irq); + local_irq_restore(flags); +} + +void msm_fiq_select(int irq) +{ + unsigned reg = VIC_INT_SELECT0 + ((irq & 32) ? 4 : 0); + unsigned index = (irq >> 5) & 1; + uint32_t mask = 1UL << (irq & 31); + unsigned long flags; + + local_irq_save(flags); + msm_irq_shadow_reg[index].int_select |= mask; + writel(msm_irq_shadow_reg[index].int_select, reg); + local_irq_restore(flags); +} + +/* set_fiq_handler originally from arch/arm/kernel/fiq.c */ +static void set_fiq_handler(void *start, unsigned int length) +{ + memcpy((void *)0xffff001c, start, length); + flush_icache_range(0xffff001c, 0xffff001c + length); + if (!vectors_high()) + flush_icache_range(0x1c, 0x1c + length); +} + +extern unsigned char fiq_glue, fiq_glue_end; + +static void (*fiq_func)(void *data, void *regs); +static unsigned long long fiq_stack[256]; + +void fiq_glue_setup(void *func, void *data, void *sp); +int msm_fiq_set_handler(void (*func)(void *data, void *regs), void *data) +{ + unsigned long flags; + int ret = -ENOMEM; + + local_irq_save(flags); + if (fiq_func == 0) { + fiq_func = func; + fiq_glue_setup(func, data, fiq_stack + 255); + set_fiq_handler(&fiq_glue, (&fiq_glue_end - &fiq_glue)); + ret = 0; + } + local_irq_restore(flags); + return ret; +} +#endif + + +static struct irq_chip msm_irq_chip = { + .name = "msm", + .ack = msm_irq_ack, + .mask = msm_irq_mask, + .unmask = msm_irq_unmask, + .set_wake = msm_irq_set_wake, + .set_type = msm_irq_set_type, +}; + +void __init msm_init_irq(void) +{ + unsigned n; + /* disable all INTs */ + writel(0, VIC_INT_EN0); + writel(0, VIC_INT_EN1); + // clear any pending ints + writel(-1, VIC_INT_CLEAR0); + writel(-1, VIC_INT_CLEAR1); + + // set correct triggering for interrupts 0-7 + // edge or level, positive or nagative, who knows! + writel(/*readl(VIC_INT_TYPE0)*/0 | 0xff,VIC_INT_TYPE0); +// writel(0,VIC_INT_TYPE0); +// writel(0,VIC_INT_TYPE1); + msm_irq_shadow_reg[0].int_type=readl(VIC_INT_TYPE0); + msm_irq_shadow_reg[1].int_type=readl(VIC_INT_TYPE1); + + /* + writel(-1,VIC_INT_POLARITY0); + writel(-1,VIC_INT_POLARITY1); + */ +// writel(-1,VIC_INT_TYPE0); // if set this triggers on rising otherwise rising and falling +// writel(-1,VIC_INT_TYPE1); + + + for (n = 0; n < NR_MSM_IRQS; n++) { + set_irq_chip(n, &msm_irq_chip); + set_irq_handler(n, handle_level_irq); + set_irq_flags(n, IRQF_VALID); + } +} diff --git a/arch/arm/mach-msm/AudioPara.c b/arch/arm/mach-msm/AudioPara.c new file mode 100644 index 0000000..f683f9c --- /dev/null +++ b/arch/arm/mach-msm/AudioPara.c @@ -0,0 +1,96 @@ +struct audioparam1_str { + int code; + char *name; + unsigned char data[0x50]; +}; + +struct audioparam2_str { + int code; + char *name; + unsigned char data[0xa0]; +}; +struct audioparam3_str { + int code; + char *name; + unsigned short data[0x140]; +}; + +struct audioparam1_str audioparams1[20]={ + {0xA0,"PHONE_HEADSET",{0x35,0x61,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x14,0x3D,0x30,0x3E,0xA8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, + {0xA1,"PHONE_HANDSFREE",{0x35,0x63,0x36,0x63,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x0,0x3B,0x0,0x3C,0xC8,0x3D,0xC8,0x3E,0xC0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x50,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x1E,0x4B,0x0,0x4C,0x0,0x35,0x63,0x36,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, + {0xA2,"PHONE_EARCUPLE",{0x35,0x71,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x0,0x3B,0x0,0x3C,0x8C,0x3D,0xA4,0x3E,0xC0,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x7,0x4B,0x0,0x4C,0x0,0x35,0x71,0x36,0x61,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA3,"PHONE_BTHEADSET",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA4,"PHONE_CARKIT",{0x35,0x69,0x36,0x69,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x30,0x3D,0x30,0x3E,0x8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA5,"PHONE_TTY_FULL",{0x35,0x69,0x36,0x69,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0xC4,0x3D,0xC4,0x3E,0x8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA6,"PHONE_TTY_VCO",{0x35,0x69,0x36,0x69,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0xC4,0x3D,0xC4,0x3E,0x0,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA7,"PHONE_TTY_HCO",{0x35,0x71,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0xC4,0x3D,0xC4,0x3E,0x8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x1,0x4B,0x0,0x4C,0x0,0x35,0x71,0x36,0x61,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA8,"CE_REC_INT_MIC",{0x35,0x63,0x36,0x63,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x0,0x3B,0x0,0x3C,0x3C,0x3D,0x3C,0x3E,0x0,0x3F,0x80,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x50,0x46,0x0,0x47,0x0,0x48,0x5,0x49,0x0,0x4A,0x1E,0x4B,0x0,0x4C,0x0,0x35,0x63,0x36,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA9,"CE_REC_EXT_MIC",{0x35,0x61,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x20,0x3D,0x20,0x3E,0x8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x5,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA10,"CE_PLAYBACK_HEADSET",{0x35,0x61,0x36,0x61,0x37,0x0,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x20,0x3D,0x20,0x3E,0x8,0x3F,0x0,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA11,"CE_PLAYBACK_HEADSET_RING",{0x35,0xEB,0x36,0xEB,0x37,0x0,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x20,0x3D,0x20,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x10,0x45,0x50,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x1E,0x4B,0x0,0x4C,0x0,0x35,0xEB,0x36,0xEB,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA12,"CE_PLAYBACK_HANDSFREE",{0x35,0x63,0x36,0x63,0x37,0x0,0x38,0x0,0x39,0x3,0x3A,0x0,0x3B,0x0,0x3C,0x90,0x3D,0x90,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x50,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x1E,0x4B,0x0,0x4C,0x0,0x35,0x63,0x36,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA13,"CE_SYS",{0x35,0x63,0x36,0x63,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x0,0x3B,0x0,0x3C,0xA4,0x3D,0xA4,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x18,0x4B,0x0,0x4C,0x0,0x35,0x63,0x36,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA14,"IDLE",{0x35,0x61,0x36,0x61,0x37,0x0,0x38,0x0,0x39,0x0,0x3A,0x0,0x3B,0x0,0x3C,0x0,0x3D,0x0,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x0,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x18,0x4B,0x0,0x4C,0x0,0x36,0x0,0x35,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA15,"OFF",{0x35,0x0,0x36,0x0,0x37,0x0,0x38,0x0,0x39,0x0,0x3A,0x0,0x3B,0x0,0x3C,0x30,0x3D,0x30,0x3E,0x8,0x3F,0x80,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x18,0x4B,0x0,0x4C,0x0,0x35,0x0,0x36,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA16,"PHONE_HEADSET_IMIC",{0x35,0x61,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x8C,0x3D,0xA4,0x3E,0xC0,0x3F,0x0,0x40,0x5,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA17,"CE_PLAYBACK_RESET",{0x37,0x0,0x38,0x0,0x3A,0x80,0x3B,0x0,0x3C,0x0,0x3D,0x0,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x0,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x35,0x69,0x36,0x69,0x4B,0x0,0x4C,0x0,0x4C,0x0,0x4C,0x0,0x39,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA18,"CE_REC_HEADSET_IMIC",{0x35,0x61,0x36,0x61,0x37,0xFF,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x3C,0x3D,0x3C,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xA19,"CE_PLAYBACK_HEADSET_IMIC",{0x35,0x61,0x36,0x61,0x37,0x0,0x38,0x0,0x39,0x3,0x3A,0x80,0x3B,0x0,0x3C,0x3C,0x3D,0x3C,0x3E,0x0,0x3F,0x0,0x40,0x0,0x41,0x2C,0x42,0x1,0x43,0x0,0x44,0x0,0x45,0x0,0x46,0x0,0x47,0x0,0x48,0x0,0x49,0x0,0x4A,0x6,0x4B,0x0,0x4C,0x0,0x35,0x69,0x36,0x69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +}; + +struct audioparam2_str audioparams2[13]={ +{0xC0,"PHONE_HEADSET",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC1,"PHONE_HANDSFREE",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC2,"PHONE_EARCUPLE",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC3,"PHONE_BTHEADSET",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC4,"PHONE_CARKIT",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC5,"PHONE_TTY_FULL",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC6,"PHONE_TTY_VCO",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC7,"PHONE_TTY_HCO",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC8,"CE_REC_INC_MIC",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC9,"CE_REC_EXT_MIC",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC10,"CE_PLAYBACK_HEADSET",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC11,"CE_PLAYBACK_HANDSFREE",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +{0xC12,"CE_SYS",{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}, +}; + +struct audioparam3_str audioparams3[37]={ +{0xF0,"PHONE_HEADSET_VOL0",{0x0,0x4000,0x4000,0x0,0x4000,0x2D4E,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF1,"PHONE_HEADSET_VOL1",{0x1,0x4000,0x4000,0x0,0x4000,0x4000,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF2,"PHONE_HEADSET_VOL2",{0x2,0x4000,0x4000,0x0,0x4000,0x5A67,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF3,"PHONE_HEADSET_VOL3",{0x3,0x4000,0x4000,0x0,0x4000,0x7FB2,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF4,"PHONE_HEADSET_VOL4",{0x4,0x4000,0x4000,0x0,0x4000,0xB460,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF5,"PHONE_HEADSET_VOL5",{0x5,0x4000,0x4000,0x0,0x4000,0xCA62,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF6,"PHONE_HANDSFREE_VOL0",{0x0,0x4000,0x4000,0x0,0xFEC9,0x1013,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x60,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x380,0x32c8,0x0fa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF7,"PHONE_HANDSFREE_VOL1",{0x1,0x4000,0x4000,0x0,0xFEC9,0x16B5,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x60,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x380,0x32c8,0x0fa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF8,"PHONE_HANDSFREE_VOL2",{0x2,0x4000,0x4000,0x0,0xFEC9,0x2013,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x60,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x380,0x32c8,0x0fa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF9,"PHONE_HANDSFREE_VOL3",{0x3,0x4000,0x4000,0x0,0xFEC9,0x2D4E,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x60,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x400,0x32c8,0x0fa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF10,"PHONE_HANDSFREE_VOL4",{0x4,0x4000,0x4000,0x0,0xFEC9,0x4000,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x70,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x450,0x32c8,0x0fa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF11,"PHONE_HANDSFREE_VOL5",{0x5,0x4000,0x4000,0x0,0xFEC9,0x390A,0xFFFF,0x7F65,0x0,0x1180,0xFF67,0x1D00,0xF333,0x07AE,0xF911,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x7F65,0x0000,0x780,0xFF9A,0x1C80,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x2026,0x800,0x7fff,0x179f,0x0,0x0,0x800,0x2000,0x2000,0x80,0x008C,0x2,0x190,0x40,0x20,0x40,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x3E80,0xBB8,0x0,0x80,0x190,0x1E00,0x300,0x400,0x300,0x258,0x190,0x1214,0x530,0x32c8,0x0fa0,0xFFFF,0x0000,0xFFF2,0xFF76,0xFCB8,0xF6BA,0xEE50,0x6AD3,0xFFFF,0xFF81,0x020B,0x00AC,0xF826,0x05A3,0x0AFA,0x3C7C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF12,"PHONE_EARCUPLE_VOL0",{0x0,0x4000,0x4000,0x524,0x47CF,0x23FD,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0xFFFF,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF13,"PHONE_EARCUPLE_VOL1",{0x1,0x4000,0x4000,0x524,0x47CF,0x32D6,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0xFFFF,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF14,"PHONE_EARCUPLE_VOL2",{0x2,0x4000,0x4000,0x524,0x47CF,0x47CF,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0x0000,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF15,"PHONE_EARCUPLE_VOL3",{0x3,0x4000,0x4000,0x524,0x47CF,0x656E,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0x0000,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF16,"PHONE_EARCUPLE_VOL4",{0x4,0x4000,0x4000,0x524,0x47CF,0x8F47,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0x0000,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF17,"PHONE_EARCUPLE_VOL5",{0x5,0x4000,0x4000,0x524,0x47CF,0xCA62,0xFFFF,0x2000,0x0,0xC80,0xFF9A,0x1E2B,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0000,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x2,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4a38,0x1770,0x0,0x20,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x002B,0xFF29,0xFFF1,0xFA54,0x0B10,0xF1BA,0x3A1F,0x0000,0x13,0xFFDC,0xFDAA,0xFF4E,0xF955,0xFA96,0x3EBE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF18,"PHONE_BTHEADSET,0x5",{0x4000,0x4000,0x0,0x7FB2,0x5A67,0x0,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF19,"PHONE_CARKIT",{0x5,0x4000,0x4000,0x0,0x7FB2,0x5A67,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x417,0xFC95,0x60,0xEC7D,0x01D8,0xF16B,0x3D23,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF20,"PHONE_TTY_FULL",{0x0,0x6000,0x6000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF21,"PHONE_TTY_VCO",{0x0,0x656E,0x4000,0x0,0xE314,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF22,"PHONE_TTY_HCO",{0x0,0x4000,0x4000,0x0,0x4000,0xFEC9,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0xFB93,0xFBF6,0xF2C6,0xFDCC,0x93,0x141F,0x382A,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF23,"CE_REC_INC_MIC",{0x5,0x4000,0x71CF,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF24,"CE_REC_EXT_MIC",{0x5,0x4000,0x4000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF25,"CE_PLAYBACK_HEADSET",{0x5,0x4000,0x4000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF26,"CE_PLAYBACK_HANDSFREE",{0x5,0x4000,0x71CF,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF27,"CE_SYS",{0x5,0x4000,0x4000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF28,"PHONE_HEADSET_IMIC_VOL0",{0x0,0x4000,0x4000,0x0,0x4000,0x2D4E,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF29,"PHONE_HEADSET_IMIC_VOL1",{0x1,0x4000,0x4000,0x0,0x4000,0x4000,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF30,"PHONE_HEADSET_IMIC_VOL2",{0x2,0x4000,0x4000,0x0,0x4000,0x5A67,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF31,"PHONE_HEADSET_IMIC_VOL3",{0x3,0x4000,0x4000,0x0,0x4000,0x7FB2,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF32,"PHONE_HEADSET_IMIC_VOL4",{0x4,0x4000,0x4000,0x0,0x4000,0xB460,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF33,"PHONE_HEADSET_IMIC_VOL5",{0x5,0x4000,0x4000,0x0,0x4000,0xCA62,0xFFFF,0x2000,0x0,0x780,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0xFFFF,0x2000,0x0,0xC80,0xFF1A,0x2580,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x149f,0x0,0x14,0x800,0x2000,0x2000,0x200,0x003c,0x2,0x02ff,0x40,0x20,0x2710,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x2,0x4650,0x0bb8,0x0,0x012c,0x012c,0x400,0x200,0x200,0x300,0x258,0x190,0x1ca8,0x384,0x32c8,0x0fa0,0xFFFF,0xFFCD,0x00A5,0xFCD4,0x02AC,0x025B,0xEBBE,0x38D3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF34,"CE_PLAYBACK_HEADSET_RING",{0x5,0x4000,0x71CF,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF35,"CE_REC_HEADSET_IMIC",{0x5,0x4000,0x4000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}}, +{0xF36,"CE_PLAYBACK_HEADSET_IMIC",{0x5,0x4000,0x4000,0x0,0x4000,0x4000,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x0,0xED00,0x0,0x0,0x7F65,0x0,0x780,0xFF9A,0x1B0C,0xF333,0x01EC,0xFFEE,0x200A,0x7F65,0x7fff,0x800,0x7fff,0x0,0x0,0x14,0x800,0x2000,0x2000,0x00fa,0x46,0x1,0x02ff,0x40,0x20,0x4650,0x40,0x41a0,0x800,0x63,0x4E20,0x4E20,0x1,0x4a38,0x1770,0x0,0x100,0x100,0x400,0x200,0x400,0x300,0x258,0x190,0x1ca8,0x01c2,0x2ee0,0x0fa0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFFFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x2,0xFFFF}} +}; + diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 326d9e6..b429a57 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -27,6 +27,53 @@ config MACH_HALIBUT bool "Halibut Board (QCT SURF7200A)" help Support for the Qualcomm SURF7200A eval board. +config MSM7X00 + depends on ARCH_MSM7X00A + default n + bool "MSM7200 & MSM7500" + help + Support for the Qualcomm MSM7X00 series + basied on MSM7X00A board + +config MACH_HTCVOGUE + depends on MSM7X00 + default y + bool "HTC Vogue Phone" + help + Support for HTC Vogue phone. + +config MACH_HTCKAISER + depends on MSM7X00 + default n + bool "HTC Kaiser Phone" + help + Basic Support for HTC Kaiser phone. + +config MACH_HTCPOLARIS + depends on MSM7X00 + default n + bool "HTC Polaris Phone" + help + Basic Support for HTC Polaris phone. + +config MSM_KAISERSMD + tristate "MSM Kaiser SMD Drivers" + depends on MACH_HTCKAISER + default n + help + Support for shared memory interface to the ARM9 "Modem" processor + on Kaiser. Needed for access to many services, including power + and clock control, cellular voice and data network access, etc. + +config MSM_7X00SMD + tristate "MSM 7X00 SMD Drivers" + depends on MSM7X00 + default y + help + Support for shared memory interface to the ARM9 "Modem" processor. + Needed for access to many services, including power + and clock control, cellular voice and data network access, etc. + choice prompt "MSM Low-Level Debug UART" @@ -210,7 +257,7 @@ config MSM_SMD and clock control, cellular voice and data network access, etc. config MSM_ONCRPCROUTER - depends on MSM_SMD + depends on MSM_KAISERSMD default y bool "MSM ONCRPC router support" help diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 9ac0b46..f335e2f 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,13 +1,18 @@ -obj-y += io.o idle.o irq.o timer.o dma.o clock.o clock-7x00a.o memory.o +obj-y += io.o idle.o timer.o dma.o clock.o clock-7x00a.o memory.o obj-y += vreg.o obj-y += gpio.o generic_gpio.o -obj-y += proc_comm.o +#obj-y += proc_comm.o # Common code for board init obj-y += common.o nand_partitions.o obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o -obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o board-halibut-keypad.o +obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o board-halibut-keypad.o irq.o +obj-$(CONFIG_MACH_HTCVOGUE) += board-htcvogue.o 7x00-irq.o tsc2003.o +obj-$(CONFIG_MSM_7X00SMD) += smd.o smd_tty.o +obj-$(CONFIG_MACH_HTCKAISER) += board-htckaiser.o 7x00-irq.o tsc2003.o board-kaiser-keypad.o kaiser-pm.o +obj-$(CONFIG_MACH_HTCPOLARIS) += board-htcpolaris.o 7x00-irq.o vogue-ts.o kaiser-smd.o smd_tty.o +obj-$(CONFIG_MSM_KAISERSMD) += kaiser-smd.o smd_tty.o obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o @@ -17,4 +22,4 @@ obj-$(CONFIG_MSM_RPCSERVERS) += rpc_server_time_remote.o obj-$(CONFIG_MSM_ADSP) += qdsp5/ obj-$(CONFIG_MSM_HW3D) += hw3d.o obj-$(CONFIG_MSM_PERF) += perf.o -obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_PM) += kaiser-pm.o diff --git a/arch/arm/mach-msm/board-htckaiser.c b/arch/arm/mach-msm/board-htckaiser.c new file mode 100644 index 0000000..eaed4f6 --- /dev/null +++ b/arch/arm/mach-msm/board-htckaiser.c @@ -0,0 +1,394 @@ +/* linux/arch/arm/mach-msm/board-kaiser.c + * + * Author: Martin Johnson, Lukas Gorris , Waylon Grange + * Based on board-halibut.c by Brian Swetland + * + * 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 + +#define MSM_SMI_BASE 0x00000000 +#define MSM_SMI_SIZE 0x900000 + +#define MSM_EBI_BASE 0x10000000 +#define MSM_EBI_SIZE 0x6e00000 + +#define MSM_PMEM_GPU0_BASE 0x0 +#define MSM_PMEM_GPU0_SIZE 0x800000 + +#define MSM_LINUX_BASE MSM_EBI_BASE +#define MSM_LINUX_SIZE 0x4c00000 + +#define MSM_PMEM_MDP_BASE MSM_LINUX_BASE + MSM_LINUX_SIZE +#define MSM_PMEM_MDP_SIZE 0x800000 + +#define MSM_PMEM_ADSP_BASE MSM_PMEM_MDP_BASE + MSM_PMEM_MDP_SIZE +#define MSM_PMEM_ADSP_SIZE 0x800000 + +#define MSM_PMEM_GPU1_BASE MSM_PMEM_ADSP_BASE + MSM_PMEM_ADSP_SIZE +#define MSM_PMEM_GPU1_SIZE 0x800000 + +// #define MSM_FB_BASE MSM_PMEM_GPU1_BASE + MSM_PMEM_GPU1_SIZE +#define MSM_FB_BASE 0x00000000 +#define MSM_FB_SIZE 0x9b000 + +#ifdef CONFIG_FB_MSM + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define PWM_BLOCK_BASE 0x140000 +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) + +static void mddi0_panel_power(struct mddi_panel_info *panel, int on) +{ + /*if(on) { + mddi_remote_write(panel->mddi, 0, DPSUS); + udelay(122); + mddi_remote_write(panel->mddi, 1, SYSCLKENA); + mddi_remote_write(panel->mddi, kaiser_ffa ? 0 : 0x00001387, PWM0OFF); +} + else { + mddi_remote_write(panel->mddi, kaiser_ffa ? 0x00001387 : 0, PWM0OFF); + udelay(122); + mddi_remote_write(panel->mddi, 0, SYSCLKENA); + mddi_remote_write(panel->mddi, 1, DPSUS); +} + */ + printk("mddi0_panel_power(%d)\n", on); +} + +static struct msm_mddi_platform_data msm_mddi0_pdata = { + .panel_power = mddi0_panel_power, + .has_vsync_irq = 0, + .fb_base = MSM_FB_BASE, + .fb_size = MSM_FB_SIZE, +}; + +static struct platform_device msm_mddi0_device = { + .name = "msm_mddi", + .id = 0, + .dev = { + .platform_data = &msm_mddi0_pdata + }, +}; + +#endif +static struct resource msm_serial0_resources[] = { + { + .start = INT_UART1, + .end = INT_UART1, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART1_PHYS, + .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device msm_serial0_device = { + .name = "msm_serial", + .id = 0, + .num_resources = ARRAY_SIZE(msm_serial0_resources), + .resource = msm_serial0_resources, +}; + +static struct resource usb_resources[] = { + { + .start = MSM_HSUSB_PHYS, + .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB_HS, + .end = INT_USB_HS, + .flags = IORESOURCE_IRQ, + }, +}; + +/* The HSUSB PHY on kaiser has a hardware bug where VBUS + * interrupts can lock up the ULPI bus, causing USB to fail. + * Disable these interrupts to avoid this issue. + */ +static int kaiser_phy_init_seq[] = { 0x1D, 0x0D, 0x1D, 0x10, -1 }; + +static struct msm_hsusb_platform_data msm_hsusb_pdata = { + .phy_init_seq = kaiser_phy_init_seq, + .vendor_id = 0x18d1, + .product_id = 0xd00d, + .version = 0x0100, + .product_name = "kaiser", +}; + +static struct platform_device msm_hsusb_device = { + .name = "msm_hsusb", + .id = -1, + .num_resources = ARRAY_SIZE(usb_resources), + .resource = usb_resources, + .dev = { + .coherent_dma_mask = 0xffffffff, + .platform_data = &msm_hsusb_pdata, + }, +}; + +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem", + .start = MSM_PMEM_MDP_BASE, + .size = MSM_PMEM_MDP_SIZE, + .no_allocator = 1, + .cached = 1, +}; + +static struct android_pmem_platform_data android_pmem_adsp_pdata = { + .name = "pmem_adsp", + .start = MSM_PMEM_ADSP_BASE, + .size = MSM_PMEM_ADSP_SIZE, + .no_allocator = 0, + .cached = 0, +}; + +static struct android_pmem_platform_data android_pmem_gpu0_pdata = { + .name = "pmem_gpu0", + .start = MSM_PMEM_GPU0_BASE, + .size = MSM_PMEM_GPU0_SIZE, + .no_allocator = 1, + .cached = 0, +}; + +static struct android_pmem_platform_data android_pmem_gpu1_pdata = { + .name = "pmem_gpu1", + .start = MSM_PMEM_GPU1_BASE, + .size = MSM_PMEM_GPU1_SIZE, + .no_allocator = 1, + .cached = 0, +}; + +static struct platform_device android_pmem_device = { + .name = "android_pmem", + .id = 0, + .dev = { .platform_data = &android_pmem_pdata }, +}; + +static struct platform_device android_pmem_adsp_device = { + .name = "android_pmem", + .id = 1, + .dev = { .platform_data = &android_pmem_adsp_pdata }, +}; + +static struct platform_device android_pmem_gpu0_device = { + .name = "android_pmem", + .id = 2, + .dev = { .platform_data = &android_pmem_gpu0_pdata }, +}; + +static struct platform_device android_pmem_gpu1_device = { + .name = "android_pmem", + .id = 3, + .dev = { .platform_data = &android_pmem_gpu1_pdata }, +}; + +/*****************************************************************/ +/* EGPIOs */ + +static struct resource egpio_resources[] = { + [0] = { + .start = 0x98000000, + .end = 0x98000000 + 0x2*9, /* 8 regs */ + .flags = IORESOURCE_MEM, + }, +}; + +struct htc_egpio_pinInfo pins[] = { + {.gpio = EGPIO_7_3_INIT + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 1}, // INIT=1 + {.gpio = EGPIO_1_0_SD_PWR + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 1}, // SDPWR + {.gpio = EGPIO_1_2_KBD_BAKLIGHT + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 0}, // Keybard backlight + {.gpio = EGPIO_2_1_RESET_PERMIT + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 1}, // Reset permit + {.gpio = EGPIO_2_4_LCD_PWR1 + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 1}, // LCD PWR + {.gpio = EGPIO_3_2_FN_LED + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 0}, // Fn led + {.gpio = EGPIO_3_3_CAPS_LED + , .type = HTC_EGPIO_TYPE_OUTPUT + , .output_initial = 0}, // Caps led +}; + +struct htc_egpio_platform_data egpio_data = { + .gpio_base = KAISER_EGPIO_BASE, + .nrRegs = 8, + .pins = pins, + .nr_pins = ARRAY_SIZE(pins), +// .reg_width=8, +// .bus_width=16, +}; + +struct platform_device kaiser_egpio = { + .name = "htc-egpio", + .id = -1, + .dev = { + .platform_data = &egpio_data, + }, + .resource = egpio_resources, + .num_resources = ARRAY_SIZE(egpio_resources), +}; + +static struct platform_device *devices[] __initdata = { +#if !defined(CONFIG_MSM_SERIAL_DEBUGGER) +// &msm_serial0_device, +#endif +#ifdef CONFIG_FB_MSM + &kaiser_egpio, + &msm_mddi0_device, +#endif +// &msm_hsusb_device, + &android_pmem_device, + &android_pmem_adsp_device, + &android_pmem_gpu0_device, + &android_pmem_gpu1_device, +}; + +static struct i2c_board_info __initdata kaiser_i2c_board_info[] = { + { + I2C_BOARD_INFO("kaiser-ts", 0x48), + .type = "vtsc2003-ts", + .irq = MSM_GPIO_TO_INT(99), + }, +}; + + +static unsigned int kaiser_sdcc_slot_status(struct device *dev) +{ + int slot=1-gpio_get_value(94); + // printk("sdcc_slot_status=%d\n",slot); + return slot; +} + +static struct mmc_platform_data kaiser_sdcc_data = { + .ocr_mask = MMC_VDD_28_29, + .status = kaiser_sdcc_slot_status, +}; + +extern struct sys_timer msm_timer; + +static void __init kaiser_init_irq(void) +{ + msm_init_irq(); +} + +static struct msm_clock_platform_data kaiser_clock_data = { + .acpu_switch_time_us = 50, + .max_speed_delta_khz = 256000, + .vdd_switch_time_us = 62, +}; + +void msm_serial_debug_init(unsigned int base, int irq, + const char *clkname, int signal_irq); + +static void __init kaiser_init_mmc(void) +{ + + struct vreg *vreg_mmc; + int rc; + + vreg_mmc = vreg_get(0, "mmc"); + rc = vreg_enable(vreg_mmc); + if (rc) + printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, rc); + + msm_add_sdcc(2, &kaiser_sdcc_data); + +/* TODO: Enable these once we have support for the SDC mux + * msm_add_sdcc(2, &kaiser_sdcc_data); + * msm_add_sdcc(3, &kaiser_sdcc_data); + * msm_add_sdcc(4, &kaiser_sdcc_data); + */ + +} + +static void __init kaiser_init(void) +{ +#if defined(CONFIG_MSM_SERIAL_DEBUGGER) + msm_serial_debug_init(MSM_UART1_PHYS, INT_UART1, + "uart1_clk", 1); +#endif + msm_init_gpio(); + platform_add_devices(devices, ARRAY_SIZE(devices)); + msm_add_devices(); + kaiser_init_mmc(); + i2c_register_board_info(0, kaiser_i2c_board_info, + ARRAY_SIZE(kaiser_i2c_board_info)); + /* TODO: detect vbus and correctly notify USB about its presence + * For now we just declare that VBUS is present at boot and USB + * copes, but this is not ideal. + */ + //msm_hsusb_set_vbus_state(1); +} + +static void __init kaiser_map_io(void) +{ + msm_map_common_io(); + msm_clock_init(&kaiser_clock_data); +} + +MACHINE_START(HTCKAISER, "HTC Kaiser") + /* Maintainer: Lukas Gorris*/ + /* UART for LL DEBUG */ + .phys_io = MSM_UART1_PHYS, + .io_pg_offst = ((MSM_UART1_BASE) >> 18) & 0xfffc, + + .boot_params = 0x10000100, + .map_io = kaiser_map_io, + .init_irq = kaiser_init_irq, + .init_machine = kaiser_init, + .timer = &msm_timer, + MACHINE_END diff --git a/arch/arm/mach-msm/board-kaiser-keypad.c b/arch/arm/mach-msm/board-kaiser-keypad.c new file mode 100644 index 0000000..e4f1d31 --- /dev/null +++ b/arch/arm/mach-msm/board-kaiser-keypad.c @@ -0,0 +1,697 @@ +/* +* HTC Kaiser Keyboard based on: +* Palm TC hardware buttons (Holger Bocklet, Bitz.Email@gmx.net, ) +* +* Author: Marcin Baliniak +* +* Tips: +* WinMenu key = Ctrl +* Camera = Backslash +* Camera + Shift = +* PAD Center = KEY_OK +* PAD OK = KEY_BACK //<- we don need 2 OK buttons, OK remaped to BACK, PAD_CENTER = OK +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +//#define USE_RELEASE_TIMER + +#define MODULE_NAME "kaiser_kbd" + +//#define KAISER_KEYBOARD_DEBUG + +#ifdef KAISER_KEYBOARD_DEBUG +#define DBG(x...) \ + printk(KERN_INFO MODULE_NAME ": " x) +#else +#define DBG(x...) do { } while (0) +#endif + +#define FALSE 0 +#define TRUE 1 +#define PERMANENT 2 + +#define PRESSED_BIT 0x01 +#define ALT_BIT 0x02 +#define CAPS_BIT 0x04 +#define CTRL_BIT 0x08 +#define SHIFT_BIT 0x80 + +#define KEY_ANDROID_OK 232 +#define KEY_ANDROID_MENU 229 + +#ifdef USE_RELEASE_TIMER +static void release_timer_went_off (unsigned long); +static struct timer_list key_release_timer; +#endif + +static u8 alternate_key = FALSE; +static u8 shift_key = FALSE; +static u8 ctrl_key = FALSE; +static u8 col_gpio[] = { 36, 37, 38, 39, 40, 41, 42 }; +static u8 row_gpio[] = {23, 30, 31, 32, 33, 34, 35, 78}; + +#define RELEASE_CHECK_TIME_MS 50 +#define MAX_ROW ARRAY_SIZE(row_gpio) +#define MAX_COL ARRAY_SIZE(col_gpio) +#define KEYBOARD_TILT (KEY_MAX+1) +#define BACKLIGHT_TIMEOUT (15*20) //15s + +static struct { + struct input_dev *idev; + struct workqueue_struct *workqueue; + struct work_struct task; + struct semaphore sem; + struct platform_device *platform_dev; + struct timer_list timer20Hz; // timer 20Hz to read gpio changes + spinlock_t lock;// = SPIN_LOCK_UNLOCKED; + unsigned int backlight_timer; +} kbd_data; + + + +static struct //gpio buttons +{ + unsigned short key; //key + unsigned short alt_key; //alternative key + unsigned short gpio; //gpio num + unsigned char state; //to remember old state + char *desc; +} gpio_buttons[]={ + //{KEY_VOLUMEUP, 18, 0, "Vol UP"}, + //{KEY_VOLUMEDOWN, 19, 0, "Vol Down"}, + {KEY_POWER, KEY_POWER, 20, 0, "Power"}, + {KEY_UP, KEY_UP, EGPIO_5_0_PAD_UP, 0, "PAD UP"}, + {KEY_DOWN, KEY_DOWN, EGPIO_5_1_PAD_DOWN, 0, "PAD DOWN"}, + {KEY_LEFT, KEY_LEFT, EGPIO_5_2_PAD_LEFT, 0, "PAD LEFT"}, + {KEY_RIGHT, KEY_RIGHT, EGPIO_5_3_PAD_RIGHT, 0, "PAD RIGHT"}, + {KEY_ANDROID_OK, KEY_ANDROID_OK, EGPIO_5_4_PAD_CENTER, 0, "PAD CENTER"}, + + {KEY_UP, KEY_PAGEUP, EGPIO_6_0_KBD_UP, 0, "KBD UP/PAGE UP"}, + {KEY_DOWN, KEY_PAGEDOWN, EGPIO_6_1_KBD_DOWN, 0, "KBD DOWN/PAGE DOWN"}, + {KEY_LEFT, KEY_COMMA, EGPIO_6_2_KBD_LEFT, 0, "KBD LEFT/COMMA"}, + {KEY_RIGHT, KEY_DOCUMENTS, EGPIO_6_3_KBD_RIGHT, 0, "KBD RIGHT/DOC."}, + + {KEY_BACKSLASH, KEY_CAMERA, EGPIO_6_4_KEY_CAM0, 0, "BACKSLASH/Camera 0"}, + {KEY_CAMERA, KEY_CAMERA, EGPIO_6_5_KEY_CAM1, 0, "Camera 1"}, + + {KEYBOARD_TILT, KEYBOARD_TILT, EGPIO_5_5_TILT, 0, "Tilt"}, +}; + +static struct +{ // matrix for real buttons + unsigned short key; + unsigned short alt_key; + u8 flags; // for recording last status (lowest) and shift_bit (highest) + char *desc; +} matrix_buttons[MAX_ROW][MAX_COL] = { +//0 + { + {KEY_LEFTCTRL, KEY_SEMICOLON, FALSE, "Menu/;"}, //<- I repleace this key with ctrl + {KEY_ANDROID_OK, KEY_WLAN, FALSE, "OK/WLAN"}, + {KEY_TAB, KEY_TAB, FALSE, "TAB"}, + {KEY_V, KEY_8, SHIFT_BIT, "V/*"}, + {KEY_SPACE, KEY_SPACE, FALSE, "SPACE"}, + {KEY_DOT, KEY_0, FALSE, "DOT/0"}, + {KEY_ENTER, KEY_ENTER, FALSE, "ENTER"} + }, +//1 + { + {KEY_MAX, KEY_MAX, FALSE, "none"}, + {KEY_MAX, KEY_MAX, FALSE, "none"}, + {KEY_MAX, KEY_MAX, FALSE, "none"}, + {KEY_MENU, KEY_MENU, FALSE, "Pad Menu"}, + {KEY_END, KEY_END, FALSE, "End"}, //red + {KEY_BACK, KEY_BACK, FALSE, "Pad OK"},//we don't have Back or C key ,so I remaped OK + {KEY_SEND, KEY_SEND, FALSE, "Send"} //call + }, +//2 + { + {KEY_FN, KEY_FN, FALSE, "Fn"}, + {KEY_X, KEY_7, SHIFT_BIT, "X/&"}, + {KEY_C, KEY_SEMICOLON, SHIFT_BIT, "C/:"}, + {KEY_G, KEY_EQUAL, SHIFT_BIT, "G/+"}, + {KEY_B, KEY_7, FALSE, "B/7"}, + {KEY_M, KEY_9, FALSE, "M/9"}, + {KEY_BACKSPACE, KEY_DELETE, FALSE, "Back./Del"} + }, +//3 + { + {KEY_RIGHTSHIFT, KEY_RIGHTSHIFT, FALSE, "Shift"}, + {KEY_Z, KEY_APOSTROPHE, FALSE, "Z/'"}, + {KEY_F, KEY_MINUS, FALSE, "F/-"}, + {KEY_Y, KEY_1, FALSE, "Y/1"}, + {KEY_H, KEY_4, FALSE, "H/4"}, + {KEY_N, KEY_8, FALSE, "N/8"}, + {KEY_L, KEY_EQUAL, FALSE, "L/="} + }, +//4 + { + {KEY_A, KEY_MINUS, SHIFT_BIT, "A/_"}, + {KEY_S, KEY_APOSTROPHE, SHIFT_BIT, "S/\""}, + {KEY_D, KEY_5, SHIFT_BIT, "D/%"}, + {KEY_T, KEY_3, SHIFT_BIT, "T/#"}, + {KEY_J, KEY_5, FALSE, "J/5"}, + {KEY_K, KEY_6, FALSE, "K/6"}, + {KEY_P, KEY_0, SHIFT_BIT, "P/)"} + }, +//5 + { + {KEY_Q, KEY_2, SHIFT_BIT, "Q/@"}, + {KEY_W, KEY_1, SHIFT_BIT, "W/!"}, + {KEY_E, KEY_SLASH, SHIFT_BIT, "E/?"}, + {KEY_R, KEY_SLASH, FALSE, "R//"}, + {KEY_U, KEY_2, FALSE, "U/2"}, + {KEY_I, KEY_3, FALSE, "I/3"}, + {KEY_O, KEY_9, SHIFT_BIT, "0/("} + }, +//6 + { + {KEY_MAX, KEY_MAX, FALSE, "61"}, + {KEY_MAX, KEY_MAX, FALSE, "62"}, + {KEY_MAX, KEY_MAX, FALSE, "63"}, + {KEY_TAB, KEY_F7, FALSE, "Kbd LeftSoft"}, + {KEY_MAX, KEY_MAX, FALSE, "65"}, + {KEY_TAB, KEY_F7, FALSE, "Kbd RightSoft"}, + {KEY_MAX, KEY_MAX, FALSE, "67"} + }, +//7 + { + {KEY_MENU, KEY_SEMICOLON, FALSE, "Left side OK"}, + {KEY_MAX, KEY_MAX, FALSE, "72"}, + {KEY_TAB, KEY_F7, FALSE, "VoiceMemo"}, + {KEY_TAB, KEY_F7, FALSE, "Pad IE"}, + {KEY_TAB, KEY_F7, FALSE, "Pad RightSoft"}, + {KEY_TAB, KEY_F7, FALSE, "Pad Mail"}, + {KEY_V, KEY_F8, FALSE, "Pad LeftSoft"} + }, +}; + +static void kaiser_kbd_enable_irqs(void) +{ + int i; + for (i=0;i2) + alternate_key=0; + shift_key=0; + ctrl_key=0; + } + else if (matrix_buttons[row][col].key == KEY_RIGHTSHIFT) + { + shift_key++; + if (shift_key>2) + shift_key=0; + alternate_key=0; + ctrl_key=0; + } + else if (matrix_buttons[row][col].key == KEY_LEFTCTRL && alternate_key == 0) + { + ctrl_key++; + if (ctrl_key>2) + ctrl_key=0; + shift_key=0; + } + else + { + if (alternate_key) + { + if (matrix_buttons[row][col].alt_key < KEY_MAX) + { + matrix_buttons[row][col].flags |= ALT_BIT; + if (matrix_buttons[row][col].flags & SHIFT_BIT) + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 1); + input_report_key (kbd_data.idev, matrix_buttons[row][col].alt_key, 1); + input_sync (kbd_data.idev); + } + if (alternate_key != PERMANENT) + alternate_key = FALSE; + } + else if (shift_key) + { + if (matrix_buttons[row][col].key < KEY_MAX) + { + matrix_buttons[row][col].flags |= CAPS_BIT; + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 1); + input_report_key (kbd_data.idev, matrix_buttons[row][col].key, 1); + input_sync (kbd_data.idev); + } + if (shift_key != PERMANENT) + shift_key = FALSE; + } + else if (ctrl_key) + { + if (matrix_buttons[row][col].key < KEY_MAX) + { + matrix_buttons[row][col].flags |= CTRL_BIT; + input_report_key (kbd_data.idev, KEY_LEFTCTRL, 1); + input_report_key (kbd_data.idev, matrix_buttons[row][col].key, 1); + input_sync (kbd_data.idev); + } + if (ctrl_key != PERMANENT) + ctrl_key = FALSE; + } + else + { + if (matrix_buttons[row][col].key < KEY_MAX) + { + input_report_key (kbd_data.idev, matrix_buttons[row][col].key, 1); + input_sync (kbd_data.idev); + } + } + } + kaiser_update_leds(); + } +#ifdef USE_RELEASE_TIMER + spin_lock_irqsave (&kbd_data.lock, flags); + if (timer_pending (&key_release_timer)) + { + mod_timer (&key_release_timer, jiffies + msecs_to_jiffies (RELEASE_CHECK_TIME_MS)); + } + else + { + key_release_timer.expires = (jiffies + msecs_to_jiffies (RELEASE_CHECK_TIME_MS)); + add_timer (&key_release_timer); + } + spin_unlock_irqrestore (&kbd_data.lock, flags); +#endif + } + else + { // not pressed branch + if (matrix_buttons[row][col].flags & PRESSED_BIT) + { + matrix_buttons[row][col].flags ^= PRESSED_BIT; //xor bit to 0 + if (matrix_buttons[row][col].key < KEY_MAX) + { + //alt key release + if (matrix_buttons[row][col].flags & ALT_BIT) + { + matrix_buttons[row][col].flags ^= ALT_BIT; //xor bit to 0 + input_report_key (kbd_data.idev, matrix_buttons[row][col].alt_key, 0); + if (matrix_buttons[row][col].flags & SHIFT_BIT) + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 0); + } + else + { + input_report_key (kbd_data.idev, matrix_buttons[row][col].key, 0); + if (matrix_buttons[row][col].flags & CAPS_BIT) + { + matrix_buttons[row][col].flags ^= CAPS_BIT; //xor bit to 0 + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 0); + } + if (matrix_buttons[row][col].flags & CTRL_BIT) + { + matrix_buttons[row][col].flags ^= CTRL_BIT; //xor bit to 0 + input_report_key (kbd_data.idev, KEY_LEFTCTRL, 0); + } + } + input_sync (kbd_data.idev); + } + } + } + } + // back to high for this row + spin_lock_irqsave (&kbd_data.lock, flags); + gpio_set_value (row_gpio[row], 1); + spin_unlock_irqrestore (&kbd_data.lock, flags); + } + + // set row-gpios low again + spin_lock_irqsave (&kbd_data.lock, flags); + for (row = 0; row < MAX_ROW; row++) + gpio_set_value (row_gpio[row], 0); + + spin_unlock_irqrestore (&kbd_data.lock, flags); + + // restore irqs + kaiser_kbd_enable_irqs(); +} + + +#ifdef USE_RELEASE_TIMER +/* +* This is called when the key release timer goes off. That's the +* only time it should be called. Check for changes in what keys +* are down. +*/ +static void release_timer_went_off (unsigned long unused) +{ + unsigned long flags; + + spin_lock_irqsave (&kbd_data.lock, flags); + + queue_work (kbd_data.workqueue, &kbd_data.task); + + spin_unlock_irqrestore (&kbd_data.lock, flags); +} +#endif + +//we need to read gpio buttons in pooling mode, no irq fo EGPIO +static void kbd_handle_timer20Hz(unsigned long __data) +{ + int i,state; + unsigned long flags; + + spin_lock_irqsave (&kbd_data.lock, flags); + + for (i = 0; i < ARRAY_SIZE(gpio_buttons); i++) + { + state = gpio_get_value(gpio_buttons[i].gpio); + if (gpio_buttons[i].state != state) + { + gpio_buttons[i].state = state; + DBG("New state of %s:%d\n",gpio_buttons[i].desc,state); + if (!state)//key pressed + { + if (gpio_buttons[i].key == KEYBOARD_TILT) + kbd_data.backlight_timer = 0; + + if (shift_key) + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 1); + + if (alternate_key) + { + input_report_key (kbd_data.idev, gpio_buttons[i].alt_key, 1); + DBG("Alt key press: %s\n",gpio_buttons[i].desc); + } + else + { + input_report_key (kbd_data.idev, gpio_buttons[i].key, 1); + DBG("Key press: %s\n",gpio_buttons[i].desc); + } + } + else + { + kbd_data.backlight_timer = BACKLIGHT_TIMEOUT; + gpio_set_value(EGPIO_1_2_KBD_BAKLIGHT,1); + + if (alternate_key) + { + input_report_key (kbd_data.idev, gpio_buttons[i].alt_key, 0); + DBG("Alt key rel: %s\n",gpio_buttons[i].desc); + } + else + { + input_report_key (kbd_data.idev, gpio_buttons[i].key, 0); + DBG("Key rel: %s\n",gpio_buttons[i].desc); + } + if (shift_key) + input_report_key (kbd_data.idev, KEY_RIGHTSHIFT, 0); + + if (shift_key != PERMANENT) + shift_key = FALSE; + + if (alternate_key != PERMANENT) + alternate_key = FALSE; + + } + input_sync(kbd_data.idev); + kaiser_update_leds(); + } + } + + if (kbd_data.backlight_timer) + kbd_data.backlight_timer--; + else + gpio_set_value(EGPIO_1_2_KBD_BAKLIGHT,0); + + spin_unlock_irqrestore (&kbd_data.lock, flags); + + kbd_data.timer20Hz.expires = jiffies+(HZ/20); + add_timer(&kbd_data.timer20Hz); +} + +static int kaiser_kbd_open (struct input_dev *idev) +{ + int ret,i; + unsigned long flags; + DBG("Open!!!\n"); + kbd_data.workqueue = create_workqueue ("kaiserkbdw"); + INIT_WORK (&kbd_data.task, kaiser_kbd_queuework); + + //init timer to read gpio changes + init_timer(&kbd_data.timer20Hz); + kbd_data.timer20Hz.function = kbd_handle_timer20Hz; + kbd_data.timer20Hz.expires = jiffies+(HZ/20); + add_timer(&kbd_data.timer20Hz); + +#ifdef USE_RELEASE_TIMER + init_timer (&key_release_timer); + key_release_timer.function = release_timer_went_off; +#endif + + // Set all GPIOS low + spin_lock_irqsave (&kbd_data.lock, flags); + for (i = 0; i < MAX_ROW; i++) + gpio_set_value (row_gpio[i], 0); + gpio_set_value (18, 0); + gpio_set_value (19, 0); + + + spin_unlock_irqrestore (&kbd_data.lock, flags); + + //ret = request_irq (INT_KEYSENSE, kaiser_kbd_irq_handler, IRQF_DISABLED, "kaiser-kbd",NULL); + for (i = 0; i < ARRAY_SIZE(col_gpio);i++) + { + ret = request_irq (gpio_to_irq(col_gpio[i]), kaiser_kbd_irq_handler, IRQF_DISABLED, "kaiser-kbd",NULL); + if (ret) + { + printk(KERN_ERR "Unable to register KBD IRQ!!!\n"); + return ret; + } + set_irq_type(gpio_to_irq(col_gpio[i]), IRQ_TYPE_EDGE_BOTH); + } + ret = request_irq (gpio_to_irq(18), kaiser_kbd_irq_handler, IRQF_DISABLED, "kaiser-kbd",NULL); + ret = request_irq (gpio_to_irq(19), kaiser_kbd_irq_handler, IRQF_DISABLED, "kaiser-kbd",NULL); + + //set_irq_type(INT_KEYSENSE, IRQ_TYPE_EDGE_BOTH); + return 0; +} + +static void kaiser_kbd_close (struct input_dev *idev) +{ + int i; + DBG("Close !!!\n"); + destroy_workqueue (kbd_data.workqueue); + + for (i=0;iname = MODULE_NAME; + kbd_data.idev->open = kaiser_kbd_open; + kbd_data.idev->close = kaiser_kbd_close; + kbd_data.idev->id.bustype = BUS_HOST; + set_bit(EV_KEY, kbd_data.idev->evbit); + set_bit(EV_REP, kbd_data.idev->evbit); + for (row = 0; row < MAX_ROW; row++) + for (col = 0; col < MAX_COL; col++) + { + if (matrix_buttons[row][col].key < KEY_MAX) + set_bit(matrix_buttons[row][col].key, kbd_data.idev->keybit); + + if (matrix_buttons[row][col].alt_key < KEY_MAX) + set_bit(matrix_buttons[row][col].alt_key, kbd_data.idev->keybit);; + } + + for (col = 0; col < ARRAY_SIZE(gpio_buttons); col++) + { + if (gpio_buttons[col].key < KEY_MAX) + set_bit(gpio_buttons[col].key, kbd_data.idev->keybit); + if (gpio_buttons[col].alt_key < KEY_MAX) + set_bit(gpio_buttons[col].alt_key, kbd_data.idev->keybit); + } + + if (input_register_device (kbd_data.idev)) + { + input_free_device(kbd_data.idev); + return -ENODEV; + } + + return 0; +} + +static int __init kaiser_kbd_remove(struct platform_device *pdev) +{ + DBG ("removing device...\n"); + input_unregister_device (kbd_data.idev); + return 0; +} + +static struct platform_driver kaiser_kbd_driver = { + .probe = kaiser_kbd_probe, + .remove = kaiser_kbd_remove, + .driver = { + .name = MODULE_NAME, + }, +}; + +static int __init kaiser_kbd_init (void) +{ + int ret; + + ret = platform_driver_register(&kaiser_kbd_driver); + if (ret) + { + printk(KERN_ERR "Cant register platform_driver:" MODULE_NAME); + return ret; + } + + kbd_data.platform_dev = platform_device_register_simple(MODULE_NAME, -1, NULL, 0); + + if (IS_ERR(kbd_data.platform_dev)) + { + platform_driver_unregister(&kaiser_kbd_driver); + printk(KERN_ERR "Cant register device " MODULE_NAME); + return PTR_ERR(kbd_data.platform_dev);; + } + return ret; +} + +static void __exit kaiser_kbd_cleanup (void) +{ + platform_device_unregister(kbd_data.platform_dev); + platform_driver_unregister(&kaiser_kbd_driver); +} + +module_init (kaiser_kbd_init); +module_exit (kaiser_kbd_cleanup); + +MODULE_AUTHOR ("Marcin Baliniak"); +MODULE_DESCRIPTION ("Support for HTC Kaiser Keyboard"); +MODULE_LICENSE ("GPL"); diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index fde1e66..3cf49f0 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c @@ -67,7 +67,115 @@ static void acpuclk_disable(struct clk *clk); static unsigned long acpuclk_get_rate(struct clk *clk); int acpuclk_set_rate(struct clk *clk, unsigned long rate, int for_power_collapse); -extern struct clkctl_acpu_speed acpu_freq_tbl[]; +// Vogue SD card slot is on SDC1 on Kaiser it is SDC2 and SDC1 is wifi + +struct clock_rate_data { + unsigned offset, shift; +}; + +// Array of clock registers for SDCx +struct clock_rate_data sd_clock_regs[] = { + {0xa0, 7}, + {0xa8, 8} +}; + +struct clock_params { + unsigned freq,val0,val1,actual_freq; +}; + +#define CLK_ARRAY_SIZE 10 + +// i'm guessing these are dividers from the 400MHz clock +struct clock_params sd_clock_parameters[][CLK_ARRAY_SIZE]= { + { + // SDC1 Clock lines (WIFI SDIO) + // TODO change these + {2000000,0x40000-0x65,0xff9e0b78,576000}, // dont know about this one! + {4000000,0x20000-0xc1,0xff400b69,2000000}, // 400/0xc0=2 + {8000000,0x20000-0x61,0xffa00b69,4160000}, // 400/0x60=4.16 + {12000000,0x20000-0x31,0xffd00b69,8300000},// 400/48=8.3 + {19000000,0x20000-0x21,0xffe00b69,14000000},// 400/32=14 + {23000000,0x20000-0xb,0xfff60079,20000000}, // 400/10/2=20 + {24000000,0x70000-0x65,0xffa10b69,24000000},// 400*6/100=24 ; is this right? + {32000000,0x20000-0x11,0xfff00b69,25000000},// 400/17=25 + {48000000,0x20000-0xd,0xfff40b69,33333333},// 400/13=33.33 + {64000000,0x20000-0x9,0xfff80b69,50000000}, // 400/9=50 + }, + { + // SDC2 Clock lines SDIO SD Card slot + {2000000,0x40000-0x65,0xff9e0b78,576000}, // dont know about this one! + {4000000,0x20000-0xc1,0xff400b69,2000000}, // 400/0xc0=2 + {8000000,0x20000-0x61,0xffa00b69,4160000}, // 400/0x60=4.16 + {12000000,0x20000-0x31,0xffd00b69,8300000},// 400/48=8.3 + {19000000,0x20000-0x21,0xffe00b69,14000000},// 400/32=14 + {23000000,0x20000-0xb,0xfff60b79,20000000}, // 400/10/2=20 + {24000000,0x70000-0x65,0xffa10b69,24000000},// 400*6/100=24 ; is this right? + {32000000,0x20000-0x11,0xfff00b69,25000000},// 400/17=25 + {48000000,0x20000-0xd,0xfff40b69,33333333},// 400/13=33.33 + {64000000,0x20000-0x9,0xfff80b69,50000000}, // 400/9=50 + } +}; + + extern struct clkctl_acpu_speed acpu_freq_tbl[]; + +// Bad Bad TODO there is a better way to do this +int clock_to_index(unsigned id) +{ + if(id==SDC1_CLK) + return 0; + else if (id==SDC2_CLK) + return 1; + return 0; +} + +int sdcc_host_clock=0; +int set_sdcc_host_clock(unsigned id, unsigned freq) { + int n; + int index; + int mask; + int offset; + + index=clock_to_index(id); + mask=(1<>7)&1; + if(id==SDC2_CLK) + return (readl(MSM_CLK_CTL_BASE)>>8)&1; + if(id==SDC1_PCLK) + return 1; + return 0; +/* if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, 0)) return 0; else - return id; + return id;*/ } static int pc_pll_request(unsigned id, unsigned on) { +return 0; int res; on = !!on; @@ -161,8 +319,8 @@ int clk_register(struct clk *clk) mutex_lock(&clocks_mutex); spin_lock_init(&clk->lock); list_add_tail(&clk->list, &clocks); - if (clk->id == ACPU_CLK) - acpuclk_init(clk); +// if (clk->id == ACPU_CLK) +// acpuclk_init(clk); mutex_unlock(&clocks_mutex); return 0; } @@ -188,6 +346,7 @@ struct clk *clk_get(struct device *dev, const char *id) int clk_enable(struct clk *clk) { unsigned long flags; + if (!clk) return 0; if (clk->id == ACPU_CLK) return acpuclk_enable(clk); spin_lock_irqsave(&clk->lock, flags); @@ -201,6 +360,7 @@ int clk_enable(struct clk *clk) void clk_disable(struct clk *clk) { unsigned long flags; + if (!clk) return; if (clk->id == ACPU_CLK) return acpuclk_disable(clk); spin_lock_irqsave(&clk->lock, flags); @@ -213,6 +373,7 @@ void clk_disable(struct clk *clk) unsigned long clk_get_rate(struct clk *clk) { + if (!clk) return 0; if (clk->id == ACPU_CLK) return acpuclk_get_rate(clk); return pc_clk_get_rate(clk->id); @@ -220,12 +381,14 @@ unsigned long clk_get_rate(struct clk *clk) void clk_put(struct clk *clk) { + if (!clk) return; module_put(clk->owner); } int clk_set_rate(struct clk *clk, unsigned long rate) { int ret; + if (!clk) return 0; if (clk->id == ACPU_CLK) return acpuclk_set_rate(clk, rate, 0); if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) { @@ -287,7 +450,7 @@ static void acpuclk_disable(struct clk *clk) static int acpuclk_set_vdd_level(int vdd) { uint32_t current_vdd; - + return 0; current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07; #if PERF_SWITCH_DEBUG @@ -808,7 +971,8 @@ void __init clock_init(uint32_t acpu_switch_time_us, unsigned long power_collapse_khz, unsigned long wait_for_irq_khz) { - pr_info("clock_init()\n"); + return; + pr_info("clock_init()\n"); spin_lock_init(&clk_set_lock); mutex_init(&drv_state.lock); diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c index eb7ee13..9cb6e78 100644 --- a/arch/arm/mach-msm/common.c +++ b/arch/arm/mach-msm/common.c @@ -149,7 +149,7 @@ static struct platform_device msm_sdc2_device = { .coherent_dma_mask = 0xffffffff, }, }; - +/* static struct resource msm_sdc3_resources[] = { { .start = MSM_SDC3_BASE, @@ -205,19 +205,19 @@ static struct platform_device msm_sdc4_device = { .coherent_dma_mask = 0xffffffff, }, }; - +*/ static struct platform_device *msm_sdcc_devices[] __initdata = { &msm_sdc1_device, &msm_sdc2_device, - &msm_sdc3_device, - &msm_sdc4_device, +/* &msm_sdc3_device, + &msm_sdc4_device,*/ }; int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat) { struct platform_device *pdev; - if (controller < 1 || controller > 4) + if (controller < 1 || controller > 2) return -EINVAL; pdev = msm_sdcc_devices[controller-1]; diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index 582945f..a2a9d08 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -16,6 +16,8 @@ #include #include #include +#include + #define MSM_DMOV_CHANNEL_COUNT 16 @@ -29,7 +31,7 @@ static DEFINE_SPINLOCK(msm_dmov_lock); static unsigned int channel_active; static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; -unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS; +unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;// | MSM_DMOV_PRINT_FLOW | MSM_DMOV_PRINT_IO; #define MSM_DMOV_DPRINTF(mask, format, args...) \ do { \ @@ -54,6 +56,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) unsigned int status; spin_lock_irqsave(&msm_dmov_lock, irq_flags); + udelay(80); status = readl(DMOV_STATUS(id)); if (list_empty(&ready_commands[id]) && (status & DMOV_STATUS_CMD_PTR_RDY)) { @@ -112,6 +115,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) init_completion(&cmd.complete); msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd); + udelay(100); wait_for_completion(&cmd.complete); if (cmd.result != 0x80000002) { @@ -135,15 +139,17 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) spin_lock_irqsave(&msm_dmov_lock, irq_flags); + udelay(200); int_status = readl(DMOV_ISR); /* read and clear interrupt */ PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status); - + //printk("status %x\n", int_status); while (int_status) { mask = int_status & -int_status; id = fls(mask) - 1; PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id); int_status &= ~mask; ch_status = readl(DMOV_STATUS(id)); + //printk("status %x\n", ch_status); if (!(ch_status & DMOV_STATUS_RSLT_VALID)) { PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status); continue; @@ -157,12 +163,12 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) cmd = NULL; } else cmd = list_entry(active_commands[id].next, typeof(*cmd), list); - PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result); +// PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result); if (ch_result & DMOV_RSLT_DONE) { - PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", - id, ch_status); - PRINT_IO("msm_datamover_irq_handler id %d, got result " - "for %p, result %x\n", id, cmd, ch_result); +// PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", +// id, ch_status); +// PRINT_IO("msm_datamover_irq_handler id %d, got result " +// "for %p, result %x\n", id, cmd, ch_result); if (cmd) { list_del(&cmd->list); cmd->complete_func(cmd, ch_result, NULL); @@ -177,8 +183,8 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) errdata.flush[3] = readl(DMOV_FLUSH3(id)); errdata.flush[4] = readl(DMOV_FLUSH4(id)); errdata.flush[5] = readl(DMOV_FLUSH5(id)); - PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); - PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); +// PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); +// PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); if (cmd) { list_del(&cmd->list); cmd->complete_func(cmd, ch_result, &errdata); diff --git a/arch/arm/mach-msm/generic_gpio.c b/arch/arm/mach-msm/generic_gpio.c index 8609313..719265d 100644 --- a/arch/arm/mach-msm/generic_gpio.c +++ b/arch/arm/mach-msm/generic_gpio.c @@ -1,7 +1,7 @@ /* arch/arm/mach-msm/generic_gpio.c * * Copyright (C) 2007 Google, Inc. - * + * Lukas 'dcordes' Gorris * 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. @@ -18,11 +18,14 @@ #include #include #include +#include #include #include "gpio_chip.h" #define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5) +struct gpio_ops gpio_desc[16]; + struct gpio_state { unsigned long flags; int refcount; @@ -216,30 +219,40 @@ EXPORT_SYMBOL(gpio_direction_output); int gpio_get_value(unsigned gpio) { - int ret = -ENOTSUPP; - struct gpio_chip *chip; - unsigned long irq_flags; - - spin_lock_irqsave(&gpio_chips_lock, irq_flags); - chip = get_gpio_chip_locked(gpio); - if (chip && chip->read) - ret = chip->read(chip, gpio); - spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); - return ret; + if (gpio < GPIO_BASE_INCREMENT) + { + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->read) + ret = chip->read(chip, gpio); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + return ret; + } + else + return gpiodev2_get_value(gpio); } EXPORT_SYMBOL(gpio_get_value); void gpio_set_value(unsigned gpio, int on) { - int ret = -ENOTSUPP; - struct gpio_chip *chip; - unsigned long irq_flags; - - spin_lock_irqsave(&gpio_chips_lock, irq_flags); - chip = get_gpio_chip_locked(gpio); - if (chip && chip->write) - ret = chip->write(chip, gpio, on); - spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + if (gpio < GPIO_BASE_INCREMENT) + { + int ret = -ENOTSUPP; + struct gpio_chip *chip; + unsigned long irq_flags; + + spin_lock_irqsave(&gpio_chips_lock, irq_flags); + chip = get_gpio_chip_locked(gpio); + if (chip && chip->write) + ret = chip->write(chip, gpio, on); + spin_unlock_irqrestore(&gpio_chips_lock, irq_flags); + } + else + gpiodev2_set_value(gpio,on); } EXPORT_SYMBOL(gpio_set_value); diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c index 4ea2dcf..d00c835 100644 --- a/arch/arm/mach-msm/gpio.c +++ b/arch/arm/mach-msm/gpio.c @@ -413,6 +413,7 @@ struct tramp_gpio_smem static void msm_gpio_sleep_int(unsigned long arg) { +#ifdef CONFIG_MSM_SMD int i, j; struct tramp_gpio_smem *smem_gpio; @@ -429,14 +430,15 @@ static void msm_gpio_sleep_int(unsigned long arg) generic_handle_irq(MSM_GPIO_TO_INT(smem_gpio->fired[i][j])); } } +#endif } -static DECLARE_TASKLET(msm_gpio_sleep_int_tasklet, msm_gpio_sleep_int, 0); +// static DECLARE_TASKLET(msm_gpio_sleep_int_tasklet, msm_gpio_sleep_int, 0); void msm_gpio_enter_sleep(int from_idle) { int i; - struct tramp_gpio_smem *smem_gpio; +/* struct tramp_gpio_smem *smem_gpio; BUILD_BUG_ON(ARRAY_SIZE(msm_gpio_chips) != ARRAY_SIZE(smem_gpio->enabled)); @@ -449,10 +451,10 @@ void msm_gpio_enter_sleep(int from_idle) smem_gpio->polarity[i] = 0; } } - +*/ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { writel(msm_gpio_chips[i].int_enable[!from_idle], msm_gpio_chips[i].regs.int_en); - if (smem_gpio) { +/* if (smem_gpio) { uint32_t tmp; int start, index, shiftl, shiftr; start = msm_gpio_chips[i].chip.start; @@ -467,8 +469,9 @@ void msm_gpio_enter_sleep(int from_idle) smem_gpio->polarity[index] |= readl(msm_gpio_chips[i].regs.int_pos) << shiftl; smem_gpio->polarity[index+1] |= readl(msm_gpio_chips[i].regs.int_pos) >> shiftr; } +*/ } - +/* if (smem_gpio) { if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP) for (i = 0; i < ARRAY_SIZE(smem_gpio->enabled); i++) { @@ -482,27 +485,41 @@ void msm_gpio_enter_sleep(int from_idle) for(i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) smem_gpio->num_fired[i] = 0; } +*/ +} + +int gpios_setup=0; +void msm_button_enable(int i) { + unsigned v; + if(!gpios_setup) + return; + v=readl(msm_gpio_chips[1].regs.int_en); + if(i) + writel(v | 0x6f8000,msm_gpio_chips[1].regs.int_en); + else + writel(v & ~0x6f8000,msm_gpio_chips[1].regs.int_en); } void msm_gpio_exit_sleep(void) { int i; - struct tramp_gpio_smem *smem_gpio; +/* struct tramp_gpio_smem *smem_gpio; BUILD_BUG_ON(ARRAY_SIZE(msm_gpio_chips) != ARRAY_SIZE(smem_gpio->enabled)); smem_gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*smem_gpio)); - +*/ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { writel(msm_gpio_chips[i].int_enable[0], msm_gpio_chips[i].regs.int_en); } - +/* if (smem_gpio && (smem_gpio->num_fired[0] || smem_gpio->num_fired[1])) { if (msm_gpio_debug_mask & GPIO_DEBUG_SLEEP) printk(KERN_INFO "gpio: fired %x %x\n", smem_gpio->num_fired[0], smem_gpio->num_fired[1]); tasklet_schedule(&msm_gpio_sleep_int_tasklet); } +*/ } void __init msm_init_gpio(void) diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S index 588eb07..74604c9 100644 --- a/arch/arm/mach-msm/idle.S +++ b/arch/arm/mach-msm/idle.S @@ -25,8 +25,9 @@ ENTRY(msm_pm_collapse) mrc p15, 0, r1, c1, c0, 0 /* MMU control */ mrc p15, 0, r2, c2, c0, 0 /* ttb */ mrc p15, 0, r3, c3, c0, 0 /* dacr */ - mrc p15, 0, ip, c13, c0, 1 /* context ID */ - stmia r0!, {r1-r3, ip} +@ mrc p15, 0, ip, c13, c0, 1 /* context ID */ +@ stmia r0!, {r1-r3, ip} + stmia r0!, {r1-r3} /* fall though */ ENTRY(msm_arch_idle) #if defined(CONFIG_MSM_FIQ_SUPPORT) @@ -63,10 +64,10 @@ ENTRY(msm_pm_collapse_exit) adr r3, msm_pm_collapse_exit add r1, r1, r3 sub r1, r1, r2 - ldmdb r1!, {r2-r5} + ldmdb r1!, {r2-r4} mcr p15, 0, r4, c3, c0, 0 /* dacr */ mcr p15, 0, r3, c2, c0, 0 /* ttb */ - mcr p15, 0, r5, c13, c0, 1 /* context ID */ +@ mcr p15, 0, r5, c13, c0, 1 /* context ID */ ldmdb r1!, {r4-r14} mov r0, #1 @@ -84,6 +85,6 @@ ENTRY(msm_pm_collapse_exit) saved_state: .space 4 * 11 /* r4-14 */ - .space 4 * 4 /* cp15 */ + .space 4 * 3 /* cp15 */ saved_state_end: diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index edc638f..b5a7038 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -59,8 +59,8 @@ static struct map_desc msm_io_desc[] __initdata = { }, MSM_DEVICE(SDC1), MSM_DEVICE(SDC2), - MSM_DEVICE(SDC3), - MSM_DEVICE(SDC4), +/* MSM_DEVICE(SDC3), + MSM_DEVICE(SDC4),*/ }; void __init msm_map_common_io(void) diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c index c317bc9..69c73f5 100644 --- a/arch/arm/mach-msm/irq.c +++ b/arch/arm/mach-msm/irq.c @@ -222,18 +222,19 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) polarity |= b; if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) polarity &= ~b; - writel(polarity, preg); +// writel(polarity, preg); msm_irq_shadow_reg[index].int_polarity = polarity; type = msm_irq_shadow_reg[index].int_type; - if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { + if (flow_type & (IRQF_TRIGGER_RISING )) { //| IRQF_TRIGGER_FALLING)) { type |= b; - irq_desc[irq].handle_irq = handle_edge_irq; +// irq_desc[irq].handle_irq = handle_edge_irq; } - if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { +/* if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { type &= ~b; irq_desc[irq].handle_irq = handle_level_irq; } +*/ writel(type, treg); msm_irq_shadow_reg[index].int_type = type; return 0; @@ -258,11 +259,11 @@ int msm_irq_idle_sleep_allowed(void) void msm_irq_enter_sleep1(bool arm9_wake, int from_idle) { struct smsm_interrupt_info int_info; - if (arm9_wake) { +/* if (arm9_wake) { int_info.aArm_en_mask = msm_irq_smsm_wake_enable[!from_idle]; int_info.aArm_interrupts_pending = 0; smsm_set_interrupt_info(&int_info); - } + }*/ } int msm_irq_enter_sleep2(bool arm9_wake, int from_idle) @@ -323,10 +324,10 @@ void msm_irq_exit_sleep1(void) msm_irq_ack(INT_A9_M2A_6); for (i = 0; i < 2; i++) { - writel(msm_irq_shadow_reg[i].int_type, VIC_INT_TYPE0 + i * 4); - writel(msm_irq_shadow_reg[i].int_polarity, VIC_INT_POLARITY0 + i * 4); +// writel(msm_irq_shadow_reg[i].int_type, VIC_INT_TYPE0 + i * 4); +// writel(msm_irq_shadow_reg[i].int_polarity, VIC_INT_POLARITY0 + i * 4); writel(msm_irq_shadow_reg[i].int_en[0], VIC_INT_EN0 + i * 4); - writel(msm_irq_shadow_reg[i].int_select, VIC_INT_SELECT0 + i * 4); +// writel(msm_irq_shadow_reg[i].int_select, VIC_INT_SELECT0 + i * 4); } writel(3, VIC_INT_MASTEREN); int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); diff --git a/arch/arm/mach-msm/kaiser-pm.c b/arch/arm/mach-msm/kaiser-pm.c new file mode 100644 index 0000000..9bcfecc --- /dev/null +++ b/arch/arm/mach-msm/kaiser-pm.c @@ -0,0 +1,439 @@ +/* arch/arm/mach-msm/pm.c + * + * MSM Power Management Routines + * + * Copyright (C) 2007 Google, 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 "smd_private.h" +#include "clock.h" +#include "proc_comm.h" +// #include "vogue-hw.h" +#include + +enum { + MSM_PM_DEBUG_SUSPEND = 1U << 0, + MSM_PM_DEBUG_POWER_COLLAPSE = 1U << 1, + MSM_PM_DEBUG_STATE = 1U << 2, + MSM_PM_DEBUG_CLOCK = 1U << 3, + MSM_PM_DEBUG_RESET_VECTOR = 1U << 4, + MSM_PM_DEBUG_SMSM_STATE = 1U << 5, +}; +static int msm_pm_debug_mask = MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE; +module_param_named(debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +enum { + MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND, + MSM_PM_SLEEP_MODE_POWER_COLLAPSE, + MSM_PM_SLEEP_MODE_APPS_SLEEP, + MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT, + MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT, +}; +static int msm_pm_sleep_mode = CONFIG_MSM7X00A_SLEEP_MODE; +module_param_named(sleep_mode, msm_pm_sleep_mode, int, S_IRUGO | S_IWUSR | S_IWGRP); + +#define A11S_CLK_SLEEP_EN (MSM_CSR_BASE + 0x11c) +#define A11S_CLK_CTL (MSM_CSR_BASE + 0x100) +#define A11S_CLK_SEL (MSM_CSR_BASE + 0x104) +#define A11S_PWRDOWN (MSM_CSR_BASE + 0x440) +#define A11S_STANDBY_CTL (MSM_CSR_BASE + 0x108) +#define A11RAMBACKBIAS (MSM_CSR_BASE + 0x508) + +static struct clk *acpu_clk; +unsigned long pm_saved_acpu_clk_rate; + +int acpuclk_set_rate(struct clk *clk, unsigned long rate, int for_power_collapse); + +int msm_pm_collapse(void); +void msm_pm_collapse_exit(void); + +static uint32_t *msm_pm_reset_vector; + +#define TARGET_CLOCK_RATE 19200000 +/* +static int +msm_pm_wait_state(uint32_t wait_state_all_set, uint32_t wait_state_all_clear, + uint32_t wait_state_any_set, uint32_t wait_state_any_clear) +{ + int i; + uint32_t state; + + for (i = 0; i < 100000; i++) { + state = smsm_get_state(); + if (((state & wait_state_all_set) == wait_state_all_set) && + ((~state & wait_state_all_clear) == wait_state_all_clear) && + (wait_state_any_set == 0 || (state & wait_state_any_set) || + wait_state_any_clear == 0 || (state & wait_state_any_clear))) + return 0; + } + printk(KERN_ERR "msm_pm_wait_state(%x, %x, %x, %x) failed %x\n", + wait_state_all_set, wait_state_all_clear, + wait_state_any_set, wait_state_any_clear, state); + return -ETIMEDOUT; +} +*/ +static int setclock(int on) { + unsigned sel=readl(A11S_CLK_SEL)&1; + unsigned clk=readl(A11S_CLK_CTL); + unsigned shift=sel*8; + if(on) + { + writel(6 | (sel ^ 1),A11S_CLK_SEL); + writel(0x11<>shift)), A11S_CLK_CTL); + } else { + writel((clk & (0xff00>>shift)), A11S_CLK_CTL); + writel((sel ^ 1),A11S_CLK_SEL); + } + printk("A11 CLK %x %x\n",readl(A11S_CLK_CTL),readl(A11S_CLK_SEL)); +} + +static int msm_sleep(int sleep_mode, uint32_t sleep_delay, int from_idle) +{ + unsigned clocks; + void msm_irq_enter_sleep(bool arm9_wake, int from_idle); + void msm_irq_exit_sleep(void); + void msm_gpio_enter_sleep(int from_idle); + void msm_gpio_exit_sleep(void); + void msm_button_enable(int); + extern int gpios_setup; + return 0; + gpios_setup=1; + msm_button_enable(0); + // msm_gpio_enter_sleep(from_idle); + msm_irq_enter_sleep(0, from_idle); + // pm_saved_acpu_clk_rate = clk_get_rate(acpu_clk); + // acpuclk_set_rate(acpu_clk, TARGET_CLOCK_RATE, 1); + + printk("Going to sleep\n"); + setclock(0); // set clock to slow while suspended + // clocks=readl(MSM_CLK_CTL_BASE); + // disable them there pesky clocks + // writel(0,MSM_CLK_CTL_BASE); + +// writel(0,MSM_CSR_BASE+0x440); // don't know what this does! +// vogue_set_egpio(1,4,0); +// vogue_set_egpio(1,5,1); + arch_idle(); +// vogue_set_egpio(1,5,0); +// vogue_set_egpio(1,4,1); + // enable them again + //writel(clocks,MSM_CLK_CTL_BASE); + setclock(1); // clck back up to speed + // acpuclk_set_rate(acpu_clk, pm_saved_acpu_clk_rate, 1); + printk("Wake up sleepy head\n"); + msm_irq_exit_sleep(); + // msm_gpio_exit_sleep(); + +/* + uint32_t saved_vector[2]; + int collapsed; + void msm_irq_enter_sleep1(bool arm9_wake, int from_idle); + void msm_irq_enter_sleep2(bool arm9_wake, int from_idle); + void msm_irq_exit_sleep1(void); + void msm_irq_exit_sleep2(void); + void msm_irq_exit_sleep3(void); + void msm_gpio_enter_sleep(int from_idle); + void msm_gpio_exit_sleep(void); + uint32_t enter_state; + uint32_t enter_wait_set = 0; + uint32_t enter_wait_clear = 0; + uint32_t exit_state; + uint32_t exit_wait_clear = 0; + uint32_t exit_wait_set = 0; + int ret; + + if (msm_pm_debug_mask & MSM_PM_DEBUG_SUSPEND) + printk(KERN_INFO "msm_pm_enter(): mode %d delay %u idle %d\n", + sleep_mode, sleep_delay, from_idle); + + switch (sleep_mode) { + case MSM_PM_SLEEP_MODE_POWER_COLLAPSE: + enter_state = SMSM_PWRC; + enter_wait_set = SMSM_RSA; + exit_state = SMSM_WFPI; + exit_wait_clear = SMSM_RSA; + break; + case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND: + enter_state = SMSM_PWRC_SUSPEND; + enter_wait_set = SMSM_RSA; + exit_state = SMSM_WFPI; + exit_wait_clear = SMSM_RSA; + break; + case MSM_PM_SLEEP_MODE_APPS_SLEEP: + enter_state = SMSM_SLEEP; + exit_state = SMSM_SLEEPEXIT; + exit_wait_set = SMSM_SLEEPEXIT; + break; + default: + enter_state = 0; + exit_state = 0; + } + + msm_irq_enter_sleep1(!!enter_state, from_idle); + msm_gpio_enter_sleep(from_idle); + + if (enter_state) { + if (sleep_delay == 0 && sleep_mode >= MSM_PM_SLEEP_MODE_APPS_SLEEP) + sleep_delay = 192000*5; + smsm_set_sleep_duration(sleep_delay); + ret = smsm_change_state(SMSM_RUN, enter_state); + if (ret) { + printk(KERN_ERR "msm_pm_enter(): smsm_change_state %x failed\n", enter_state); + enter_state = 0; + exit_state = 0; + } + ret = msm_pm_wait_state(enter_wait_set, enter_wait_clear, 0, 0); + if (ret) { + printk(KERN_INFO "msm_pm_enter(): msm_pm_wait_state failed, %x\n", smsm_get_state()); + goto enter_failed; + } + } + msm_irq_enter_sleep2(!!enter_state, from_idle); + + if (enter_state) { + writel(0x1f, A11S_CLK_SLEEP_EN); + writel(1, A11S_PWRDOWN); + + writel(0, A11S_STANDBY_CTL); + writel(0, A11RAMBACKBIAS); + + if (msm_pm_debug_mask & MSM_PM_DEBUG_STATE) + printk(KERN_INFO "msm_pm_enter(): enter " + "A11S_CLK_SLEEP_EN %x, A11S_PWRDOWN %x, " + "smsm_get_state %x\n", readl(A11S_CLK_SLEEP_EN), + readl(A11S_PWRDOWN), smsm_get_state()); + } + + if (sleep_mode <= MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT) { + pm_saved_acpu_clk_rate = clk_get_rate(acpu_clk); + if (msm_pm_debug_mask & MSM_PM_DEBUG_CLOCK) + printk(KERN_INFO "msm_pm_enter(): change clk %ld -> %d" + "\n", pm_saved_acpu_clk_rate, TARGET_CLOCK_RATE); + acpuclk_set_rate(acpu_clk, TARGET_CLOCK_RATE, 1); + } + if (sleep_mode < MSM_PM_SLEEP_MODE_APPS_SLEEP) { + if (msm_pm_debug_mask & MSM_PM_DEBUG_SMSM_STATE) + smsm_print_sleep_info(); + saved_vector[0] = msm_pm_reset_vector[0]; + saved_vector[1] = msm_pm_reset_vector[1]; + msm_pm_reset_vector[0] = 0xE51FF004; // ldr pc, 4 + msm_pm_reset_vector[1] = virt_to_phys(msm_pm_collapse_exit); + if (msm_pm_debug_mask & MSM_PM_DEBUG_RESET_VECTOR) + printk(KERN_INFO "msm_pm_enter: vector %x %x -> " + "%x %x\n", saved_vector[0], saved_vector[1], + msm_pm_reset_vector[0], msm_pm_reset_vector[1]); + collapsed = msm_pm_collapse(); + msm_pm_reset_vector[0] = saved_vector[0]; + msm_pm_reset_vector[1] = saved_vector[1]; + if (collapsed) { + cpu_init(); + local_fiq_enable(); + } + if (msm_pm_debug_mask & MSM_PM_DEBUG_POWER_COLLAPSE) + printk(KERN_INFO "msm_pm_collapse(): returned %d\n", + collapsed); + if (msm_pm_debug_mask & MSM_PM_DEBUG_SMSM_STATE) + smsm_print_sleep_info(); + } else + arch_idle(); + + if (sleep_mode <= MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT) { + if (msm_pm_debug_mask & MSM_PM_DEBUG_CLOCK) + printk(KERN_INFO "msm_pm_enter(): change clk %d -> %ld" + "\n", TARGET_CLOCK_RATE, pm_saved_acpu_clk_rate); + if (acpuclk_set_rate(acpu_clk, pm_saved_acpu_clk_rate, 1) < 0) + printk(KERN_ERR "msm_pm_enter(): clk_set_rate %ld " + "failed\n", pm_saved_acpu_clk_rate); + } + if (msm_pm_debug_mask & MSM_PM_DEBUG_STATE) + printk(KERN_INFO "msm_pm_enter(): exit A11S_CLK_SLEEP_EN %x, " + "A11S_PWRDOWN %x, smsm_get_state %x\n", + readl(A11S_CLK_SLEEP_EN), readl(A11S_PWRDOWN), + smsm_get_state()); +enter_failed: + msm_irq_exit_sleep1(); + if (enter_state) { + writel(0x00, A11S_CLK_SLEEP_EN); + writel(0, A11S_PWRDOWN); + smsm_change_state(enter_state, exit_state); + msm_pm_wait_state(exit_wait_set, exit_wait_clear, 0, 0); + if (msm_pm_debug_mask & MSM_PM_DEBUG_STATE) + printk(KERN_INFO "msm_pm_enter(): sleep exit " + "A11S_CLK_SLEEP_EN %x, A11S_PWRDOWN %x, " + "smsm_get_state %x\n", readl(A11S_CLK_SLEEP_EN), + readl(A11S_PWRDOWN), smsm_get_state()); + if (msm_pm_debug_mask & MSM_PM_DEBUG_SMSM_STATE) + smsm_print_sleep_info(); + } + msm_irq_exit_sleep2(); + if (enter_state) { + smsm_change_state(exit_state, SMSM_RUN); + msm_pm_wait_state(SMSM_RUN, 0, 0, 0); + if (msm_pm_debug_mask & MSM_PM_DEBUG_STATE) + printk(KERN_INFO "msm_pm_enter(): sleep exit " + "A11S_CLK_SLEEP_EN %x, A11S_PWRDOWN %x, " + "smsm_get_state %x\n", readl(A11S_CLK_SLEEP_EN), + readl(A11S_PWRDOWN), smsm_get_state()); + } + msm_irq_exit_sleep3(); + msm_gpio_exit_sleep(); + return 0; +*/ +} +int msm_arch_idle(void); +void arch_idle(void) +{ + int ret; + int64_t sleep_time; + int low_power = 0; + msm_arch_idle(); + /* +#ifdef CONFIG_MSM_IDLE_STATS + int64_t t1; + static int64_t t2; + int exit_stat; +#endif + int allow_sleep = + msm_pm_idle_sleep_mode < MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT && + msm_irq_idle_sleep_allowed(); + sleep_time = msm_timer_enter_idle(); +#ifdef CONFIG_MSM_IDLE_STATS + t1 = ktime_to_ns(ktime_get()); + msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - t2); + msm_pm_add_stat(MSM_PM_STAT_REQUESTED_IDLE, sleep_time); +#endif + if (msm_pm_debug_mask & MSM_PM_DEBUG_IDLE) + printk(KERN_INFO "arch_idle: sleep time %llu, allow_sleep %d\n", + sleep_time, allow_sleep); + if (sleep_time < msm_pm_idle_sleep_min_time || !allow_sleep) { + msm_arch_idle(); +#ifdef CONFIG_MSM_IDLE_STATS + exit_stat = MSM_PM_STAT_IDLE_WFI; +#endif + } else { + low_power = 1; + do_div(sleep_time, NSEC_PER_SEC / 32768); + if (sleep_time > 0x6DDD000) { + printk("sleep_time too big %lld\n", sleep_time); + sleep_time = 0x6DDD000; + } + ret = msm_sleep(msm_pm_idle_sleep_mode, sleep_time, 1); +#ifdef CONFIG_MSM_IDLE_STATS + if (ret) + exit_stat = MSM_PM_STAT_IDLE_FAILED_SLEEP; + else + exit_stat = MSM_PM_STAT_IDLE_SLEEP; +#endif + } + msm_timer_exit_idle(low_power); +#ifdef CONFIG_MSM_IDLE_STATS + t2 = ktime_to_ns(ktime_get()); + msm_pm_add_stat(exit_stat, t2 - t1); +#endif + */ +} +static int msm_pm_enter(suspend_state_t state) +{ + msm_sleep(msm_pm_sleep_mode, 0, 0); + return 0; +} + +static struct platform_suspend_ops msm_pm_ops = { + .enter = msm_pm_enter, + .valid = suspend_valid_only_mem, +}; + +static uint32_t restart_reason = 0x776655AA; + +static void msm_pm_power_off(void) +{ +// msm_proc_comm(PCOM_POWER_DOWN, 0, 0); +// for (;;) ; +} + +static void msm_pm_restart(char str) +{ + /* If there's a hard reset hook and the restart_reason + * is the default, prefer that to the (slower) proc_comm + * reset command. + */ +/* + if ((restart_reason == 0x776655AA) && msm_reset_hook) { + msm_reset_hook(str); + } else { + msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0); + } + for (;;) ; +*/ +} + +static int msm_reboot_call(struct notifier_block *this, unsigned long code, void *_cmd) +{ + if((code == SYS_RESTART) && _cmd) { + char *cmd = _cmd; + if (!strcmp(cmd, "bootloader")) { + restart_reason = 0x77665500; + } else if (!strcmp(cmd, "recovery")) { + restart_reason = 0x77665502; + } else if (!strcmp(cmd, "eraseflash")) { + restart_reason = 0x776655EF; + } else if (!strncmp(cmd, "oem-", 4)) { + unsigned code = simple_strtoul(cmd + 4, 0, 16) & 0xff; + restart_reason = 0x6f656d00 | code; + } else { + restart_reason = 0x77665501; + } + } + return NOTIFY_DONE; +} + +static struct notifier_block msm_reboot_notifier = +{ + .notifier_call = msm_reboot_call, +}; + +static int __init msm_pm_init(void) +{ + pm_power_off = msm_pm_power_off; + arm_pm_restart = msm_pm_restart; + + register_reboot_notifier(&msm_reboot_notifier); + + acpu_clk = clk_get(NULL, "acpu_clk"); + if (acpu_clk == NULL) { + printk(KERN_ERR "msm_pm_init: failed get acpu_clk\n"); + //return -ENODEV; + } + + msm_pm_reset_vector = ioremap(0, PAGE_SIZE); + if (msm_pm_reset_vector == NULL) { + printk(KERN_ERR "msm_pm_init: failed to map reset vector\n"); + return -ENODEV; + } + + suspend_set_ops(&msm_pm_ops); + return 0; +} + +__initcall(msm_pm_init); diff --git a/arch/arm/mach-msm/kaiser-smd.c b/arch/arm/mach-msm/kaiser-smd.c new file mode 100644 index 0000000..e9b8362 --- /dev/null +++ b/arch/arm/mach-msm/kaiser-smd.c @@ -0,0 +1,583 @@ +/* arch/arm/mach-msm/kaiser-smd.c - MSM7200 shared memory communications. + * + * Authors: Martin Johnson , + * Lukas Gorris , + * Martin Ling , + * Patrick Remy + * + * Based on smd.c by Brian Swetland + * + * 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 "smd_private.h" +#include "proc_comm.h" + +#define MODULE_NAME "msm_smd" + +// Toggle to enable debug printks. +#ifdef KAISER_SMD_DEBUG +#define D(x...) printk(x) +#else +#define D(x...) do {} while (0) +#endif + +/* This spinlock is used to synchronize between the + * irq handler and code that mutates the channel + * list or fiddles with channel state. */ +static DEFINE_SPINLOCK(smd_lock); + +/* This mutex is used during open() and close() + * operations to avoid races while creating or + * destroying smd_channel structures. */ +static DEFINE_MUTEX(smd_creation_mutex); + +// Flag set when smd_core_init() has been called successfully. +static int smd_initialized = 0; + +// FIFO states. +#define SMD_SS_CLOSED 0x00000000 +#define SMD_SS_OPENING 0x00000001 +#define SMD_SS_OPENED 0x00000002 +#define SMD_SS_FLUSHING 0x00000003 +#define SMD_SS_CLOSING 0x00000004 +#define SMD_SS_RESET 0x00000005 +#define SMD_SS_RESET_OPENING 0x00000006 + +// Size of the circular buffer in each shared memory FIFO. +#define BUF_SIZE 0x2000 + +// Maximum number of bytes to read/write before notifying. +#define BURST_SIZE 0xf4 + +// FIFO structure located in shared memory. +struct smd_fifo +{ + volatile unsigned int state; + volatile unsigned char fDSR; + volatile unsigned char fCTS; + volatile unsigned char fCD; + volatile unsigned char fRI; + volatile unsigned char fHEAD; + volatile unsigned char fTAIL; + volatile unsigned char fSTATE; + volatile unsigned char fUNUSED; + volatile unsigned int tail; + volatile unsigned int head; + volatile unsigned int padding; + volatile char buffer[BUF_SIZE]; +}; + +// Bidirectional channel implemented using two FIFOs. +struct smd_channel +{ + volatile struct smd_fifo *send; + volatile struct smd_fifo *recv; + struct list_head ch_list; + + unsigned n; + void *priv; + void (*notify)(void *priv, unsigned flags); +}; + +// List of currently open channels. +static LIST_HEAD(smd_ch_list); + +// How many bytes are available for reading from a channel. +int smd_read_avail(struct smd_channel *ch) +{ + if (ch->recv == NULL) + return 0; + + return (ch->recv->head - ch->recv->tail + BUF_SIZE) % BUF_SIZE; +} + +// How many bytes we are free to write to a channel. +int smd_write_avail(struct smd_channel *ch) +{ + if (ch->send == NULL) + return 0; + + return (BUF_SIZE - 1) - + ((ch->send->head- ch->send->tail + BUF_SIZE) % BUF_SIZE); +} + +#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) + +// Interrupt the ARM9 to tell it we have written to the shared memory. +static inline void notify_other_smd(int ch) +{ + /* TODO: Isolate which line is used for which channel and set + * only the appropriate one for the given channel. */ + writel(1,MSM_A2M_INT(0)); + writel(1,MSM_A2M_INT(1)); + writel(1,MSM_A2M_INT(2)); +} + +static DEFINE_SPINLOCK(proc_comm_lock); +static DECLARE_WAIT_QUEUE_HEAD(proc_comm_queue); + +int irq6_received; + +static inline void notify_other_proc_comm(void) +{ + writel(1, MSM_A2M_INT(6)); +} + +static irqreturn_t proc_comm_isr(int irq, void *data) { + irq6_received=1; + wake_up(&proc_comm_queue); + return IRQ_HANDLED; +} + +#define PC_COMMAND 0x00 +#define PC_STATUS 0x04 +#define PC_DATA1 0x20 +#define PC_DATA2 0x30 +#define PC_NUMBER 0x08 +#define PC_RESP_NUMBER 0x0c +#define PC_RESULT_DATA1 0x24 +// wild guess.... +#define PC_RESULT_DATA2 0x34 + +int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) +{ + unsigned long flags; + unsigned base = MSM_SHARED_RAM_BASE+0xfc100; + unsigned timeout = (2000000 / 10); + unsigned int number; + + + printk("msm_proc_comm(%x,%x,%x)\n", cmd, + (data1 ? *data1 : 0), + (data2 ? *data2 : 0)); + + // for the moment, the only commands we've identified are + // 0x17 and 0x18. In order not to break existing code, it's best + // to not do anything for other commands. + // 0x18 + 0x17 vibrate on and off + // 0x181 + 0x182 Real Time Clock + // + if (cmd != 0x17 && cmd !=0x18 && cmd != 0x181 && cmd != 0x182 && cmd != 0x119) + return -1; + + spin_lock_irqsave(&proc_comm_lock, flags); + irq6_received=0; + number = readl(base + PC_NUMBER); + writel(data1 ? *data1 : 0, base + PC_DATA1); + writel(data2 ? *data2 : 0, base + PC_DATA2); + writel(cmd, base + PC_COMMAND); + writel(number + 1, base + PC_NUMBER); + spin_unlock_irqrestore(&proc_comm_lock, flags); + notify_other_proc_comm(); + + // unclear how to fetch the command return value + // irq6 or polling PC_RESP_NUMBER + // (wince seems to poll PC_RESP_NUMBER, though) + do { + if (readl(base+PC_RESP_NUMBER) == (number+1)) { + break; + } + udelay(5); + } while (--timeout != 0); + + wait_event_interruptible(proc_comm_queue, irq6_received); + + if (readl(base + PC_STATUS) == cmd) { + if (data1) + *data1 = readl(base + PC_RESULT_DATA1); + if (data2) + *data2 = readl(base + PC_RESULT_DATA2); + } + + // wince seems to reset this + writel(0, base + PC_STATUS); + writel(0, base + PC_RESULT_DATA1); + writel(0, base + PC_RESULT_DATA2); + + return 0; +} + +// Check for changes to the FIFOs of all currently open channels. +void check_for_smd_data(void) +{ + struct smd_channel *ch; + unsigned long flags; + + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) { + if(ch->recv->head != ch->recv->tail) + ch->notify(ch->priv, SMD_EVENT_DATA); + if(ch->send->head != ch->send->tail) + notify_other_smd(ch->n); + } + spin_unlock_irqrestore(&smd_lock, flags); +} + +// Interrupt handler called when the ARM9 has written to us. +static irqreturn_t smd_irq_handler(int irq, void *data) +{ + D("smd: irq %d\n", irq); + /* TODO: work out which interrupt actually relates to + * each FIFO. For now, just check all of them. */ + check_for_smd_data(); + return IRQ_HANDLED; +} + +// Write data to a channel. +int smd_write(smd_channel_t *ch, const void *_data, int len) +{ + const unsigned char *buf = _data; + unsigned int myhead; + int sent = 0; + + if (ch->send == NULL) + return -ENODEV; + + if (len < 0) + return -EINVAL; + + myhead = ch->send->head; + + while (sent < len) { + ch->send->buffer[myhead] = *buf++; + + if ((sent++ % BURST_SIZE) == 0) { + ch->send->head = myhead; + ch->send->fHEAD = 1; + notify_other_smd(ch->n); + } + + myhead = (myhead + 1) % BUF_SIZE; + } + + ch->send->head = myhead; + ch->send->fHEAD = 1; + + notify_other_smd(ch->n); + + return sent; +} + +// Read data from a channel. +int smd_read(smd_channel_t *ch, void *data, int len) +{ + unsigned char *buf = data; + unsigned int mytail; + int recvd = 0; + + if (ch->recv == NULL) + return -ENODEV; + + if (len < 0) + return -EINVAL; + + mytail = ch->recv->tail; + + while (recvd < len) { + if (buf) + *buf++ = ch->recv->buffer[mytail]; + + if ((recvd++ % BURST_SIZE) == 0) { + ch->recv->tail = mytail; + ch->recv->fTAIL = 1; + notify_other_smd(ch->n); + } + + mytail = (mytail + 1) % BUF_SIZE; + } + + ch->recv->tail = mytail; + ch->recv->fTAIL = 1; + + notify_other_smd(ch->n); + + return recvd; +} + +// Set the state of a FIFO. +static void smd_set_state(volatile struct smd_fifo *hc, + unsigned state, unsigned ch) +{ + if (state == SMD_SS_OPENED) { + hc->fDSR = 1; + hc->fCTS = 1; + hc->fCD = 1; + } else { + hc->fDSR = 0; + hc->fCTS = 0; + hc->fCD = 0; + } + hc->state = state; + hc->fSTATE = 1; + notify_other_smd(ch); +} + +// Force both sides of a channel to check for data. +void smd_kick(smd_channel_t *ch) +{ + unsigned long flags; + + spin_lock_irqsave(&smd_lock, flags); + ch->notify(ch->priv, SMD_EVENT_DATA); + notify_other_smd(ch->n); + spin_unlock_irqrestore(&smd_lock, flags); +} + +// Empty default notify function. +static void do_nothing_notify(void *priv, unsigned flags) {} + +// Open an shared memory channel. +int smd_open(int n, smd_channel_t **_ch, void *priv, + void (*notify)(void *, unsigned)) +{ + struct smd_channel *ch; + unsigned long flags; + int res = 0; + + if (!smd_initialized) { + printk(KERN_INFO "smd_open() before smd_core_init()\n"); + return -ENODEV; + } + + if (notify == 0) + notify = do_nothing_notify; + + mutex_lock(&smd_creation_mutex); + + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) { + if (ch->n == n) { + res = -ENODEV; + break; + } + } + spin_unlock_irqrestore(&smd_lock, flags); + if (res) goto out; + + ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); + if (ch == 0) { + res = -ENOMEM; + goto out; + } + + switch (n) { + case 0: + // AT command channel to GSM modem. + ch->send = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x041f0); + ch->recv = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x32418); + break; + case 1: + // Data channel to GSM modem. + ch->send = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x12298); + ch->recv = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x404c0); + break; +/* case 2: + // unknown channel 1 + ch->send = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x8220); + ch->recv = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x36448); + break; + case 3: + // unknown channel 2 + ch->send = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0xa238); + ch->recv = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x38460); + break;*/ + case 7: + // Read-only channel from GPS. + ch->send = NULL; + ch->recv = (struct smd_fifo *)(MSM_SHARED_RAM_BASE+0x545b0); + break; + default: + res = -ENODEV; + goto out; + } + + ch->priv = priv; + ch->notify = notify; + ch->n = n; + + *_ch = ch; + + // TODO: Set recv state, do other state changes... + smd_set_state(ch->send, SMD_SS_OPENED, ch->n); + + spin_lock_irqsave(&smd_lock, flags); + list_add(&ch->ch_list, &smd_ch_list); + spin_unlock_irqrestore(&smd_lock, flags); + + // Trigger handling of any data already waiting in the FIFOs. + smd_kick(ch); + +out: + mutex_unlock(&smd_creation_mutex); + return res; +} + +// Close an SMD channel. +int smd_close(smd_channel_t *ch) +{ + unsigned long flags; + + if (ch == NULL) + return -EINVAL; + + mutex_lock(&smd_creation_mutex); + spin_lock_irqsave(&smd_lock, flags); + + list_del(&ch->ch_list); + D("smd_close: closing ch %d\n", ch->n); + + spin_unlock_irqrestore(&smd_lock, flags); + mutex_unlock(&smd_creation_mutex); + + return 0; +} + +// Init for Kaiser SMD driver. +int smd_core_init(void) +{ + int r; + int i; + printk(KERN_INFO "smd_core_init()\n"); + + r = request_irq(INT_A9_M2A_6,proc_comm_isr, IRQF_TRIGGER_RISING, + "proc_comm", 0); + if(r<0) return r; + r=enable_irq_wake(INT_A9_M2A_6); + if (r < 0) + printk(KERN_ERR "smd_core_init: " + "enable_irq_wake failed for INT_A9_M2A_6\n"); + + /* TODO: These interrupts are used by the ARM9 to tell us that it has + * written to the shared memory. They are associated with particular + * channels and should really be requested only when those channels + * are opened. */ + for (i = 0; i < 6; i++) { + r = request_irq(INT_A9_M2A_0+i, smd_irq_handler, + IRQF_TRIGGER_RISING, "smd_dev", 0); + if (r < 0) + return r; + r = enable_irq_wake(INT_A9_M2A_0+i); + if (r < 0) + printk(KERN_ERR "smd_core_init: " + "enable_irq_wake failed for INT_A9_M2A_%d\n",i); + } + + smd_initialized = 1; + + printk(KERN_INFO "smd_core_init() done\n"); + + return 0; +} + +/* Generic driver glue follows below... */ + +static int __init msm_smd_probe(struct platform_device *pdev) +{ + printk(KERN_INFO "smd_init()\n"); + + if (smd_core_init()) { + printk(KERN_ERR "smd_core_init() failed\n"); + return -1; + } + + return 0; +} + +static struct platform_driver msm_smd_driver = { + .probe = msm_smd_probe, + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init msm_smd_init(void) +{ + return platform_driver_register(&msm_smd_driver); +} + +module_init(msm_smd_init); + +MODULE_DESCRIPTION("MSM Shared Memory Core for Kaiser"); +MODULE_AUTHOR("Martin Johnson <>"); +MODULE_LICENSE("GPL"); + +/* Unimplemented stubs for Kaiser that live here for lack of a better home... */ + +void *smem_alloc(unsigned id, unsigned size) +{ + return 0; +} +static DEFINE_SPINLOCK(smem_lock); +uint32_t smsm_get_state(void) +{ + unsigned long flags; + struct smsm_shared *smsm; + uint32_t rv; + + spin_lock_irqsave(&smem_lock, flags); + + smsm = smem_alloc(ID_SHARED_STATE, + 2 * sizeof(struct smsm_shared)); + + if (smsm) + rv = smsm[1].state; + else + rv = 0; + + spin_unlock_irqrestore(&smem_lock, flags); + + if (smsm == NULL) + printk(KERN_ERR "smsm_get_state \n"); + return rv; +} + +enum { + MSM_SMD_DEBUG = 1U << 0, + MSM_SMSM_DEBUG = 1U << 0, +}; +static int msm_smd_debug_mask; +module_param_named(debug_mask, msm_smd_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +int smsm_set_interrupt_info(struct smsm_interrupt_info *info) +{ + struct smsm_interrupt_info *ptr; + + ptr = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*ptr)); + if (ptr == NULL) { + printk(KERN_ERR "smsm_set_sleep_duration \n"); + return -EIO; + } + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + printk(KERN_INFO "smsm_set_interrupt_info %x %x -> %x %x\n", + ptr->aArm_en_mask, ptr->aArm_interrupts_pending, + info->aArm_en_mask, info->aArm_interrupts_pending); + *ptr = *info; + return 0; +} \ No newline at end of file diff --git a/arch/arm/mach-msm/pm.c b/arch/arm/mach-msm/pm.c index 75f1704..e094b90 100644 --- a/arch/arm/mach-msm/pm.c +++ b/arch/arm/mach-msm/pm.c @@ -416,8 +416,8 @@ static uint32_t restart_reason = 0x776655AA; static void msm_pm_power_off(void) { - msm_proc_comm(PCOM_POWER_DOWN, 0, 0); - for (;;) ; +// msm_proc_comm(PCOM_POWER_DOWN, 0, 0); +// for (;;) ; } static void msm_pm_restart(char str) @@ -426,12 +426,14 @@ static void msm_pm_restart(char str) * is the default, prefer that to the (slower) proc_comm * reset command. */ +/* if ((restart_reason == 0x776655AA) && msm_reset_hook) { msm_reset_hook(str); } else { msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0); } for (;;) ; +*/ } static int msm_reboot_call(struct notifier_block *this, unsigned long code, void *_cmd) diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c index 724b6b3..4ad90d6 100644 --- a/arch/arm/mach-msm/smd_tty.c +++ b/arch/arm/mach-msm/smd_tty.c @@ -99,7 +99,8 @@ static int smd_tty_open(struct tty_struct *tty, struct file *f) if (info->ch) { smd_kick(info->ch); } else { - res = smd_open(name, &info->ch, info, smd_tty_notify); +// res = smd_open(name, &info->ch, info, smd_tty_notify); + res = smd_open(n, &info->ch, info, smd_tty_notify); } } mutex_unlock(&smd_tty_lock); @@ -200,6 +201,7 @@ static int __init smd_tty_init(void) /* this should be dynamic */ tty_register_device(smd_tty_driver, 0, 0); + tty_register_device(smd_tty_driver, 1, 0); tty_register_device(smd_tty_driver, 27, 0); return 0; diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 9e225da..c9a975c 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -194,7 +194,7 @@ static uint32_t msm_timer_sync_smem_clock(int exit_sleep) uint32_t last_state; uint32_t state; uint32_t new_offset; - +return 0; smem_clock = smem_alloc(SMEM_SMEM_SLOW_CLOCK_VALUE, sizeof(uint32_t)); @@ -283,7 +283,7 @@ int64_t msm_timer_enter_idle(void) uint32_t alarm; uint32_t count; int32_t delta; - +return 0; if (clock != &msm_clocks[MSM_CLOCK_GPT]) return 0; @@ -307,7 +307,7 @@ void msm_timer_exit_idle(int low_power) { struct msm_clock *clock = msm_active_clock; uint32_t smem_clock; - +return; if (!low_power || clock != &msm_clocks[MSM_CLOCK_GPT]) return; diff --git a/arch/arm/mach-msm/tsc2003.c b/arch/arm/mach-msm/tsc2003.c new file mode 100644 index 0000000..c1bf142 --- /dev/null +++ b/arch/arm/mach-msm/tsc2003.c @@ -0,0 +1,439 @@ +/* +kaiser Touch Screen Driver +Based on TSC2003 driver by Bill Gatliff + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "kaiser-ts" + +enum ts_pd { + PD_POWERDOWN = 0, /* penirq */ + PD_IREFOFF_ADCON = 1, /* no penirq */ + PD_IREFON_ADCOFF = 2, /* penirq */ + PD_IREFON_ADCON = 3, /* no penirq */ + PD_PENIRQ_ARM = PD_IREFON_ADCOFF, + PD_PENIRQ_DISARM = PD_IREFON_ADCON, +}; + +enum ts_m { + M_12BIT = 0, + M_8BIT = 1 +}; + +enum ts_cmd { + MEAS_TEMP0 = 0, + MEAS_VBAT1 = 1, + MEAS_IN1 = 2, + MEAS_TEMP1 = 4, + MEAS_VBAT2 = 5, + MEAS_IN2 = 6, + ACTIVATE_NX_DRIVERS = 8, + ACTIVATE_NY_DRIVERS = 9, + ACTIVATE_YNX_DRIVERS = 10, + MEAS_XPOS = 12, + MEAS_YPOS = 13, + MEAS_Z1POS = 14, + MEAS_Z2POS = 15 +}; + +#define TS_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1)) + +#define ADC_MAX ((1 << 12) - 1) + +#define MAX_X 240 +#define MAX_Y 320 + +int df_MIN_X=447; +int df_MAX_X=3807; + + +//we read Y from p1 is X < 50% +int df_MIN_Y1=864; //624 at 50% of X pos - diff ~240 +int df_MAX_Y1=2448;//2240 at 50% of X pos - diff ~220 + +//we read Y from y is X > 50% +int df_MIN_Y2=2850; +int df_MAX_Y2=3820; + +#define X_diff (df_MAX_X-df_MIN_X) +#define Y_diff ((df_MIN_Y2-df_MIN_Y1)+(df_MAX_Y2-df_MAX_Y1)) + + +struct ts_data { + struct i2c_client *client; + struct input_dev *idev; + struct timer_list penirq_timer; + struct semaphore sem; + struct task_struct *tstask; + struct completion tstask_completion; + enum ts_pd pd; + enum ts_m m; + int vbat1; + int vbat2; + int temp0; + int temp1; + int in1; + int in2; + int x; + int y; +}; + + +static inline int ts_command (struct ts_data *data, + enum ts_cmd cmd, + enum ts_pd pd) +{ + char c; + int ret; + down(&data->sem); + c = TS_CMD(cmd, pd, data->m); + ret = i2c_master_send(data->client, &c, 1); + up(&data->sem); + return ret; +} + +static int ts_read (struct ts_data *data, + enum ts_cmd cmd, + enum ts_pd pd, + int *val) +{ + char c; + char d[2]; + int ret; + + c = TS_CMD(cmd, pd, data->m); + ret = i2c_master_send(data->client, &c, 1); + + udelay(20); + ret = i2c_master_recv(data->client, d, data->m == M_12BIT ? 2 : 1); + + if (val) + { + *val = d[0]; + *val <<= 4; + if (data->m == M_12BIT) + *val += (d[1] >> 4); + } + +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_ALERT "%s: val[%x] = %d\n", + __FUNCTION__, cmd, (((int)d[0]) << 8) + d[1]); +#endif + + return 0; + if (!ret) ret = -ENODEV; + return ret; +} + +static inline int ts_read_temp0 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_TEMP0, pd, t); +} + +static inline int ts_read_temp1 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_TEMP1, pd, t); +} + +static inline int ts_read_xpos (struct ts_data *d, enum + ts_pd pd, int *x) +{ + return ts_read(d, MEAS_XPOS, pd, x); +} + +static inline int ts_read_ypos (struct ts_data *d, enum + ts_pd pd, int *y) +{ + return ts_read(d, MEAS_YPOS, pd, y); +} + +static inline int ts_read_pressure (struct ts_data *d, enum + ts_pd pd, int *p) +{ + return ts_read(d, MEAS_Z1POS, pd, p); +} + +static inline int ts_read_p2 (struct ts_data *d, enum ts_pd pd, int *p) +{ + return ts_read(d, MEAS_Z2POS, pd, p); +} +static inline int ts_read_in1 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_IN1, pd, t); +} + +static inline int ts_read_in2 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_IN2, pd, t); +} + +static inline int ts_read_vbat1 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_VBAT1, pd, t); +} + +static inline int ts_read_vbat2 (struct ts_data *d, enum + ts_pd pd, int *t) +{ + return ts_read(d, MEAS_VBAT2, pd, t); +} + +static inline int ts_powerdown (struct ts_data *d) +{ + /* we don't have a distinct powerdown command, + so do a benign read with the PD bits cleared */ + //char c=0xB2; + //return i2c_master_send(d->client, &c, 1); + return ts_read(d, 11, PD_POWERDOWN, 0); +} + +void ts_init_client (struct i2c_client *client) +{ + struct ts_data *data = i2c_get_clientdata(client); + + data->pd = PD_PENIRQ_DISARM; + data->m = M_8BIT; + return; +} + +static int tsts_thread (void *v) +{ + struct ts_data *d = v; + struct task_struct *tsk = current; + int pendown=0; + + d->tstask = tsk; + + daemonize(DRIVER_NAME "tsd"); + allow_signal(SIGKILL); + + complete(&d->tstask_completion); + + printk(KERN_INFO "%s: address 0x%x\n", + __FUNCTION__, d->client->addr); + + while (!signal_pending(tsk)) + { + unsigned int x, y, p, p1, p2; + int xc,yc,corr; + ts_read_xpos(d, PD_PENIRQ_DISARM, &x); + ts_read_ypos(d, PD_PENIRQ_DISARM, &y); + ts_read_pressure(d, PD_PENIRQ_DISARM, &p1); + ts_read_p2(d, PD_PENIRQ_DISARM, &p2); + x=ADC_MAX-x; + //y=y-2200; + //y=ADC_MAX-y; + p=((x/41)* (p2*100/p1 -100)); + + if (p > 100) { + xc = x; + xc = ((xc - df_MIN_X) * MAX_X)/(df_MAX_X-df_MIN_X); //X calibrated is ranges 0-320 + + yc = p1+xc*2; //strange but should works ;) + yc = ((yc - df_MIN_Y1) * MAX_Y)/(df_MAX_Y1-df_MIN_Y1); //X calibrated is ranges 0-320 + corr = (MAX_Y/2 - abs(MAX_Y/2 - yc))/4; + + if (d->x != xc || d->y != yc) + { + d->x = xc; + d->y = yc; +#ifdef CONFIG_INPUT_EVBUG + printk(KERN_ALERT "%d %d %d\n", xc, yc, corr); +#endif + pendown = 1; + input_report_abs(d->idev, ABS_X, xc); + input_report_abs(d->idev, ABS_Y, yc - corr); + input_report_abs(d->idev, ABS_PRESSURE, p); + input_report_key(d->idev, BTN_TOUCH, 1); + input_sync(d->idev); + } + } else if (pendown == 1) { + d->x = 0; + d->y = 0; + pendown = 0; + input_report_key(d->idev, BTN_TOUCH, 0); + input_report_abs(d->idev, ABS_PRESSURE, 0); + input_sync(d->idev); + } +#ifdef CONFIG_INPUT_EVBUG + schedule_timeout_interruptible(msecs_to_jiffies(100)); +#else + schedule_timeout_interruptible(msecs_to_jiffies(30)); +#endif + } + + d->tstask = NULL; + complete_and_exit(&d->tstask_completion, 0); +} + +static int ts_idev_open (struct input_dev *idev) +{ + struct ts_data *d = idev->private; + int ret = 0; + + if (down_interruptible(&d->sem)) + return -EINTR; + + if (d->tstask) + panic(DRIVER_NAME "tsd already running (!). abort."); + + init_completion(&d->tstask_completion); + + ret = kernel_thread(tsts_thread, d, CLONE_KERNEL); + if (ret >= 0) { + wait_for_completion(&d->tstask_completion); + ret = 0; + } + + up(&d->sem); + return ret; +} + +static void ts_idev_close (struct input_dev *idev) +{ + struct ts_data *d = idev->private; + down_interruptible(&d->sem); + if (d->tstask) + { + send_sig(SIGKILL, d->tstask, 1); + wait_for_completion(&d->tstask_completion); + } + up(&d->sem); + return; +} + +static int ts_driver_register (struct ts_data *data) +{ + int ret = 0; + + init_MUTEX(&data->sem); + + data->idev = input_allocate_device(); + if(!data->idev) + { + return -ENOMEM; + } + data->idev->private = data; + data->idev->name = DRIVER_NAME; + set_bit(EV_SYN, data->idev->evbit); + set_bit(EV_KEY, data->idev->evbit); + set_bit(BTN_TOUCH, data->idev->keybit); + set_bit(EV_ABS, data->idev->evbit); + + data->idev->open = ts_idev_open; + data->idev->close = ts_idev_close; + data->idev->absbit[ABS_X] = BIT(ABS_X); + data->idev->absbit[ABS_Y] = BIT(ABS_Y); + data->idev->absbit[ABS_PRESSURE] = BIT(ABS_PRESSURE); + input_set_abs_params(data->idev, ABS_X, 0, MAX_X, 4, 2); + input_set_abs_params(data->idev, ABS_Y, 0, MAX_Y, 4, 2); + input_set_abs_params(data->idev, ABS_PRESSURE, 0, 1, 4, 2); + + ret = input_register_device(data->idev); + if(ret) + { + input_free_device(data->idev); + return ret; + } + return ret; +} + +static int kaiser_ts_probe(struct i2c_client *client) +{ + int ret; + struct ts_data *data; + + printk(KERN_INFO "kaiser i2c touch screen\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + printk(KERN_ERR "kaiser_ts_probe: need I2C_FUNC_I2C\n"); + ret = -ENODEV; + goto err; + } + data = kcalloc(1, sizeof(*data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto err; + } + + data->client = client; + i2c_set_clientdata(client, data); + + ts_init_client(client); + + ts_powerdown(data); + + ret = ts_driver_register(data); + if(ret < 0) { + printk(KERN_ALERT "driver_register failed\n"); + goto err; + } + + return ret; + +err: + kfree(client); + return ret; +} + +#define kaiser_ts_suspend NULL +#define kaiser_ts_resume NULL + + +static int __devexit kaiser_ts_remove(struct i2c_client *client) +{ + printk(KERN_ALERT "raven goodbye!\n"); + struct ts_data *ts = i2c_get_clientdata(client); + input_unregister_device(ts->idev); + kfree(ts); + return 0; +} + +static struct i2c_driver kaiser_ts_driver = { + .probe = kaiser_ts_probe, + .remove = kaiser_ts_remove, + .suspend = kaiser_ts_suspend, + .resume = kaiser_ts_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __devinit kaiser_ts_init(void) +{ + printk("kaiser ts_init\n"); + return i2c_add_driver(&kaiser_ts_driver); +} + +static void __exit kaiser_ts_exit(void) +{ + i2c_del_driver(&kaiser_ts_driver); +} + +MODULE_AUTHOR("Martin Johnson <>"); +MODULE_DESCRIPTION("kaiser Touch Screen"); +MODULE_LICENSE("GPL"); + +module_init(kaiser_ts_init); +module_exit(kaiser_ts_exit); diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index 89f579a..36e2046 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c @@ -82,20 +82,20 @@ int vreg_enable(struct vreg *vreg) { unsigned id = vreg->id; unsigned enable = 1; - return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); +/* return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);*/ } void vreg_disable(struct vreg *vreg) { unsigned id = vreg->id; unsigned enable = 0; - msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); +/* msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);*/ } int vreg_set_level(struct vreg *vreg, unsigned mv) { unsigned id = vreg->id; - return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); +/* return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);*/ } #if defined(CONFIG_DEBUG_FS) diff --git a/block/blk-core.c b/block/blk-core.c index 2a438a9..4b35824 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1537,9 +1537,9 @@ static int __end_that_request_first(struct request *req, int error, req->errors = 0; if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) { - printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n", - req->rq_disk ? req->rq_disk->disk_name : "?", - (unsigned long long)req->sector); + //printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n", + // req->rq_disk ? req->rq_disk->disk_name : "?", + //(unsigned long long)req->sector); } if (blk_fs_request(req) && req->rq_disk) { diff --git a/drivers/i2c/busses/i2c-msm.c b/drivers/i2c/busses/i2c-msm.c index 0921f55..881e5ea 100644 --- a/drivers/i2c/busses/i2c-msm.c +++ b/drivers/i2c/busses/i2c-msm.c @@ -13,8 +13,6 @@ * */ -#include -#include #include #include #include @@ -31,12 +29,19 @@ #define DEBUG 0 enum { +#ifndef CONFIG_MSM7X00 I2C_WRITE_DATA = 0x00, I2C_CLK_CTL = 0x04, I2C_STATUS = 0x08, I2C_READ_DATA = 0x0c, I2C_INTERFACE_SELECT = 0x10, - +#else + I2C_WRITE_DATA = 0x100, + I2C_CLK_CTL = 0x104, + I2C_STATUS = 0x108, + I2C_READ_DATA = 0x10c, + I2C_INTERFACE_SELECT = 0x110, +#endif I2C_WRITE_DATA_DATA_BYTE = 0xff, I2C_WRITE_DATA_ADDR_BYTE = 1U << 8, I2C_WRITE_DATA_LAST_BYTE = 1U << 9, @@ -64,7 +69,6 @@ struct msm_i2c_dev { struct device *dev; void __iomem *base; /* virtual */ int irq; - struct clk *clk; struct i2c_adapter adapter; spinlock_t lock; @@ -340,10 +344,15 @@ msm_i2c_probe(struct platform_device *pdev) int i2c_clk; int clk_ctl; int target_clk; - struct clk *clk; printk(KERN_INFO "msm_i2c_probe\n"); +#ifndef CONFIG_MSM7X00 + /* FIXME: this needs to use the clock api once it is supported */ + writel((1U << 11) | (1U << 9), MSM_CLK_CTL_BASE + 0x68); + mdelay(10); +#endif + /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -362,12 +371,6 @@ msm_i2c_probe(struct platform_device *pdev) dev_err(&pdev->dev, "I2C region already claimed\n"); return -EBUSY; } - clk = clk_get(&pdev->dev, "i2c_clk"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Could not get clock\n"); - ret = PTR_ERR(clk); - goto err_clk_get_failed; - } dev = kzalloc(sizeof(struct msm_i2c_dev), GFP_KERNEL); if (!dev) { @@ -377,12 +380,12 @@ msm_i2c_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->irq = irq->start; - dev->clk = clk; +// dev->clk = clk; dev->base = (void __iomem *)(size_t)mem->start; spin_lock_init(&dev->lock); platform_set_drvdata(pdev, dev); - clk_enable(clk); +// clk_enable(clk); /* I2C_HS_CLK = I2C_CLK/(3*(HS_DIVIDER_VALUE+1) */ /* I2C_FS_CLK = I2C_CLK/(2*(FS_DIVIDER_VALUE+3) */ @@ -393,6 +396,9 @@ msm_i2c_probe(struct platform_device *pdev) fs_div = ((i2c_clk / target_clk) / 2) - 3; hs_div = 3; clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff); +#ifdef CONFIG_MSM7X00 + clk_ctl=0x715; // from wince +#endif writel(clk_ctl, dev->base + I2C_CLK_CTL); printk(KERN_INFO "msm_i2c_probe: clk_ctl %x, %d Hz\n", clk_ctl, i2c_clk / (2 * ((clk_ctl & 0xff) + 3))); @@ -422,11 +428,8 @@ msm_i2c_probe(struct platform_device *pdev) err_request_irq_failed: i2c_del_adapter(&dev->adapter); err_i2c_add_adapter_failed: - clk_disable(clk); kfree(dev); err_alloc_dev_failed: - clk_put(clk); -err_clk_get_failed: release_mem_region(mem->start, (mem->end - mem->start) + 1); return ret; } @@ -440,35 +443,15 @@ msm_i2c_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); free_irq(dev->irq, dev); i2c_del_adapter(&dev->adapter); - clk_disable(dev->clk); - clk_put(dev->clk); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, (mem->end - mem->start) + 1); return 0; } -static int msm_i2c_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct msm_i2c_dev *dev = platform_get_drvdata(pdev); - if (dev) - clk_disable(dev->clk); - return 0; -} - -static int msm_i2c_resume(struct platform_device *pdev) -{ - struct msm_i2c_dev *dev = platform_get_drvdata(pdev); - if (dev) - clk_enable(dev->clk); - return 0; -} - static struct platform_driver msm_i2c_driver = { .probe = msm_i2c_probe, .remove = msm_i2c_remove, - .suspend = msm_i2c_suspend, - .resume = msm_i2c_resume, .driver = { .name = "msm_i2c", .owner = THIS_MODULE, diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 0c886c8..c66e164 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -22,6 +22,22 @@ config MFD_ASIC3 This driver supports the ASIC3 multifunction chip found on many PDAs (mainly iPAQ and HTC based ones) +config HTC_EGPIO + bool "HTC EGPIO support" + depends on GENERIC_HARDIRQS + help + This driver supports the CPLD egpio chip present on + several HTC phones. It provides basic support for input + pins, output pins, and irqs. + +config HTC_PASIC3 + tristate "HTC PASIC3 LED/DS1WM chip support" + help + This core driver provides register access for the LED/DS1WM + chips labeled "AIC2" and "AIC3", found on HTC Blueangel and + HTC Magician devices, respectively. Actual functionality is + handled by the leds-pasic3 and ds1wm drivers. + endmenu menu "Multimedia Capabilities Port drivers" @@ -44,5 +60,27 @@ config MCP_UCB1200 config MCP_UCB1200_TS tristate "Touchscreen interface support" depends on MCP_UCB1200 && INPUT +config MFD_ASIC3 + bool "Support for Compaq ASIC3" + depends on GENERIC_HARDIRQS && ARM + ---help--- + This driver supports the ASIC3 multifunction chip found on many + PDAs (mainly iPAQ and HTC based ones) + +config HTC_EGPIO + bool "HTC EGPIO support" + depends on GENERIC_HARDIRQS + help + This driver supports the CPLD egpio chip present on + several HTC phones. It provides basic support for input + pins, output pins, and irqs. + +config HTC_PASIC3 + tristate "HTC PASIC3 LED/DS1WM chip support" + help + This core driver provides register access for the LED/DS1WM + chips labeled "AIC2" and "AIC3", found on HTC Blueangel and + HTC Magician devices, respectively. Actual functionality is + handled by the leds-pasic3 and ds1wm drivers. endmenu diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 521cd5c..794ae8a 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -3,8 +3,7 @@ # obj-$(CONFIG_MFD_SM501) += sm501.o -obj-$(CONFIG_MFD_ASIC3) += asic3.o - +obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o obj-$(CONFIG_MCP) += mcp-core.o obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c new file mode 100644 index 0000000..ce6ed71 --- /dev/null +++ b/drivers/mfd/htc-egpio.c @@ -0,0 +1,357 @@ +/* + * Support for the EGPIO chip present on several HTC phones. This + * is believed to be related to the CPLD chip present on the board. + * + * (c) Copyright 2007 Kevin O'Connor + * + * This file may be distributed under the terms of the GNU GPL license. + */ + +#include +#include /* ENODEV */ +#include /* enable_irq_wake */ +#include /* spinlock_t */ +#include /* platform_device */ +#include +#include +#include + +#include /* IRQT_RISING */ +#include /* ioremap_nocache */ +#include /* struct irq_chip */ + +struct egpio_info { + spinlock_t lock; + u16 *addrBase; + int bus_shift; + + /* irq info */ + int ackRegister; + int ackWrite; + u16 irqsEnabled; + uint irqStart; + uint chainedirq; + + /* output info */ + int maxRegs; + u16 cached_values[MAX_EGPIO_REGS]; +}; + + +/**************************************************************** + * Irqs + ****************************************************************/ + +static inline void ackirqs(struct egpio_info *ei) +{ + writew(ei->ackWrite, &ei->addrBase[ei->ackRegister << ei->bus_shift]); + /* printk("EGPIO ack\n"); */ +} + +/* There does not appear to be a way to proactively mask interrupts + * on the egpio chip itself. So, we simply ignore interrupts that + * aren't desired. */ +static void egpio_mask(unsigned int irq) +{ + struct egpio_info *ei = get_irq_chip_data(irq); + ei->irqsEnabled &= ~(1 << (irq - ei->irqStart)); + /* printk("EGPIO mask %d %04x\n", irq, ei->irqsEnabled); */ +} +static void egpio_unmask(unsigned int irq) +{ + struct egpio_info *ei = get_irq_chip_data(irq); + ei->irqsEnabled |= 1 << (irq - ei->irqStart); + /* printk("EGPIO unmask %d %04x\n", irq, ei->irqsEnabled); */ +} + +static struct irq_chip egpio_muxed_chip = { + .name = "htc-egpio", + .mask = egpio_mask, + .unmask = egpio_unmask, +}; + +static void egpio_handler(unsigned int irq, struct irq_desc *desc) +{ + struct egpio_info *ei = get_irq_data(irq); + int irqpin; + + /* Read current pins. */ + u16 readval = readw(&ei->addrBase[ei->ackRegister << ei->bus_shift]); + /* Ack/unmask interrupts. */ + ackirqs(ei); + /* Process all set pins. */ + for (irqpin=0; irqpinirqsEnabled & (1<irqStart + irqpin; + desc = &irq_desc[irq]; + desc->handle_irq(irq, desc); + } +} + +int htc_egpio_get_wakeup_irq(struct device *dev) +{ + struct egpio_info *ei = dev_get_drvdata(dev); + int irqpin; + + /* Read current pins. */ + u16 readval = readw(&ei->addrBase[ei->ackRegister << ei->bus_shift]); + /* Ack/unmask interrupts. */ + ackirqs(ei); + /* Process all set pins. */ + for (irqpin=0; irqpinirqsEnabled & (1<irqStart + irqpin; + } + return 0; +} +EXPORT_SYMBOL(htc_egpio_get_wakeup_irq); + + +/**************************************************************** + * Input pins + ****************************************************************/ + +static inline int u16pos(int bit) { + return bit/16; +} +static inline int u16bit(int bit) { + return 1<<(bit & (16-1)); +} + +/* Check an input pin to see if it is active. */ +static int egpio_get(struct device *dev, unsigned gpio) +{ + unsigned bit = gpio & GPIO_BASE_MASK; + struct egpio_info *ei = dev_get_drvdata(dev); + u16 readval = readw(&ei->addrBase[u16pos(bit) << ei->bus_shift]); + return readval & u16bit(bit); +} + +static int egpio_to_irq(struct device *dev, unsigned gpio_no) +{ + struct egpio_info *ei = dev_get_drvdata(dev); + struct htc_egpio_platform_data *pdata = dev->platform_data; + int i; + for (i=0; inr_pins; i++) { + struct htc_egpio_pinInfo *pi = &pdata->pins[i]; + if (pi->type == HTC_EGPIO_TYPE_INPUT + && pi->gpio == gpio_no + && pi->input_irq >= 0) + return (pi->input_irq & 0xf) + ei->irqStart; + } + return -ENODEV; +} + + +/**************************************************************** + * Output pins + ****************************************************************/ + +static void egpio_set(struct device *dev, unsigned gpio, int val) +{ + unsigned bit = gpio & GPIO_BASE_MASK; + struct egpio_info *ei = dev_get_drvdata(dev); + int pos = u16pos(bit); + unsigned long flag; + + spin_lock_irqsave(&ei->lock, flag); + if (val) { + ei->cached_values[pos] |= u16bit(bit); + //printk("egpio set: reg %d = 0x%04x\n", pos, ei->cached_values[pos]); + } else { + ei->cached_values[pos] &= ~u16bit(bit); + //printk("egpio clear: reg %d = 0x%04x\n", pos, ei->cached_values[pos]); + } + writew(ei->cached_values[pos], &ei->addrBase[pos << ei->bus_shift]); + spin_unlock_irqrestore(&ei->lock, flag); +} + + +/**************************************************************** + * Setup + ****************************************************************/ + +static void setup_pin(struct egpio_info *ei, struct htc_egpio_pinInfo *pi) +{ + int pin = pi->gpio & GPIO_BASE_MASK; + + if (pi->gpio < 0 || pin > 16*MAX_EGPIO_REGS) { + printk(KERN_ERR "EGPIO invalid pin %d\n", pi->gpio); + return; + } + + switch (pi->type) { + case HTC_EGPIO_TYPE_INPUT: + if (pi->input_irq < 0) + break; + pin = pi->input_irq & GPIO_BASE_MASK; + if (ei->ackRegister != u16pos(pin)) { + printk(KERN_ERR "EGPIO irq conflict %d vs %d\n" + , ei->ackRegister, u16pos(pin)); + return; + } + break; + case HTC_EGPIO_TYPE_OUTPUT: + if (ei->maxRegs < u16pos(pin)) + ei->maxRegs = u16pos(pin); + if (pi->output_initial) + ei->cached_values[u16pos(pin)] |= u16bit(pin); + break; + default: + printk(KERN_ERR "EGPIO unknown type %d\n", pi->type); + } +} + +static int egpio_probe(struct platform_device *pdev) +{ + struct htc_egpio_platform_data *pdata = pdev->dev.platform_data; + struct resource *res; + struct egpio_info *ei; + int irq, i, ret; + struct gpio_ops ops; + + /* Initialize ei data structure. */ + ei = kzalloc(sizeof(*ei), GFP_KERNEL); + if (!ei) + return -ENOMEM; + + spin_lock_init(&ei->lock); + + /* Find chained irq */ + ret = -EINVAL; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res) + ei->chainedirq = res->start; + + /* Map egpio chip into virtual address space. */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + goto fail; + ei->addrBase = (u16 *)ioremap_nocache(res->start, res->end - res->start); + if (!ei->addrBase) + goto fail; + printk(KERN_NOTICE "EGPIO phys=0x%08X virt=%p\n", res->start, (unsigned int)ei->addrBase); + ei->bus_shift = pdata->bus_shift; + + platform_set_drvdata(pdev, ei); + + ops.get_value = egpio_get; + ops.set_value = egpio_set; + ops.to_irq = egpio_to_irq; + gpiodev_register(pdata->gpio_base, &pdev->dev, &ops); + + /* Go through list of pins. */ + ei->irqStart = pdata->irq_base; + ei->maxRegs = pdata->nrRegs - 1; + ei->ackRegister = pdata->ackRegister; + for (i = 0; i < pdata->nr_pins; i++) + setup_pin(ei, &pdata->pins[i]); + + if (ei->chainedirq) { + /* Setup irq handlers */ + ei->ackWrite = 0xFFFF; + if (pdata->invertAcks) + ei->ackWrite = 0; + for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { + set_irq_chip(irq, &egpio_muxed_chip); + set_irq_chip_data(irq, ei); + set_irq_handler(irq, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + set_irq_type(ei->chainedirq, IRQT_RISING); + set_irq_data(ei->chainedirq, ei); + set_irq_chained_handler(ei->chainedirq, egpio_handler); + ackirqs(ei); + + device_init_wakeup(&pdev->dev, 1); + } + + /* Setup initial output pin values. */ + for (i = 0; i<=ei->maxRegs; i++) + if (i != ei->ackRegister) + writew(ei->cached_values[i], &ei->addrBase[i << ei->bus_shift]); + + return 0; + +fail: + printk(KERN_NOTICE "EGPIO failed to setup\n"); + kfree(ei); + return ret; +} + +static int egpio_remove(struct platform_device *pdev) +{ + struct egpio_info *ei = platform_get_drvdata(pdev); + unsigned int irq; + if (ei->chainedirq) { + for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { + set_irq_chip(irq, NULL); + set_irq_handler(irq, NULL); + set_irq_flags(irq, 0); + } + set_irq_chained_handler(ei->chainedirq, NULL); + device_init_wakeup(&pdev->dev, 0); + } + iounmap(ei->addrBase); + kfree(ei); + + return 0; +} + +#ifdef CONFIG_PM +static int egpio_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct egpio_info *ei = platform_get_drvdata(pdev); + + if (ei->chainedirq && device_may_wakeup(&pdev->dev)) + enable_irq_wake(ei->chainedirq); + return 0; +} + +static int egpio_resume(struct platform_device *pdev) +{ + struct egpio_info *ei = platform_get_drvdata(pdev); + + if (ei->chainedirq && device_may_wakeup(&pdev->dev)) + disable_irq_wake(ei->chainedirq); + return 0; +} +#else +#define egpio_suspend NULL +#define egpio_resume NULL +#endif + + +static struct platform_driver egpio_driver = { + .driver = { + .name = "htc-egpio", + }, + .probe = egpio_probe, + .remove = egpio_remove, + .suspend = egpio_suspend, + .resume = egpio_resume, +}; + +static int __init egpio_init(void) +{ + return platform_driver_register(&egpio_driver); +} + +static void __exit egpio_exit(void) +{ + platform_driver_unregister(&egpio_driver); +} + +#ifdef MODULE +module_init(egpio_init); +#else /* start early for dependencies */ +subsys_initcall(egpio_init); +#endif +module_exit(egpio_exit) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kevin O'Connor "); diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 0e88e82..f48c165 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -650,7 +650,7 @@ static int __init mmc_blk_init(void) { int res = -ENOMEM; - mmcblk_dbg_logenable = 1; + mmcblk_dbg_logenable = 0; res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); if (res) diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 482d8f4..a4e88a0 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -58,1506 +58,1555 @@ static void msmsdcc_dbg_createhost(struct msmsdcc_host *); static struct dentry *debugfs_dir; #endif -static unsigned int msmsdcc_fmin = 144000; -static unsigned int msmsdcc_fmax = 25000000; +static unsigned int msmsdcc_fmin = 100000; +static unsigned int msmsdcc_fmax = 32000000; static unsigned int msmsdcc_4bit = 1; static unsigned int msmsdcc_pwrsave = 0; static char *msmsdcc_clks[] = { NULL, "sdc1_clk", "sdc2_clk", "sdc3_clk", - "sdc4_clk" }; -static char *msmsdcc_pclks[] = { NULL, "sdc1_pclk", "sdc2_pclk", "sdc3_pclk", - "sdc4_pclk" }; + "sdc4_clk" }; + static char *msmsdcc_pclks[] = { NULL, "sdc1_pclk", "sdc2_pclk", "sdc3_pclk", + "sdc4_pclk" }; #define VERBOSE_COMMAND_TIMEOUTS 0 #define MAX_DATAEND_WAIT_ITER 10000 #define MSMSDCC_POLLING_RETRIES 10000 -static void -msmsdcc_start_command(struct msmsdcc_host *host, - struct mmc_command *cmd, u32 c); + static void + msmsdcc_start_command(struct msmsdcc_host *host, + struct mmc_command *cmd, u32 c); -static void -msmsdcc_dump_fifodata(struct msmsdcc_host *host) -{ - uint32_t reg_datacnt = readl(host->base + MMCIDATACNT); - uint32_t reg_fifocnt = readl(host->base + MMCIFIFOCNT); - uint32_t reg_status = readl(host->base + MMCISTATUS); + static void + msmsdcc_dump_fifodata(struct msmsdcc_host *host) + { + uint32_t reg_datacnt = readl(host->base + MMCIDATACNT); + uint32_t reg_fifocnt = readl(host->base + MMCIFIFOCNT); + uint32_t reg_status = readl(host->base + MMCISTATUS); - printk(KERN_DEBUG "%s: DATACNT = %d, FIFOCNT = %d, STATUS = 0x%.8x\n", - mmc_hostname(host->mmc), reg_datacnt, reg_fifocnt, reg_status); -} - -static void -msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) -{ - writel(0, host->base + MMCICOMMAND); + printk(KERN_DEBUG "%s: DATACNT = %d, FIFOCNT = %d, STATUS = 0x%.8x\n", + mmc_hostname(host->mmc), reg_datacnt, reg_fifocnt, reg_status); + } - BUG_ON(host->data); + static void + msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) + { + writel(0, host->base + MMCICOMMAND); - host->mrq = NULL; - host->cmd = NULL; + BUG_ON(host->data); +//printk("request end\n"); + host->mrq = NULL; + host->cmd = NULL; #if 0 - if (mrq->data && mrq->data->error) - mrq->cmd->error = mrq->data->error; + if (mrq->data && mrq->data->error) + mrq->cmd->error = mrq->data->error; #endif - if (mrq->data) - mrq->data->bytes_xfered = host->data_xfered; - if (mrq->cmd->error == -ETIMEDOUT) { - mdelay(5); - } + if (mrq->data) + mrq->data->bytes_xfered = host->data_xfered; + if (mrq->cmd->error == -ETIMEDOUT) { + mdelay(5); + } /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); - mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); -} - -static void -msmsdcc_stop_data(struct msmsdcc_host *host) -{ - writel(0, host->base + MMCIDATACTRL); - host->data = NULL; -} - -uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) -{ - if (host->pdev_id == 1) - return MSM_SDC1_PHYS + MMCIFIFO; - else if (host->pdev_id == 2) - return MSM_SDC2_PHYS + MMCIFIFO; - else if (host->pdev_id == 3) - return MSM_SDC3_PHYS + MMCIFIFO; - else if (host->pdev_id == 4) - return MSM_SDC4_PHYS + MMCIFIFO; - else - BUG(); -} - -static int -msmsdcc_wait_for_dataend(struct msmsdcc_host *host, unsigned int retries) -{ - uint32_t reg_status; - - while(retries) { - reg_status = readl(host->base + MMCISTATUS); - if ((reg_status & (MCI_DATAEND | MCI_DATABLOCKEND)) == - (MCI_DATAEND | MCI_DATABLOCKEND)) - break; - retries--; - } - if (!retries) - return -ETIMEDOUT; - return 0; -} - -static void -msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, - unsigned int result, - struct msm_dmov_errdata *err) -{ - struct msmsdcc_dma_data *dma_data = - container_of(cmd, struct msmsdcc_dma_data, hdr); - struct msmsdcc_host *host = dma_data->host; - unsigned long flags; - uint32_t reg_datacnt, reg_status; - struct mmc_request *mrq; - int rc = 0; - - spin_lock_irqsave(&host->lock, flags); - - mrq = host->mrq; - BUG_ON(!mrq); - - if (!(result & DMOV_RSLT_VALID)) - printk(KERN_ERR "%s: DM result not valid\n", - mmc_hostname(host->mmc)); - else if (!(result & DMOV_RSLT_DONE)) { + * Need to drop the host lock here; mmc_request_done may call + * back into the driver... + */ + spin_unlock(&host->lock); + mmc_request_done(host->mmc, mrq); + spin_lock(&host->lock); + } + + static void + msmsdcc_stop_data(struct msmsdcc_host *host) + { + writel(0, host->base + MMCIDATACTRL); + host->data = NULL; + } + + uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) + { + if (host->pdev_id == 1) + return MSM_SDC1_PHYS + MMCIFIFO; + else if (host->pdev_id == 2) + return MSM_SDC2_PHYS + MMCIFIFO; +/* else if (host->pdev_id == 3) + return MSM_SDC3_PHYS + MMCIFIFO; + else if (host->pdev_id == 4) + return MSM_SDC4_PHYS + MMCIFIFO;*/ + else + BUG(); + } + + static int + msmsdcc_wait_for_dataend(struct msmsdcc_host *host, unsigned int retries) + { + uint32_t reg_status; + + while(retries) { + //printk("waiting for dataend\n"); + reg_status = readl(host->base + MMCISTATUS); + if ((reg_status & (MCI_DATAEND | MCI_DATABLOCKEND)) == + (MCI_DATAEND | MCI_DATABLOCKEND)) + break; + retries--; + } + if (!retries) + return -ETIMEDOUT; + return 0; + } + + static void + msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, + unsigned int result, + struct msm_dmov_errdata *err) + { + struct msmsdcc_dma_data *dma_data = + container_of(cmd, struct msmsdcc_dma_data, hdr); + struct msmsdcc_host *host = dma_data->host; + unsigned long flags; + uint32_t reg_datacnt, reg_status; + struct mmc_request *mrq; + int rc = 0; + + spin_lock_irqsave(&host->lock, flags); + + mrq = host->mrq; + BUG_ON(!mrq); + + if (!(result & DMOV_RSLT_VALID)) + printk(KERN_ERR "%s: DM result not valid\n", + mmc_hostname(host->mmc)); + else if (!(result & DMOV_RSLT_DONE)) { /* - * Either an error or a flush occurred - */ - if (result & DMOV_RSLT_ERROR) - printk(KERN_ERR "%s: DMA error (0x%.8x)\n", - mmc_hostname(host->mmc), result); - if (result & DMOV_RSLT_FLUSH) - printk(KERN_ERR "%s: DMA channel flushed (0x%.8x)\n", - mmc_hostname(host->mmc), result); - msmsdcc_dump_fifodata(host); - if (err) - printk(KERN_ERR - "Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", - err->flush[0], err->flush[1], err->flush[2], - err->flush[3], err->flush[4], err->flush[5]); - if (!mrq->data->error) - mrq->data->error = -EIO; - } - - reg_status = readl(host->base + MMCISTATUS); - - if ((result & DMOV_RSLT_DONE) - && (reg_status & (MCI_DATAEND | MCI_DATABLOCKEND)) - !=(MCI_DATAEND | MCI_DATABLOCKEND)) { + * Either an error or a flush occurred + */ + if (result & DMOV_RSLT_ERROR) + printk(KERN_ERR "%s: DMA error (0x%.8x)\n", + mmc_hostname(host->mmc), result); + if (result & DMOV_RSLT_FLUSH) + printk(KERN_ERR "%s: DMA channel flushed (0x%.8x)\n", + mmc_hostname(host->mmc), result); + msmsdcc_dump_fifodata(host); + if (err) + printk(KERN_ERR + "Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", + err->flush[0], err->flush[1], err->flush[2], + err->flush[3], err->flush[4], err->flush[5]); + if (!mrq->data->error) + mrq->data->error = -EIO; + } + + reg_status = readl(host->base + MMCISTATUS); + + if ((result & DMOV_RSLT_DONE) + && (reg_status & (MCI_DATAEND | MCI_DATABLOCKEND)) + !=(MCI_DATAEND | MCI_DATABLOCKEND)) { #if 0 - printk(KERN_WARNING - "%s: DMA result 0x%.8x but still waiting for DATAEND (0x%.8x)\n", - mmc_hostname(host->mmc), result, reg_status); + printk(KERN_WARNING + "%s: DMA result 0x%.8x but still waiting for DATAEND (0x%.8x)\n", + mmc_hostname(host->mmc), result, reg_status); #endif - if (result & DMOV_RSLT_VALID) { - rc = msmsdcc_wait_for_dataend(host, - MAX_DATAEND_WAIT_ITER); - if (rc) { - printk(KERN_ERR - "%s: Timed out waiting for DATAEND\n", - mmc_hostname(host->mmc)); - mrq->data->error = -ETIMEDOUT; - } - } - } + if (result & DMOV_RSLT_VALID) { + rc = msmsdcc_wait_for_dataend(host, + MAX_DATAEND_WAIT_ITER); + if (rc) { + printk(KERN_ERR + "%s: Timed out waiting for DATAEND\n", + mmc_hostname(host->mmc)); + mrq->data->error = -ETIMEDOUT; + } + } + } - writel(MCI_DATAEND | MCI_DATABLOCKEND, host->base + MMCICLEAR); + writel(MCI_DATAEND | MCI_DATABLOCKEND, host->base + MMCICLEAR); - msmsdcc_stop_data(host); + msmsdcc_stop_data(host); /* - * According to QCT it is only ok to read datacnt - * after the transfer is complete (or otherwise stopped) - */ - reg_datacnt = readl(host->base + MMCIDATACNT); + * According to QCT it is only ok to read datacnt + * after the transfer is complete (or otherwise stopped) + */ + reg_datacnt = readl(host->base + MMCIDATACNT); /* - * If we timed out on DMA then output some debugging - */ - if (rc) { - printk(KERN_DEBUG "%s: DC %d, BS %d, B %d, OP %d\n", - mmc_hostname(host->mmc), reg_datacnt, mrq->data->blksz, - mrq->data->blocks, mrq->cmd->opcode); - } - - dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, - host->dma.dir); - - if (host->dma.user_pages) { - struct scatterlist *sg = host->dma.sg; - int i; - - for (i = 0; i < host->dma.num_ents; i++, sg++) - flush_dcache_page(sg_page(sg)); - } - - if (!mrq->data->error) { - host->data_xfered = host->xfer_size - reg_datacnt; - - if (host->data_xfered != host->xfer_size) { - printk(KERN_WARNING - "%s: Short xfer (%d != %d), dc %d, flags 0x%x\n", - mmc_hostname(host->mmc), host->data_xfered, - host->xfer_size, reg_datacnt, mrq->data->flags); - } - } - host->dma.sg = NULL; - - /* Don't send STOP if we're a read but got a command error */ - if (!mrq->data->stop || mrq->cmd->error) { - writel(0, host->base + MMCICOMMAND); - - host->mrq = NULL; - host->cmd = NULL; + * If we timed out on DMA then output some debugging + */ + if (rc) { + printk(KERN_DEBUG "%s: DC %d, BS %d, B %d, OP %d\n", + mmc_hostname(host->mmc), reg_datacnt, mrq->data->blksz, + mrq->data->blocks, mrq->cmd->opcode); + } + + dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, + host->dma.dir); + + if (host->dma.user_pages) { + struct scatterlist *sg = host->dma.sg; + int i; + + for (i = 0; i < host->dma.num_ents; i++, sg++) + flush_dcache_page(sg_page(sg)); + } + + if (!mrq->data->error) { + host->data_xfered = host->xfer_size - reg_datacnt; + + if (host->data_xfered != host->xfer_size) { + printk(KERN_WARNING + "%s: Short xfer (%d != %d), dc %d, flags 0x%x\n", + mmc_hostname(host->mmc), host->data_xfered, + host->xfer_size, reg_datacnt, mrq->data->flags); + } + } + host->dma.sg = NULL; + + /* Don't send STOP if we're a read but got a command error */ + if (!mrq->data->stop || mrq->cmd->error) { + writel(0, host->base + MMCICOMMAND); + + host->mrq = NULL; + host->cmd = NULL; #if 0 - if (mrq->data && mrq->data->error) - mrq->cmd->error = mrq->data->error; + if (mrq->data && mrq->data->error) + mrq->cmd->error = mrq->data->error; #endif - mrq->data->bytes_xfered = host->data_xfered; + mrq->data->bytes_xfered = host->data_xfered; #if 0 - if (mrq->cmd->error == -ETIMEDOUT) - mdelay(5); + if (mrq->cmd->error == -ETIMEDOUT) + mdelay(5); #endif - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(host->mmc, mrq); - return; - } else - msmsdcc_start_command(host, mrq->data->stop, 0); + spin_unlock_irqrestore(&host->lock, flags); + mmc_request_done(host->mmc, mrq); + return; + } else + msmsdcc_start_command(host, mrq->data->stop, 0); - spin_unlock_irqrestore(&host->lock, flags); - return; -} - -static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) -{ - if (host->dma.channel == -1) - return -ENOENT; - if ((data->blksz * data->blocks) < 32) - return -EINVAL; - if ((data->blksz * data->blocks) % 32) - return -EINVAL; - return 0; -} - -static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) -{ - struct msmsdcc_nc_dmadata *nc; - dmov_box *box; - uint32_t rows; - uint32_t crci; - unsigned int n; - int i, rc; - struct scatterlist *sg = data->sg; + spin_unlock_irqrestore(&host->lock, flags); + return; + } + + static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) + { + //printk("validate dma\n"); + if (host->dma.channel == -1) + return -ENOENT; + if ((data->blksz * data->blocks) < 32) + { + printk("<32\n"); + return -EINVAL; + } + if ((data->blksz * data->blocks) % 32) + { + printk("%%32\n"); + return -EINVAL; + } + return 0; + } + + static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) + { + struct msmsdcc_nc_dmadata *nc; + dmov_box *box; + uint32_t rows; + uint32_t crci; + unsigned int n; + int i, rc; + struct scatterlist *sg = data->sg; - rc = validate_dma(host, data); - if (rc) - return rc; - - host->dma.sg = data->sg; - host->dma.num_ents = data->sg_len; - - nc = host->dma.nc; - - if (host->pdev_id == 1) - crci = MSMSDCC_CRCI_SDC1; - else if (host->pdev_id == 2) - crci = MSMSDCC_CRCI_SDC2; - else if (host->pdev_id == 3) - crci = MSMSDCC_CRCI_SDC3; - else if (host->pdev_id == 4) - crci = MSMSDCC_CRCI_SDC4; - else { - host->dma.sg = NULL; - host->dma.num_ents = 0; - return -ENOENT; - } - - if (data->flags & MMC_DATA_READ) - host->dma.dir = DMA_FROM_DEVICE; - else - host->dma.dir = DMA_TO_DEVICE; - - host->dma.user_pages = (data->flags & MMC_DATA_USERPAGE); - - n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg, - host->dma.num_ents, host->dma.dir); - - if (n != host->dma.num_ents) { - printk(KERN_ERR "%s: Unable to map in all sg elements\n", - mmc_hostname(host->mmc)); - host->dma.sg = NULL; - host->dma.num_ents = 0; - return -ENOMEM; - } - - box = &nc->cmd[0]; - for (i = 0; i < host->dma.num_ents; i++) { - box->cmd = CMD_MODE_BOX; - - if (i == (host->dma.num_ents - 1)) - box->cmd |= CMD_LC; - rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? - (sg_dma_len(sg) / MCI_FIFOSIZE) + 1: - (sg_dma_len(sg) / MCI_FIFOSIZE) ; + rc = validate_dma(host, data); + if (rc) + return rc; + + host->dma.sg = data->sg; + host->dma.num_ents = data->sg_len; + + nc = host->dma.nc; + + if (host->pdev_id == 1) + crci = MSMSDCC_CRCI_SDC1; + else if (host->pdev_id == 2) + crci = MSMSDCC_CRCI_SDC2; + else if (host->pdev_id == 3) + crci = MSMSDCC_CRCI_SDC3; + else if (host->pdev_id == 4) + crci = MSMSDCC_CRCI_SDC4; + else { + host->dma.sg = NULL; + host->dma.num_ents = 0; + return -ENOENT; + } + + if (data->flags & MMC_DATA_READ) + host->dma.dir = DMA_FROM_DEVICE; + else + host->dma.dir = DMA_TO_DEVICE; + + host->dma.user_pages = (data->flags & MMC_DATA_USERPAGE); + + n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg, + host->dma.num_ents, host->dma.dir); + + if (n != host->dma.num_ents) { + printk(KERN_ERR "%s: Unable to map in all sg elements\n", + mmc_hostname(host->mmc)); + host->dma.sg = NULL; + host->dma.num_ents = 0; + return -ENOMEM; + } - if (data->flags & MMC_DATA_READ) { - box->src_row_addr = msmsdcc_fifo_addr(host); - box->dst_row_addr = sg_dma_address(sg); + box = &nc->cmd[0]; + for (i = 0; i < host->dma.num_ents; i++) { + box->cmd = CMD_MODE_BOX; - box->src_dst_len = (MCI_FIFOSIZE << 16) | (MCI_FIFOSIZE); - box->row_offset = MCI_FIFOSIZE; + if (i == (host->dma.num_ents - 1)) + box->cmd |= CMD_LC; + rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? + (sg_dma_len(sg) / MCI_FIFOSIZE) + 1: + (sg_dma_len(sg) / MCI_FIFOSIZE) ; + + if (data->flags & MMC_DATA_READ) { + box->src_row_addr = msmsdcc_fifo_addr(host); + box->dst_row_addr = sg_dma_address(sg); +// printk("rd_dmovboxfifo %x\n",box->src_row_addr); +// printk("rd_dmovboxdma %x\n",box->dst_row_addr); + box->src_dst_len = (MCI_FIFOSIZE << 16) | (MCI_FIFOSIZE); + box->row_offset = MCI_FIFOSIZE; + + box->num_rows = rows * ((1 << 16) + 1); + box->cmd |= CMD_SRC_CRCI(crci); + } else { + box->src_row_addr = sg_dma_address(sg); + box->dst_row_addr = msmsdcc_fifo_addr(host); +// printk("wr_dmovboxfifo %x\n",box->dst_row_addr); +// printk("wr_dmovboxdma %x\n",box->src_row_addr); + + box->src_dst_len = (MCI_FIFOSIZE << 16) | (MCI_FIFOSIZE); + box->row_offset = (MCI_FIFOSIZE << 16); + + box->num_rows = rows * ((1 << 16) + 1); + box->cmd |= CMD_DST_CRCI(crci); + } + box++; + sg++; + } - box->num_rows = rows * ((1 << 16) + 1); - box->cmd |= CMD_SRC_CRCI(crci); - } else { - box->src_row_addr = sg_dma_address(sg); - box->dst_row_addr = msmsdcc_fifo_addr(host); + /* location of command block must be 64 bit aligned */ + BUG_ON(host->dma.cmd_busaddr & 0x07); - box->src_dst_len = (MCI_FIFOSIZE << 16) | (MCI_FIFOSIZE); - box->row_offset = (MCI_FIFOSIZE << 16); + nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP; + host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | + DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); +// printk("dmovcmdaddr %x\n",host->dma.hdr.cmdptr); + host->dma.hdr.complete_func = msmsdcc_dma_complete_func; - box->num_rows = rows * ((1 << 16) + 1); - box->cmd |= CMD_DST_CRCI(crci); + return 0; } - box++; - sg++; - } - - /* location of command block must be 64 bit aligned */ - BUG_ON(host->dma.cmd_busaddr & 0x07); - - nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP; - host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | - DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); - host->dma.hdr.complete_func = msmsdcc_dma_complete_func; - - return 0; -} - -static void -msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) -{ - unsigned int datactrl, timeout; - unsigned long long clks; - void __iomem *base = host->base; - - host->data = data; - host->xfer_size = data->blksz * data->blocks; - host->xfer_remain = host->xfer_size; - host->data_xfered = 0; - - clks = (unsigned long long)data->timeout_ns * host->clk_rate; - do_div(clks, 1000000000UL); - timeout = data->timeout_clks + (unsigned int)clks; - writel(timeout, base + MMCIDATATIMER); - - writel(host->xfer_size, base + MMCIDATALENGTH); - - datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); - - if (!msmsdcc_config_dma(host, data)) - datactrl |= MCI_DPSM_DMAENABLE; - - if (data->flags & MMC_DATA_READ) - datactrl |= MCI_DPSM_DIRECTION; - - writel(datactrl, base + MMCIDATACTRL); - - if (datactrl & MCI_DPSM_DMAENABLE) - msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); -} - -static void -msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) -{ - void __iomem *base = host->base; - - DBG(host, "op %02x arg %08x flags %08x\n", - cmd->opcode, cmd->arg, cmd->flags); - - if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { - writel(0, base + MMCICOMMAND); - udelay(2 + ((5 * 1000000) / host->clk_rate)); - } - - c |= cmd->opcode | MCI_CPSM_ENABLE; - - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) - c |= MCI_CPSM_LONGRSP; - c |= MCI_CPSM_RESPONSE; - } - - if (/*interrupt*/0) - c |= MCI_CPSM_INTERRUPT; - - if ((((cmd->opcode == 17) || (cmd->opcode == 18)) || - ((cmd->opcode == 24) || (cmd->opcode == 25))) || - (cmd->opcode == 53)) - c |= MCI_CSPM_DATCMD; - - if (cmd == cmd->mrq->stop) - c |= MCI_CSPM_MCIABORT; - - host->cmd = cmd; - - writel(cmd->arg, base + MMCIARGUMENT); - writel(c, base + MMCICOMMAND); -} - -static void -msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data, - unsigned int status) -{ - if (status & MCI_DATACRCFAIL) { - printk(KERN_ERR "%s: Data CRC error\n", mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: opcode 0x%.8x\n", __func__, data->mrq->cmd->opcode); - printk(KERN_ERR "%s: blksz %d, blocks %d\n", __func__, data->blksz, data->blocks); - data->error = -EILSEQ; - } else if (status & MCI_DATATIMEOUT) { - printk(KERN_ERR "%s: Data timeout\n", mmc_hostname(host->mmc)); - data->error = -ETIMEDOUT; - } else if (status & MCI_RXOVERRUN) { - printk(KERN_ERR "%s: RX overrun\n", mmc_hostname(host->mmc)); - data->error = -EIO; - } else if (status & MCI_TXUNDERRUN) { - printk(KERN_ERR "%s: TX underrun\n", mmc_hostname(host->mmc)); - data->error = -EIO; - } else { - printk(KERN_ERR "%s: Unknown error (0x%.8x)\n", - mmc_hostname(host->mmc), status); - data->error = -EIO; - } -} -/* - * IRQ Handler for processing DMA request related errors and - * command completion. - */ -static irqreturn_t -msmsdcc_irq(int irq, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; - void __iomem *base = host->base; - u32 status; - int ret = 0; + static void + msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) + { + unsigned int datactrl, timeout; + unsigned long long clks; + void __iomem *base = host->base; - spin_lock(&host->lock); + host->data = data; + host->xfer_size = data->blksz * data->blocks; + host->xfer_remain = host->xfer_size; + host->data_xfered = 0; + //printk("dma start %x\n", host->xfer_size); + clks = (unsigned long long)data->timeout_ns * host->clk_rate; + do_div(clks, 1000000000UL); + timeout = data->timeout_clks + (unsigned int)clks; + writel(timeout, base + MMCIDATATIMER); - do { - struct mmc_command *cmd; - struct mmc_data *data; - status = readl(host->base + MMCISTATUS); + writel(host->xfer_size, base + MMCIDATALENGTH); - DBG(host, "irq0 %08x\n", status); + datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); - status &= readl(host->base + MMCIMASK0); - writel(status, host->base + MMCICLEAR); + if (!msmsdcc_config_dma(host, data)) + datactrl |= MCI_DPSM_DMAENABLE; - /* - * Check for data errors - */ - data = host->data; - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| - MCI_RXOVERRUN) && data) { - msmsdcc_data_err(host, data, status); - msm_dmov_stop_cmd(host->dma.channel, &host->dma.hdr, 0); + if (data->flags & MMC_DATA_READ) + datactrl |= MCI_DPSM_DIRECTION; + + writel(datactrl, base + MMCIDATACTRL); + + if (datactrl & MCI_DPSM_DMAENABLE) + msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); } + static void + msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) + { + void __iomem *base = host->base; - /* - * Check for proper command response - */ - cmd = host->cmd; - if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | - MCI_CMDTIMEOUT) && cmd) { - host->cmd = NULL; - cmd->resp[0] = readl(base + MMCIRESPONSE0); - cmd->resp[1] = readl(base + MMCIRESPONSE1); - cmd->resp[2] = readl(base + MMCIRESPONSE2); - cmd->resp[3] = readl(base + MMCIRESPONSE3); + DBG(host, "op %02x arg %08x flags %08x\n", + cmd->opcode, cmd->arg, cmd->flags); - del_timer(&host->command_timer); - if (status & MCI_CMDTIMEOUT) { -#if VERBOSE_COMMAND_TIMEOUTS - printk(KERN_ERR "%s: Command timeout\n", - mmc_hostname(host->mmc)); -#endif - cmd->error = -ETIMEDOUT; - } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { - printk(KERN_ERR "%s: Command CRC error\n", - mmc_hostname(host->mmc)); - cmd->error = -EILSEQ; + if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { + writel(0, base + MMCICOMMAND); + udelay(2 + ((5 * 1000000) / host->clk_rate)); } - if (!cmd->data || cmd->error) { - if (host->data && host->dma.sg) - msm_dmov_stop_cmd(host->dma.channel, - &host->dma.hdr, 0); - else if (host->data) { /* Non DMA transfer */ - msmsdcc_stop_data(host); - msmsdcc_request_end(host, cmd->mrq); - } else /* host->data == NULL */ - msmsdcc_request_end(host, cmd->mrq); - } else if (!(cmd->data->flags & MMC_DATA_READ)) - msmsdcc_start_data(host, cmd->data); - } + c |= cmd->opcode | MCI_CPSM_ENABLE; - ret = 1; - } while (status); + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) + c |= MCI_CPSM_LONGRSP; + c |= MCI_CPSM_RESPONSE; + } - spin_unlock(&host->lock); + if (/*interrupt*/0) + c |= MCI_CPSM_INTERRUPT; - return IRQ_RETVAL(ret); -} + if ((((cmd->opcode == 17) || (cmd->opcode == 18)) || + ((cmd->opcode == 24) || (cmd->opcode == 25))) || + (cmd->opcode == 53)) + c |= MCI_CSPM_DATCMD; + if (cmd == cmd->mrq->stop) + c |= MCI_CSPM_MCIABORT; -static int -msmsdcc_waitfor_cmd(struct msmsdcc_host *host, struct mmc_command *cmd, - uint32_t *status) -{ - unsigned int retries = MSMSDCC_POLLING_RETRIES; + host->cmd = cmd; - while(retries) { - *status = readl(host->base + MMCISTATUS); + writel(cmd->arg, base + MMCIARGUMENT); + writel(c, base + MMCICOMMAND); + } - if (*status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) - return -EILSEQ; - if (*status & MCI_CMDTIMEOUT) - return -ETIMEDOUT; - if (*status & (MCI_CMDSENT | MCI_CMDRESPEND)) - return 0; - retries--; - } + static void + msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data, + unsigned int status) + { + if (status & MCI_DATACRCFAIL) { + printk(KERN_ERR "%s: Data CRC error\n", mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: opcode 0x%.8x\n", __func__, data->mrq->cmd->opcode); + printk(KERN_ERR "%s: blksz %d, blocks %d\n", __func__, data->blksz, data->blocks); + data->error = -EILSEQ; + } else if (status & MCI_DATATIMEOUT) { + printk(KERN_ERR "%s: Data timeout\n", mmc_hostname(host->mmc)); + data->error = -ETIMEDOUT; + } else if (status & MCI_RXOVERRUN) { + printk(KERN_ERR "%s: RX overrun\n", mmc_hostname(host->mmc)); + data->error = -EIO; + } else if (status & MCI_TXUNDERRUN) { + printk(KERN_ERR "%s: TX underrun\n", mmc_hostname(host->mmc)); + data->error = -EIO; + } else { + printk(KERN_ERR "%s: Unknown error (0x%.8x)\n", + mmc_hostname(host->mmc), status); + data->error = -EIO; + } + } -#if MSMSDCC_POLLING_DEBUG - printk("%s: Timed out waiting for command status\n", __func__); +/* + * IRQ Handler for processing DMA request related errors and + * command completion. + */ + static irqreturn_t + msmsdcc_irq(int irq, void *dev_id) + { + struct msmsdcc_host *host = dev_id; + void __iomem *base = host->base; + u32 status; + int ret = 0; + int i; + + spin_lock(&host->lock); +// if (!host->cmd) + udelay(5); + + + //printk("irq %d %x %x\n", irq, //0, 0); + // readl(MSM_VIC_BASE),readl(MSM_VIC_BASE+0x10)); +// if(host->data) +// { +// printk("rising\n"); +// spin_unlock(&host->lock); +// return IRQ_RETVAL(1); +// } + +// while((readl(MSM_VIC_BASE+0x10)&(1<<22))==0) { +// printk("rising\n"); +// spin_unlock(&host->lock); +// return IRQ_RETVAL(1); +// } + +// status = readl(host->base + MMCISTATUS); + + i = 1; + do { + struct mmc_command *cmd; + struct mmc_data *data; +// if (i==1){ +// i = 0; +// } +// else +// { + status = readl(host->base + MMCISTATUS); +// } + + DBG(host, "irq0 %08x\n", status); + //printk("irq0 %08x\n", status); + + status &= readl(host->base + MMCIMASK0); + writel(status, host->base + MMCICLEAR); + + /* + * Check for data errors + */ + data = host->data; + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| + MCI_RXOVERRUN) && data) { + msmsdcc_data_err(host, data, status); + msm_dmov_stop_cmd(host->dma.channel, &host->dma.hdr, 0); + } + + + /* + * Check for proper command response + */ + cmd = host->cmd; + if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | + MCI_CMDTIMEOUT) && cmd) { + host->cmd = NULL; + cmd->resp[0] = readl(base + MMCIRESPONSE0); + cmd->resp[1] = readl(base + MMCIRESPONSE1); + cmd->resp[2] = readl(base + MMCIRESPONSE2); + cmd->resp[3] = readl(base + MMCIRESPONSE3); + + del_timer(&host->command_timer); + if (status & MCI_CMDTIMEOUT) { +#if VERBOSE_COMMAND_TIMEOUTS + printk(KERN_ERR "%s: Command timeout\n", + mmc_hostname(host->mmc)); #endif - return -ETIMEDOUT; -} - -static int -msmsdcc_polling_rx(struct msmsdcc_host *host, struct mmc_data *data) -{ - void __iomem *base = host->base; - uint32_t timeout = 0; - uint32_t brtr = data->blksz * data->blocks; - struct scatterlist *sg = data->sg; - unsigned int sg_len = data->sg_len; - unsigned int sg_off = 0; - unsigned int count = 0; - uint32_t status; + cmd->error = -ETIMEDOUT; + } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { + printk(KERN_ERR "%s: Command CRC error\n", + mmc_hostname(host->mmc)); + cmd->error = -EILSEQ; + } + + if (!cmd->data || cmd->error) { + if (host->data && host->dma.sg) + msm_dmov_stop_cmd(host->dma.channel, + &host->dma.hdr, 0); + else if (host->data) { /* Non DMA transfer */ + msmsdcc_stop_data(host); + msmsdcc_request_end(host, cmd->mrq); + } else /* host->data == NULL */ + msmsdcc_request_end(host, cmd->mrq); + } else if (!(cmd->data->flags & MMC_DATA_READ)) + msmsdcc_start_data(host, cmd->data); + } + + ret = 1; + } while (status); + + spin_unlock(&host->lock); + + return IRQ_RETVAL(ret); + } - writel(0x18007ff, host->base + MMCICLEAR); - while(brtr) { - unsigned int sg_remain; - unsigned long flags; - char *buffer; - uint32_t *ptr; - - local_irq_save(flags); - buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; - ptr = (uint32_t *) buffer; - - sg_remain = sg->length - sg_off; - - while(sg_remain) { - - /* Wait for FIFO data */ - status = readl(base + MMCISTATUS); - - if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | - MCI_TXUNDERRUN)) { - if (status & MCI_DATACRCFAIL) - data->error = -EILSEQ; - else if (status & MCI_DATATIMEOUT) - data->error = -ETIMEDOUT; - else - data->error = -EIO; - printk(KERN_ERR "%s: Data error (%d)\n", - mmc_hostname(host->mmc), data->error); + static int + msmsdcc_waitfor_cmd(struct msmsdcc_host *host, struct mmc_command *cmd, + uint32_t *status) + { + unsigned int retries = MSMSDCC_POLLING_RETRIES; - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); - goto out; - } - - if (status & MCI_RXDATAAVLBL) { - *ptr = readl(base + MMCIFIFO + (count % MCI_FIFOSIZE)); - ptr++; - count += sizeof(uint32_t); - sg_off += sizeof(uint32_t); - sg_remain -= sizeof(uint32_t); - brtr -= sizeof(uint32_t); - data->bytes_xfered += sizeof(uint32_t); - timeout = 0; - - writel(0x18007ff, host->base + MMCICLEAR); - continue; + while(retries) { + *status = readl(host->base + MMCISTATUS); + + if (*status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) + return -EILSEQ; + if (*status & MCI_CMDTIMEOUT) + return -ETIMEDOUT; + if (*status & (MCI_CMDSENT | MCI_CMDRESPEND)) + return 0; + retries--; } - if (timeout++ > MSMSDCC_POLLING_RETRIES) { - uint32_t datacnt, fifocnt; - uint32_t dbg[2]; +#if MSMSDCC_POLLING_DEBUG + printk("%s: Timed out waiting for command status\n", __func__); +#endif + return -ETIMEDOUT; + } - datacnt = readl(base + MMCIDATACNT); - fifocnt = readl(base + MMCIFIFOCNT); - status = readl(base + MMCISTATUS); + static int + msmsdcc_polling_rx(struct msmsdcc_host *host, struct mmc_data *data) + { + void __iomem *base = host->base; + uint32_t timeout = 0; + uint32_t brtr = data->blksz * data->blocks; + struct scatterlist *sg = data->sg; + unsigned int sg_len = data->sg_len; + unsigned int sg_off = 0; + unsigned int count = 0; + uint32_t status; + + + writel(0x18007ff, host->base + MMCICLEAR); + while(brtr) { + unsigned int sg_remain; + unsigned long flags; + char *buffer; + uint32_t *ptr; + + local_irq_save(flags); + buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; + ptr = (uint32_t *) buffer; + + sg_remain = sg->length - sg_off; + + while(sg_remain) { + + /* Wait for FIFO data */ + status = readl(base + MMCISTATUS); + + if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | + MCI_TXUNDERRUN)) { + if (status & MCI_DATACRCFAIL) + data->error = -EILSEQ; + else if (status & MCI_DATATIMEOUT) + data->error = -ETIMEDOUT; + else + data->error = -EIO; + printk(KERN_ERR "%s: Data error (%d)\n", + mmc_hostname(host->mmc), data->error); + + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + goto out; + } + + if (status & MCI_RXDATAAVLBL) { + *ptr = readl(base + MMCIFIFO + (count % MCI_FIFOSIZE)); + ptr++; + count += sizeof(uint32_t); + sg_off += sizeof(uint32_t); + sg_remain -= sizeof(uint32_t); + brtr -= sizeof(uint32_t); + data->bytes_xfered += sizeof(uint32_t); + timeout = 0; + + writel(0x18007ff, host->base + MMCICLEAR); + continue; + } + + if (timeout++ > MSMSDCC_POLLING_RETRIES) { + uint32_t datacnt, fifocnt; + uint32_t dbg[2]; + + datacnt = readl(base + MMCIDATACNT); + fifocnt = readl(base + MMCIFIFOCNT); + status = readl(base + MMCISTATUS); - printk(KERN_ERR "%s: Timed out waiting for RXDATAAVLBL (st = 0x%.8x)\n", - mmc_hostname(host->mmc), status); - printk(KERN_ERR "%s: 0x%.8x 0x%.8x 0x%.8x\n", - mmc_hostname(host->mmc), datacnt, - fifocnt, status); - dbg[0] = readl(base + MMCIFIFO); - dbg[1] = readl(base + MMCIFIFO + 4); - printk(KERN_ERR "%s: Data = 0x%.8x 0x%.8x\n", - mmc_hostname(host->mmc), dbg[0], dbg[1]); - printk(KERN_ERR "%s: opcode 0x%.8x\n", __func__, data->mrq->cmd->opcode); - - data->error = -ETIMEDOUT; + printk(KERN_ERR "%s: Timed out waiting for RXDATAAVLBL (st = 0x%.8x)\n", + mmc_hostname(host->mmc), status); + printk(KERN_ERR "%s: 0x%.8x 0x%.8x 0x%.8x\n", + mmc_hostname(host->mmc), datacnt, + fifocnt, status); + dbg[0] = readl(base + MMCIFIFO); + dbg[1] = readl(base + MMCIFIFO + 4); + printk(KERN_ERR "%s: Data = 0x%.8x 0x%.8x\n", + mmc_hostname(host->mmc), dbg[0], dbg[1]); + printk(KERN_ERR "%s: opcode 0x%.8x\n", __func__, data->mrq->cmd->opcode); + + data->error = -ETIMEDOUT; + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + goto out; + } + } + + /* Done with this SG element */ kunmap_atomic(buffer, KM_BIO_SRC_IRQ); local_irq_restore(flags); - goto out; - } - } - /* Done with this SG element */ - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); - - if (--sg_len) { - /* Advance to next SG element */ - sg++; - sg_off = 0; - } - } + if (--sg_len) { + /* Advance to next SG element */ + sg++; + sg_off = 0; + } + } #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG "%s: Rx complete (%d bytes xfered)\n", - mmc_hostname(host->mmc), data->bytes_xfered); + printk(KERN_DEBUG "%s: Rx complete (%d bytes xfered)\n", + mmc_hostname(host->mmc), data->bytes_xfered); #endif out: - writel(0x18007ff, host->base + MMCICLEAR); + writel(0x18007ff, host->base + MMCICLEAR); return data->error; -} - -static int -msmsdcc_polling_tx(struct msmsdcc_host *host, struct mmc_data *data) -{ - void __iomem *base = host->base; - uint32_t timeout = 0; - uint32_t brtw = data->blksz * data->blocks; - struct scatterlist *sg = data->sg; - unsigned int sg_len = data->sg_len; - unsigned int sg_off = 0; - uint32_t status; + } + + static int + msmsdcc_polling_tx(struct msmsdcc_host *host, struct mmc_data *data) + { + void __iomem *base = host->base; + uint32_t timeout = 0; + uint32_t brtw = data->blksz * data->blocks; + struct scatterlist *sg = data->sg; + unsigned int sg_len = data->sg_len; + unsigned int sg_off = 0; + uint32_t status; #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG "%s: TX blksz %d, blocks %d\n", - mmc_hostname(host->mmc), data->blksz, data->blocks); + printk(KERN_DEBUG "%s: TX blksz %d, blocks %d\n", + mmc_hostname(host->mmc), data->blksz, data->blocks); #endif - writel(0x18007ff, host->base + MMCICLEAR); + writel(0x18007ff, host->base + MMCICLEAR); - while(brtw) { - unsigned int sg_remain, count; - unsigned long flags; - char *buffer, *ptr; + while(brtw) { + unsigned int sg_remain, count; + unsigned long flags; + char *buffer, *ptr; - local_irq_save(flags); - buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; - ptr = buffer; + local_irq_save(flags); + buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; + ptr = buffer; - sg_remain = sg->length - sg_off; + sg_remain = sg->length - sg_off; #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG "%s: SG buffer @ %p (remain = %d)\n", - mmc_hostname(host->mmc), buffer, sg_remain); + printk(KERN_DEBUG "%s: SG buffer @ %p (remain = %d)\n", + mmc_hostname(host->mmc), buffer, sg_remain); #endif - while(sg_remain) { - unsigned int maxcnt; - - /* Wait for the FIFO to be ready */ - status = readl(base + MMCISTATUS); - - if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | - MCI_TXUNDERRUN)) { - if (status & MCI_DATACRCFAIL) - data->error = -EILSEQ; - else if (status & MCI_DATATIMEOUT) - data->error = -ETIMEDOUT; - else - data->error = -EIO; - printk(KERN_ERR "%s: Data error (%d)\n", - mmc_hostname(host->mmc), data->error); - writel(0x18007ff, host->base + MMCICLEAR); - - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); - goto out; - } + while(sg_remain) { + unsigned int maxcnt; + + /* Wait for the FIFO to be ready */ + status = readl(base + MMCISTATUS); + + if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | + MCI_TXUNDERRUN)) { + if (status & MCI_DATACRCFAIL) + data->error = -EILSEQ; + else if (status & MCI_DATATIMEOUT) + data->error = -ETIMEDOUT; + else + data->error = -EIO; + printk(KERN_ERR "%s: Data error (%d)\n", + mmc_hostname(host->mmc), data->error); + writel(0x18007ff, host->base + MMCICLEAR); + + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + goto out; + } - /* Write (up to) a full fifo length */ - if (status & MCI_TXFIFOEMPTY) { - maxcnt = (status & MCI_TXFIFOEMPTY ? - MCI_FIFOSIZE : MCI_FIFOHALFSIZE); - count = min(sg_remain, maxcnt); + /* Write (up to) a full fifo length */ + if (status & MCI_TXFIFOEMPTY) { + maxcnt = (status & MCI_TXFIFOEMPTY ? + MCI_FIFOSIZE : MCI_FIFOHALFSIZE); + count = min(sg_remain, maxcnt); #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG "%s: Wr %d bytes to FIFO \n", - mmc_hostname(host->mmc), count); + printk(KERN_DEBUG "%s: Wr %d bytes to FIFO \n", + mmc_hostname(host->mmc), count); #endif - writesl(base + MMCIFIFO, ptr, count >> 2); + writesl(base + MMCIFIFO, ptr, count >> 2); + + ptr += count; + sg_off += count; + sg_remain -= count; + brtw -= count; + + timeout = 0; + continue; + } + + if (timeout++ > MSMSDCC_POLLING_RETRIES) { + printk(KERN_ERR + "%s: Timed out waiting for TXFIFOEMPTY (0x%.8x)\n", + mmc_hostname(host->mmc), status); + data->error = -ETIMEDOUT; + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + goto out; + } + } + + /* Done with this SG element */ + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(flags); - ptr += count; - sg_off += count; - sg_remain -= count; - brtw -= count; + if (--sg_len) { + /* Advance to next SG element */ + sg++; + sg_off = 0; + } + } - timeout = 0; - continue; + /* + * Wait for data xmit to complete + */ + timeout = MSMSDCC_POLLING_RETRIES; + while(timeout) { + status = readl(base + MMCISTATUS); + if (status & MCI_DATAEND) + break; + timeout--; } + if (!timeout) { + uint32_t reg_datacnt, reg_fifocnt; + reg_datacnt = readl(host->base + MMCIDATACNT); + reg_fifocnt = readl(host->base + MMCIFIFOCNT); + + printk(KERN_ERR "%s: Timed out waiting for DATAEND on Tx (0x%.8x, %d, %d)\n", + mmc_hostname(host->mmc), status, reg_datacnt, reg_fifocnt); - if (timeout++ > MSMSDCC_POLLING_RETRIES) { - printk(KERN_ERR - "%s: Timed out waiting for TXFIFOEMPTY (0x%.8x)\n", - mmc_hostname(host->mmc), status); data->error = -ETIMEDOUT; - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); goto out; } - } - - /* Done with this SG element */ - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); - - if (--sg_len) { - /* Advance to next SG element */ - sg++; - sg_off = 0; - } - } - - /* - * Wait for data xmit to complete - */ - timeout = MSMSDCC_POLLING_RETRIES; - while(timeout) { - status = readl(base + MMCISTATUS); - if (status & MCI_DATAEND) - break; - timeout--; - } - if (!timeout) { - uint32_t reg_datacnt, reg_fifocnt; - reg_datacnt = readl(host->base + MMCIDATACNT); - reg_fifocnt = readl(host->base + MMCIFIFOCNT); - - printk(KERN_ERR "%s: Timed out waiting for DATAEND on Tx (0x%.8x, %d, %d)\n", - mmc_hostname(host->mmc), status, reg_datacnt, reg_fifocnt); - - data->error = -ETIMEDOUT; - goto out; - } - data->bytes_xfered = data->blksz * data->blocks; + data->bytes_xfered = data->blksz * data->blocks; #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG "%s: Tx complete (%d bytes xfered)\n", - mmc_hostname(host->mmc), data->bytes_xfered); + printk(KERN_DEBUG "%s: Tx complete (%d bytes xfered)\n", + mmc_hostname(host->mmc), data->bytes_xfered); #endif out: - writel(0x18007ff, host->base + MMCICLEAR); + writel(0x18007ff, host->base + MMCICLEAR); return data->error; -} - -static void -msmsdcc_do_polling_request(struct msmsdcc_host *host, struct mmc_request *mrq) -{ - struct mmc_command *cmd = mrq->cmd; - struct mmc_data *data = mrq->data; - uint32_t status; - int rc; - - writel(0x018007FF, host->base + MMCICLEAR); + } - msmsdcc_start_command(host, cmd, 0); - rc = msmsdcc_waitfor_cmd(host, cmd, &status); + static void + msmsdcc_do_polling_request(struct msmsdcc_host *host, struct mmc_request *mrq) + { + struct mmc_command *cmd = mrq->cmd; + struct mmc_data *data = mrq->data; + uint32_t status; + int rc; + +// writel(0x018007FF, host->base + MMCICLEAR); +// while(readl(host->base + MMCISTATUS) & 0x018007FF) + writel(0x018007FF, host->base + MMCICLEAR); + printk("polling\n"); + + msmsdcc_start_command(host, cmd, 0); + rc = msmsdcc_waitfor_cmd(host, cmd, &status); #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG - "%s: Polling waitforcmd rc = %d (status 0x%.8x)\n", - mmc_hostname(host->mmc), rc, status); + printk(KERN_DEBUG + "%s: Polling waitforcmd rc = %d (status 0x%.8x)\n", + mmc_hostname(host->mmc), rc, status); #endif - host->cmd = NULL; - cmd->resp[0] = readl(host->base + MMCIRESPONSE0); - cmd->resp[1] = readl(host->base + MMCIRESPONSE1); - cmd->resp[2] = readl(host->base + MMCIRESPONSE2); - cmd->resp[3] = readl(host->base + MMCIRESPONSE3); - - if (rc) { - printk(KERN_ERR "%s: Command error (%d)\n", - mmc_hostname(host->mmc), rc); - cmd->error = rc; - goto done; - } - - if (data) { - if (!(mrq->data->flags & MMC_DATA_READ)) { - msmsdcc_start_data(host, data); - msmsdcc_polling_tx(host, data); - } else - msmsdcc_polling_rx(host, data); - msmsdcc_stop_data(host); - } + host->cmd = NULL; + cmd->resp[0] = readl(host->base + MMCIRESPONSE0); + cmd->resp[1] = readl(host->base + MMCIRESPONSE1); + cmd->resp[2] = readl(host->base + MMCIRESPONSE2); + cmd->resp[3] = readl(host->base + MMCIRESPONSE3); + + if (rc) { + printk(KERN_ERR "%s: Command error (%d)\n", + mmc_hostname(host->mmc), rc); + cmd->error = rc; + goto done; + } + + if (data) { + if (!(mrq->data->flags & MMC_DATA_READ)) { + msmsdcc_start_data(host, data); + msmsdcc_polling_tx(host, data); + } else + msmsdcc_polling_rx(host, data); + msmsdcc_stop_data(host); + } done: #if MSMSDCC_POLLING_DEBUG - printk(KERN_DEBUG - "%s: Done request (cmd_err = %d, dat_err = %d, stop_err = %d)\n", - mmc_hostname(host->mmc), cmd->error, - (mrq->data != NULL ? mrq->data->error : -1), - (mrq->stop != NULL ? mrq->stop->error : -1)); + printk(KERN_DEBUG + "%s: Done request (cmd_err = %d, dat_err = %d, stop_err = %d)\n", + mmc_hostname(host->mmc), cmd->error, + (mrq->data != NULL ? mrq->data->error : -1), + (mrq->stop != NULL ? mrq->stop->error : -1)); #endif writel(0x18007ff, host->base + MMCICLEAR); spin_unlock_irq(&host->lock); mmc_request_done(host->mmc, host->mrq); return; -} + } -static void -msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct msmsdcc_host *host = mmc_priv(mmc); - int poll = 0; + static void + msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) + { + struct msmsdcc_host *host = mmc_priv(mmc); + int poll = 0; - WARN_ON(host->mrq != NULL); + WARN_ON(host->mrq != NULL); - spin_lock_irq(&host->lock); + spin_lock_irq(&host->lock); - if (host->eject) { - if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) { - mrq->cmd->error = 0; - mrq->data->bytes_xfered = mrq->data->blksz * mrq->data->blocks; - } else - mrq->cmd->error = -ENOMEDIUM; + if (host->eject) { + if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) { + mrq->cmd->error = 0; + mrq->data->bytes_xfered = mrq->data->blksz * mrq->data->blocks; + } else + mrq->cmd->error = -ENOMEDIUM; - spin_unlock_irq(&host->lock); - mmc_request_done(mmc, mrq); - return; - } + spin_unlock_irq(&host->lock); + mmc_request_done(mmc, mrq); + return; + } - host->mrq = mrq; + host->mrq = mrq; /* - * According to QCT PIO interrupts may be broken, - * so if we're not going to use DMA, fall back to - * polling - */ - if (mrq->data && validate_dma(host, mrq->data)) { - - writel(0, host->base + MMCIMASK0); - poll = 1; + * According to QCT PIO interrupts may be broken, + * so if we're not going to use DMA, fall back to + * polling + */ + if (mrq->data && validate_dma(host, mrq->data)) { + + writel(0, host->base + MMCIMASK0); + poll = 1; - } else - writel(MCI_IRQENABLE, host->base + MMCIMASK0); - - if (mrq->data && mrq->data->flags & MMC_DATA_READ) - msmsdcc_start_data(host, mrq->data); - - if (poll) { - msmsdcc_do_polling_request(host, mrq); - host->mrq = NULL; - } else { - msmsdcc_start_command(host, mrq->cmd, 0); - mod_timer(&host->command_timer, jiffies + (HZ / 2)); - spin_unlock_irq(&host->lock); - } - -} - -static void -msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct msmsdcc_host *host = mmc_priv(mmc); - u32 clk = 0, pwr = 0; - int rc; - - if (ios->clock) { - - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; + } else + writel(MCI_IRQENABLE, host->base + MMCIMASK0); + + if (mrq->data && mrq->data->flags & MMC_DATA_READ) + msmsdcc_start_data(host, mrq->data); + + if (poll) { + printk("\nPolling\n"); + msmsdcc_do_polling_request(host, mrq); + host->mrq = NULL; + } else { + msmsdcc_start_command(host, mrq->cmd, 0); + mod_timer(&host->command_timer, jiffies + (HZ / 2)); + spin_unlock_irq(&host->lock); + } + } - if (ios->clock != host->clk_rate) { - rc = clk_set_rate(host->clk, ios->clock); - if (rc < 0) - printk(KERN_ERR - "Error setting clock rate (%d)\n", rc); - else - host->clk_rate = ios->clock; + + static void + msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct msmsdcc_host *host = mmc_priv(mmc); + u32 clk = 0, pwr = 0; + int rc; + + if (ios->clock) { + + if (!host->clks_on) { + clk_enable(host->pclk); + clk_enable(host->clk); + host->clks_on = 1; + } + if (ios->clock != host->clk_rate) { + rc = clk_set_rate(host->clk, ios->clock); + if (rc < 0) + printk(KERN_ERR + "Error setting clock rate (%d)\n", rc); + else + host->clk_rate = ios->clock; + } + clk |= MCI_CLK_ENABLE; + } + + if (ios->bus_width == MMC_BUS_WIDTH_4) + clk |= (2 << 10); /* Set WIDEBUS */ + + if (ios->clock > 400000 && msmsdcc_pwrsave) + clk |= (1 << 9); /* PWRSAVE */ + + clk |= (1 << 12); /* FLOW_ENA */ + clk |= (1 << 15); /* feedback clock */ + + if (host->plat->translate_vdd) + pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd); + + switch (ios->power_mode) { + case MMC_POWER_OFF: + break; + case MMC_POWER_UP: + pwr |= MCI_PWR_UP; + break; + case MMC_POWER_ON: + pwr |= MCI_PWR_ON; + break; + } + + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) + pwr |= MCI_OD; + + writel(clk, host->base + MMCICLOCK); + +// if (host->pwr != pwr) { +// host->pwr = pwr; + writel(pwr, host->base + MMCIPOWER); +// } + + if (!(clk & MCI_CLK_ENABLE) && host->clks_on) { + clk_disable(host->clk); + clk_disable(host->pclk); + host->clks_on = 0; + } } - clk |= MCI_CLK_ENABLE; - } - - if (ios->bus_width == MMC_BUS_WIDTH_4) - clk |= (2 << 10); /* Set WIDEBUS */ - - if (ios->clock > 400000 && msmsdcc_pwrsave) - clk |= (1 << 9); /* PWRSAVE */ - - clk |= (1 << 12); /* FLOW_ENA */ - clk |= (1 << 15); /* feedback clock */ - - if (host->plat->translate_vdd) - pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd); - - switch (ios->power_mode) { - case MMC_POWER_OFF: - break; - case MMC_POWER_UP: - pwr |= MCI_PWR_UP; - break; - case MMC_POWER_ON: - pwr |= MCI_PWR_ON; - break; - } - - if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) - pwr |= MCI_OD; - - writel(clk, host->base + MMCICLOCK); - - if (host->pwr != pwr) { - host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); - } - - if (!(clk & MCI_CLK_ENABLE) && host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } -} - -static const struct mmc_host_ops msmsdcc_ops = { - .request = msmsdcc_request, - .set_ios = msmsdcc_set_ios, -}; - -static void -msmsdcc_check_status(unsigned long data) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *)data; - unsigned int status; - - if (!host->plat->status) { - mmc_detect_change(host->mmc, 0); - goto out; - } - - status = host->plat->status(mmc_dev(host->mmc)); - host->eject = !status; - if (status ^ host->oldstat) { - printk(KERN_INFO - "%s: Slot status change detected (%d -> %d)\n", - mmc_hostname(host->mmc), host->oldstat, status); - mmc_detect_change(host->mmc, 0); - } - - host->oldstat = status; + + static const struct mmc_host_ops msmsdcc_ops = { + .request = msmsdcc_request, + .set_ios = msmsdcc_set_ios, + }; + + static void + msmsdcc_check_status(unsigned long data) + { + struct msmsdcc_host *host = (struct msmsdcc_host *)data; + unsigned int status; + + if (!host->plat->status) { + mmc_detect_change(host->mmc, 0); + goto out; + } + + status = host->plat->status(mmc_dev(host->mmc)); + host->eject = !status; + if (status ^ host->oldstat) { + printk(KERN_INFO + "%s: Slot status change detected (%d -> %d)\n", + mmc_hostname(host->mmc), host->oldstat, status); + mmc_detect_change(host->mmc, 0); + } + + host->oldstat = status; out: - if (host->timer.function) + if (host->timer.function) mod_timer(&host->timer, jiffies + HZ); -} + } -static irqreturn_t -msmsdcc_platform_status_irq(int irq, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; + static irqreturn_t + msmsdcc_platform_status_irq(int irq, void *dev_id) + { + struct msmsdcc_host *host = dev_id; - printk(KERN_DEBUG "%s: %d\n", __func__, irq); - msmsdcc_check_status((unsigned long) host); - return IRQ_HANDLED; -} + printk(KERN_DEBUG "%s: %d\n", __func__, irq); + msmsdcc_check_status((unsigned long) host); + return IRQ_HANDLED; + } -static void -msmsdcc_status_notify_cb(int card_present, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; + static void + msmsdcc_status_notify_cb(int card_present, void *dev_id) + { + struct msmsdcc_host *host = dev_id; - printk(KERN_DEBUG "%s: card_present %d\n", mmc_hostname(host->mmc), - card_present); - msmsdcc_check_status((unsigned long) host); -} + printk(KERN_DEBUG "%s: card_present %d\n", mmc_hostname(host->mmc), + card_present); + msmsdcc_check_status((unsigned long) host); + } /* - * called when a command expires. - * Dump some debugging, and then error - * out the transaction. + * called when a command expires. + * Dump some debugging, and then error + * out the transaction. */ -static void -msmsdcc_command_expired(unsigned long _data) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *) _data; - struct mmc_request *mrq; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - mrq = host->mrq; - - if (!mrq) { - printk(KERN_INFO "%s: Command expiry misfire\n", - mmc_hostname(host->mmc)); - spin_unlock_irqrestore(&host->lock, flags); - return; - } - - printk(KERN_ERR "%s: Command timeout (%p %p %p %p)\n", - mmc_hostname(host->mmc), mrq, mrq->cmd, - mrq->data, host->dma.sg); - - mrq->cmd->error = -ETIMEDOUT; - msmsdcc_stop_data(host); - - writel(0, host->base + MMCICOMMAND); - - host->mrq = NULL; - host->cmd = NULL; - - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(host->mmc, mrq); -} - -static int -msmsdcc_init_dma(struct msmsdcc_host *host) -{ - memset(&host->dma, 0, sizeof(struct msmsdcc_dma_data)); - host->dma.host = host; - host->dma.channel = -1; - - if (!host->dmares) - return -ENODEV; - - host->dma.nc = dma_alloc_coherent(NULL, - sizeof(struct msmsdcc_nc_dmadata), - &host->dma.nc_busaddr, - GFP_KERNEL); - if (host->dma.nc == NULL) { - printk(KERN_ERR "Unable to allocate DMA buffer\n"); - return -ENOMEM; - } - memset(host->dma.nc, 0x00, sizeof(struct msmsdcc_nc_dmadata)); - host->dma.cmd_busaddr = host->dma.nc_busaddr; - host->dma.cmdptr_busaddr = host->dma.nc_busaddr + - offsetof(struct msmsdcc_nc_dmadata, cmdptr); - host->dma.channel = host->dmares->start; - - return 0; -} - -static int -msmsdcc_probe(struct platform_device *pdev) -{ - struct mmc_platform_data *plat = pdev->dev.platform_data; - struct msmsdcc_host *host; - struct mmc_host *mmc; - struct resource *irqres = NULL; - struct resource *memres = NULL; - struct resource *dmares = NULL; - int ret; - int i; - - /* must have platform data */ - if (!plat) { - printk(KERN_ERR "%s: Platform data not available\n", __func__); - ret = -EINVAL; - goto out; - } - - if (pdev->id < 1 || pdev->id > 4) - return -EINVAL; - - if (pdev->resource == NULL || pdev->num_resources < 2) { - printk(KERN_ERR "%s: Invalid resource\n", __func__); - return -ENXIO; - } - - for (i = 0; i < pdev->num_resources; i++) { - if (pdev->resource[i].flags & IORESOURCE_MEM) - memres = &pdev->resource[i]; - if (pdev->resource[i].flags & IORESOURCE_IRQ) - irqres = &pdev->resource[i]; - if (pdev->resource[i].flags & IORESOURCE_DMA) - dmares = &pdev->resource[i]; - } - if (!irqres || !memres) { - printk(KERN_ERR "%s: Invalid resource\n", __func__); - return -ENXIO; - } + static void + msmsdcc_command_expired(unsigned long _data) + { + struct msmsdcc_host *host = (struct msmsdcc_host *) _data; + struct mmc_request *mrq; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + mrq = host->mrq; + + if (!mrq) { + printk(KERN_INFO "%s: Command expiry misfire\n", + mmc_hostname(host->mmc)); + spin_unlock_irqrestore(&host->lock, flags); + return; + } + + printk(KERN_ERR "%s: Command timeout (%p %p %p %p)\n", + mmc_hostname(host->mmc), mrq, mrq->cmd, + mrq->data, host->dma.sg); + + mrq->cmd->error = -ETIMEDOUT; + msmsdcc_stop_data(host); + + writel(0, host->base + MMCICOMMAND); + + host->mrq = NULL; + host->cmd = NULL; + + spin_unlock_irqrestore(&host->lock, flags); + mmc_request_done(host->mmc, mrq); + } + + static int + msmsdcc_init_dma(struct msmsdcc_host *host) + { + memset(&host->dma, 0, sizeof(struct msmsdcc_dma_data)); + host->dma.host = host; + host->dma.channel = -1; + + if (!host->dmares) + return -ENODEV; + + host->dma.nc = dma_alloc_coherent(NULL, + sizeof(struct msmsdcc_nc_dmadata), + &host->dma.nc_busaddr, + GFP_KERNEL); + if (host->dma.nc == NULL) { + printk(KERN_ERR "Unable to allocate DMA buffer\n"); + return -ENOMEM; + } + memset(host->dma.nc, 0x00, sizeof(struct msmsdcc_nc_dmadata)); + host->dma.cmd_busaddr = host->dma.nc_busaddr; + host->dma.cmdptr_busaddr = host->dma.nc_busaddr + + offsetof(struct msmsdcc_nc_dmadata, cmdptr); + host->dma.channel = host->dmares->start; + + return 0; + } + + static int + msmsdcc_probe(struct platform_device *pdev) + { + struct mmc_platform_data *plat = pdev->dev.platform_data; + struct msmsdcc_host *host; + struct mmc_host *mmc; + struct resource *irqres = NULL; + struct resource *memres = NULL; + struct resource *dmares = NULL; + int ret; + int i; + + /* must have platform data */ + if (!plat) { + printk(KERN_ERR "%s: Platform data not available\n", __func__); + ret = -EINVAL; + goto out; + } + + if (pdev->id < 1 || pdev->id > 4) + return -EINVAL; + + if (pdev->resource == NULL || pdev->num_resources < 2) { + printk(KERN_ERR "%s: Invalid resource\n", __func__); + return -ENXIO; + } + + for (i = 0; i < pdev->num_resources; i++) { + if (pdev->resource[i].flags & IORESOURCE_MEM) + memres = &pdev->resource[i]; + if (pdev->resource[i].flags & IORESOURCE_IRQ) + irqres = &pdev->resource[i]; + if (pdev->resource[i].flags & IORESOURCE_DMA) + dmares = &pdev->resource[i]; + } + if (!irqres || !memres) { + printk(KERN_ERR "%s: Invalid resource\n", __func__); + return -ENXIO; + } /* - * Setup our host structure - */ - - mmc = mmc_alloc_host(sizeof(struct msmsdcc_host), &pdev->dev); - if (!mmc) { - ret = -ENOMEM; - goto out; - } - - host = mmc_priv(mmc); - host->pdev_id = pdev->id; - host->plat = plat; - host->mmc = mmc; - host->base = memres->start; - host->irqres = irqres; - host->memres = memres; - host->dmares = dmares; - spin_lock_init(&host->lock); + * Setup our host structure + */ + + mmc = mmc_alloc_host(sizeof(struct msmsdcc_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + goto out; + } + + host = mmc_priv(mmc); + host->pdev_id = pdev->id; + host->plat = plat; + host->mmc = mmc; + host->base = memres->start; + host->irqres = irqres; + host->memres = memres; + host->dmares = dmares; + host->eject = 0; + spin_lock_init(&host->lock); #ifdef CONFIG_MMC_EMBEDDED_SDIO - if (plat->embedded_sdio) - mmc_set_embedded_sdio_data(mmc, - &plat->embedded_sdio->cis, - &plat->embedded_sdio->cccr, - plat->embedded_sdio->funcs, - plat->embedded_sdio->num_funcs); + if (plat->embedded_sdio) + mmc_set_embedded_sdio_data(mmc, + &plat->embedded_sdio->cis, + &plat->embedded_sdio->cccr, + plat->embedded_sdio->funcs, + plat->embedded_sdio->num_funcs); #endif /* - * Setup DMA - */ - msmsdcc_init_dma(host); + * Setup DMA + */ + msmsdcc_init_dma(host); /* - * Setup main peripheral bus clock - */ - host->pclk = clk_get(&pdev->dev, msmsdcc_pclks[pdev->id]); - if (IS_ERR(host->pclk)) { - ret = PTR_ERR(host->pclk); - goto host_free; - } - - ret = clk_enable(host->pclk); - if (ret) - goto pclk_put; + * Setup main peripheral bus clock + */ + host->pclk = clk_get(&pdev->dev, msmsdcc_pclks[pdev->id]); + if (IS_ERR(host->pclk)) { + ret = PTR_ERR(host->pclk); + goto host_free; + } - host->pclk_rate = clk_get_rate(host->pclk); + ret = clk_enable(host->pclk); + if (ret) + goto pclk_put; + host->pclk_rate = clk_get_rate(host->pclk); + printk("current pclock %d\n", host->pclk_rate); + /* - * Setup SDC MMC clock - */ - host->clk = clk_get(&pdev->dev, msmsdcc_clks[pdev->id]); - if (IS_ERR(host->clk)) { - ret = PTR_ERR(host->clk); - goto pclk_disable; - } + * Setup SDC MMC clock + */ + host->clk = clk_get(&pdev->dev, msmsdcc_clks[pdev->id]); + if (IS_ERR(host->clk)) { + ret = PTR_ERR(host->clk); + goto pclk_disable; + } - ret = clk_enable(host->clk); - if (ret) - goto clk_put; + ret = clk_enable(host->clk); + if (ret) + goto clk_put; - ret = clk_set_rate(host->clk, msmsdcc_fmin); - if (ret) { - printk(KERN_ERR "%s: Clock rate set failed (%d)\n", - __func__, ret); - goto clk_disable; - } + ret = clk_set_rate(host->clk, msmsdcc_fmin); + if (ret) { + printk(KERN_ERR "%s: Clock rate set failed (%d)\n", + __func__, ret); + goto clk_disable; + } - host->clk_rate = clk_get_rate(host->clk); + host->clk_rate = clk_get_rate(host->clk); - host->clks_on = 1; + host->clks_on = 1; /* - * Setup MMC host structure - */ - mmc->ops = &msmsdcc_ops; - mmc->f_min = msmsdcc_fmin; - mmc->f_max = msmsdcc_fmax; - mmc->ocr_avail = plat->ocr_mask; - mmc->caps = MMC_CAP_MULTIWRITE; - - if (msmsdcc_4bit) - mmc->caps |= MMC_CAP_4_BIT_DATA; - - mmc->max_phys_segs = NR_SG; - mmc->max_hw_segs = NR_SG; - mmc->max_blk_size = 4096; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */ - mmc->max_blk_count = 65536; - - mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */ - mmc->max_seg_size = mmc->max_req_size; + * Setup MMC host structure + */ + mmc->ops = &msmsdcc_ops; + mmc->f_min = msmsdcc_fmin; + mmc->f_max = msmsdcc_fmax; + mmc->ocr_avail = plat->ocr_mask; + mmc->caps = MMC_CAP_MULTIWRITE; + + if (msmsdcc_4bit) + mmc->caps |= MMC_CAP_4_BIT_DATA; + + mmc->max_phys_segs = NR_SG; + mmc->max_hw_segs = NR_SG; + // mmc->max_blk_size = 4096; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */ +// mmc->max_blk_count = 65536; + mmc->max_blk_size = 512; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */ + mmc->max_blk_count = 127; + + mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */ + mmc->max_seg_size = mmc->max_req_size; - writel(0, host->base + MMCIMASK0); - writel(0x5c007ff, host->base + MMCICLEAR); + writel(0, host->base + MMCIMASK0); + writel(0x5c007ff, host->base + MMCICLEAR); - writel(MCI_IRQENABLE, host->base + MMCIMASK0); + writel(MCI_IRQENABLE, host->base + MMCIMASK0); /* - * Setup card detect change - */ - - memset(&host->timer, 0, sizeof(host->timer)); - - if (plat->status_irq) { - ret = request_irq(plat->status_irq, - msmsdcc_platform_status_irq, - IRQF_SHARED, - DRIVER_NAME " (slot)", - host); - if (ret) { - printk(KERN_ERR "Unable to get slot IRQ %d (%d)\n", - plat->status_irq, ret); - goto clk_disable; - } - } else if (plat->register_status_notify) { - plat->register_status_notify(msmsdcc_status_notify_cb, host); - } else if (!plat->status) - printk(KERN_ERR "%s: No card detect facilities available\n", - mmc_hostname(mmc)); - else { - init_timer(&host->timer); - host->timer.data = (unsigned long)host; - host->timer.function = msmsdcc_check_status; - host->timer.expires = jiffies + HZ; - add_timer(&host->timer); - } - - if (plat->status) { - host->oldstat = host->plat->status(mmc_dev(host->mmc)); - host->eject = !host->oldstat; - } + * Setup card detect change + */ + + memset(&host->timer, 0, sizeof(host->timer)); + + if (plat->status_irq) { + ret = request_irq(plat->status_irq, + msmsdcc_platform_status_irq, + IRQF_SHARED, + DRIVER_NAME " (slot)", + host); + if (ret) { + printk(KERN_ERR "Unable to get slot IRQ %d (%d)\n", + plat->status_irq, ret); + goto clk_disable; + } + } else if (plat->register_status_notify) { + plat->register_status_notify(msmsdcc_status_notify_cb, host); + } else if (!plat->status) + printk(KERN_ERR "%s: No card detect facilities available\n", + mmc_hostname(mmc)); + else { + init_timer(&host->timer); + host->timer.data = (unsigned long)host; + host->timer.function = msmsdcc_check_status; + host->timer.expires = jiffies + HZ; + add_timer(&host->timer); + } + + if (plat->status) { + host->oldstat = host->plat->status(mmc_dev(host->mmc)); + host->eject = !host->oldstat; + } /* - * Setup a command timer. We currently need this due to - * some 'strange' timeout / error handling situations. - */ - init_timer(&host->command_timer); - host->command_timer.data = (unsigned long) host; - host->command_timer.function = msmsdcc_command_expired; - - ret = request_irq(irqres->start, msmsdcc_irq, IRQF_SHARED, - DRIVER_NAME " (cmd)", host); - if (ret) - goto platform_irq_free; - - mmc_set_drvdata(pdev, mmc); - mmc_add_host(mmc); - - printk(KERN_INFO - "%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n", - mmc_hostname(mmc), (unsigned long long)memres->start, - (unsigned int) irqres->start, - (unsigned int) plat->status_irq, host->dma.channel); - printk(KERN_INFO "%s: 4 bit data mode %s\n", mmc_hostname(mmc), - (mmc->caps & MMC_CAP_4_BIT_DATA ? "enabled" : "disabled")); - printk(KERN_INFO "%s: MMC clock %u -> %u Hz, PCLK %u Hz\n", - mmc_hostname(mmc), msmsdcc_fmin, msmsdcc_fmax, host->pclk_rate); - printk(KERN_INFO "%s: Slot eject status = %d\n", mmc_hostname(mmc), - host->eject); - printk(KERN_INFO "%s: Power save feature enable = %d\n", - mmc_hostname(mmc), msmsdcc_pwrsave); - - if (host->dma.channel != -1) { - printk(KERN_INFO - "%s: DM non-cached buffer at %p, dma_addr 0x%.8x\n", - mmc_hostname(mmc), host->dma.nc, host->dma.nc_busaddr); - printk(KERN_INFO - "%s: DM cmd busaddr %u, cmdptr busaddr %u\n", - mmc_hostname(mmc), host->dma.cmd_busaddr, - host->dma.cmdptr_busaddr); - } else - printk(KERN_INFO - "%s: PIO transfer enabled\n", mmc_hostname(mmc)); - if (host->timer.function) - printk(KERN_INFO "%s: Polling status mode enabled\n", - mmc_hostname(mmc)); + * Setup a command timer. We currently need this due to + * some 'strange' timeout / error handling situations. + */ + init_timer(&host->command_timer); + host->command_timer.data = (unsigned long) host; + host->command_timer.function = msmsdcc_command_expired; + + ret = request_irq(irqres->start, msmsdcc_irq, IRQF_SHARED, + DRIVER_NAME " (cmd)", host); + if (ret) + goto platform_irq_free; + + mmc_set_drvdata(pdev, mmc); + mmc_add_host(mmc); + + printk(KERN_INFO + "%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n", + mmc_hostname(mmc), (unsigned long long)memres->start, + (unsigned int) irqres->start, + (unsigned int) plat->status_irq, host->dma.channel); + printk(KERN_INFO "%s: 4 bit data mode %s\n", mmc_hostname(mmc), + (mmc->caps & MMC_CAP_4_BIT_DATA ? "enabled" : "disabled")); + printk(KERN_INFO "%s: MMC clock %u -> %u Hz, PCLK %u Hz\n", + mmc_hostname(mmc), msmsdcc_fmin, msmsdcc_fmax, host->pclk_rate); + printk(KERN_INFO "%s: Slot eject status = %d\n", mmc_hostname(mmc), + host->eject); + printk(KERN_INFO "%s: Power save feature enable = %d\n", + mmc_hostname(mmc), msmsdcc_pwrsave); + + if (host->dma.channel != -1) { + printk(KERN_INFO + "%s: DM non-cached buffer at %p, dma_addr 0x%.8x\n", + mmc_hostname(mmc), host->dma.nc, host->dma.nc_busaddr); + printk(KERN_INFO + "%s: DM cmd busaddr %u, cmdptr busaddr %u\n", + mmc_hostname(mmc), host->dma.cmd_busaddr, + host->dma.cmdptr_busaddr); + } else + printk(KERN_INFO + "%s: PIO transfer enabled\n", mmc_hostname(mmc)); + if (host->timer.function) + printk(KERN_INFO "%s: Polling status mode enabled\n", + mmc_hostname(mmc)); #if defined(CONFIG_DEBUG_FS) - msmsdcc_dbg_createhost(host); + msmsdcc_dbg_createhost(host); #endif - return 0; + return 0; platform_irq_free: - if (plat->status_irq) - free_irq(plat->status_irq, host); + if (plat->status_irq) + free_irq(plat->status_irq, host); clk_disable: - clk_disable(host->clk); + clk_disable(host->clk); clk_put: - clk_put(host->clk); + clk_put(host->clk); pclk_disable: - clk_disable(host->pclk); + clk_disable(host->pclk); pclk_put: - clk_put(host->pclk); + clk_put(host->pclk); host_free: - mmc_free_host(mmc); + mmc_free_host(mmc); out: - return ret; -} - -static int -msmsdcc_suspend(struct platform_device *dev, pm_message_t state) -{ - struct mmc_host *mmc = mmc_get_drvdata(dev); - int rc = 0; - - if (mmc) { - struct msmsdcc_host *host = mmc_priv(mmc); - - if (host->plat->status_irq) - disable_irq(host->plat->status_irq); - if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) - rc = mmc_suspend_host(mmc, state); - if (!rc) { - writel(0, host->base + MMCIMASK0); + return ret; + } - if (host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; + static int + msmsdcc_suspend(struct platform_device *dev, pm_message_t state) + { + struct mmc_host *mmc = mmc_get_drvdata(dev); + int rc = 0; + + if (mmc) { + struct msmsdcc_host *host = mmc_priv(mmc); + + if (host->plat->status_irq) + disable_irq(host->plat->status_irq); + if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) + rc = mmc_suspend_host(mmc, state); + if (!rc) { + writel(0, host->base + MMCIMASK0); + + if (host->clks_on) { + clk_disable(host->clk); + clk_disable(host->pclk); + host->clks_on = 0; + } + } } + return rc; } - } - return rc; -} - -static int -msmsdcc_resume(struct platform_device *dev) -{ - struct mmc_host *mmc = mmc_get_drvdata(dev); - int rc = 0; - - if (mmc) { - struct msmsdcc_host *host = mmc_priv(mmc); - - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; + + static int + msmsdcc_resume(struct platform_device *dev) + { + struct mmc_host *mmc = mmc_get_drvdata(dev); + int rc = 0; + + if (mmc) { + struct msmsdcc_host *host = mmc_priv(mmc); + + if (!host->clks_on) { + clk_enable(host->pclk); + clk_enable(host->clk); + host->clks_on = 1; + } + + writel(MCI_IRQENABLE, host->base + MMCIMASK0); + if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) + rc = mmc_resume_host(mmc); + + if (host->plat->status_irq) + enable_irq(host->plat->status_irq); + } + return rc; + } + + static struct platform_driver msmsdcc_driver = { + .probe = msmsdcc_probe, + .suspend = NULL, //msmsdcc_suspend, + .resume = NULL, //msmsdcc_resume, + .driver = { + .name = "msm_sdcc", + }, + }; + + static int __init msmsdcc_init(void) + { + return platform_driver_register(&msmsdcc_driver); + } + + static void __exit msmsdcc_exit(void) + { + platform_driver_unregister(&msmsdcc_driver); + } + + static int __init msmsdcc_pwrsave_setup(char *__unused) + { + msmsdcc_pwrsave = 1; + return 1; + } + + static int __init msmsdcc_nopwrsave_setup(char *__unused) + { + msmsdcc_pwrsave = 0; + return 1; + } + + static int __init msmsdcc_4bit_setup(char *__unused) + { + msmsdcc_4bit = 1; + return 1; } - writel(MCI_IRQENABLE, host->base + MMCIMASK0); - if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) - rc = mmc_resume_host(mmc); - - if (host->plat->status_irq) - enable_irq(host->plat->status_irq); - } - return rc; -} - -static struct platform_driver msmsdcc_driver = { - .probe = msmsdcc_probe, - .suspend = msmsdcc_suspend, - .resume = msmsdcc_resume, - .driver = { - .name = "msm_sdcc", - }, -}; - -static int __init msmsdcc_init(void) -{ - return platform_driver_register(&msmsdcc_driver); -} - -static void __exit msmsdcc_exit(void) -{ - platform_driver_unregister(&msmsdcc_driver); -} - -static int __init msmsdcc_pwrsave_setup(char *__unused) -{ - msmsdcc_pwrsave = 1; - return 1; -} - -static int __init msmsdcc_nopwrsave_setup(char *__unused) -{ - msmsdcc_pwrsave = 0; - return 1; -} - -static int __init msmsdcc_4bit_setup(char *__unused) -{ - msmsdcc_4bit = 1; - return 1; -} - -static int __init msmsdcc_1bit_setup(char *__unused) -{ - msmsdcc_4bit = 0; - return 1; -} - -static int __init msmsdcc_fmin_setup(char *str) -{ - unsigned int n; - - if (!get_option(&str, &n)) - return 0; - msmsdcc_fmin = n; - return 1; -} - -static int __init msmsdcc_fmax_setup(char *str) -{ - unsigned int n; - - if (!get_option(&str, &n)) - return 0; - msmsdcc_fmax = n; - return 1; -} - -__setup("msmsdcc_4bit", msmsdcc_4bit_setup); -__setup("msmsdcc_1bit", msmsdcc_1bit_setup); -__setup("msmsdcc_pwrsave", msmsdcc_pwrsave_setup); -__setup("msmsdcc_nopwrsave", msmsdcc_nopwrsave_setup); -__setup("msmsdcc_fmin=", msmsdcc_fmin_setup); -__setup("msmsdcc_fmax=", msmsdcc_fmax_setup); - -module_init(msmsdcc_init); -module_exit(msmsdcc_exit); -module_param(msmsdcc_fmin, uint, 0444); -module_param(msmsdcc_fmax, uint, 0444); -module_param(msmsdcc_4bit, uint, 0444); - -MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); -MODULE_LICENSE("GPL"); + static int __init msmsdcc_1bit_setup(char *__unused) + { + msmsdcc_4bit = 0; + return 1; + } + + static int __init msmsdcc_fmin_setup(char *str) + { + unsigned int n; + + if (!get_option(&str, &n)) + return 0; + msmsdcc_fmin = n; + return 1; + } + + static int __init msmsdcc_fmax_setup(char *str) + { + unsigned int n; + + if (!get_option(&str, &n)) + return 0; + msmsdcc_fmax = n; + return 1; + } + + __setup("msmsdcc_4bit", msmsdcc_4bit_setup); + __setup("msmsdcc_1bit", msmsdcc_1bit_setup); + __setup("msmsdcc_pwrsave", msmsdcc_pwrsave_setup); + __setup("msmsdcc_nopwrsave", msmsdcc_nopwrsave_setup); + __setup("msmsdcc_fmin=", msmsdcc_fmin_setup); + __setup("msmsdcc_fmax=", msmsdcc_fmax_setup); + + module_init(msmsdcc_init); + module_exit(msmsdcc_exit); + module_param(msmsdcc_fmin, uint, 0444); + module_param(msmsdcc_fmax, uint, 0444); + module_param(msmsdcc_4bit, uint, 0444); + + MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); + MODULE_LICENSE("GPL"); #if defined(CONFIG_DEBUG_FS) -static int -msmsdcc_dbg_state_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t -msmsdcc_dbg_state_read(struct file *file, char __user *ubuf, - size_t count, loff_t *ppos) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *) file->private_data; - char buf[1024]; - int max, i; - - i = 0; - max = sizeof(buf) -1; - - i += scnprintf(buf + i, max - i, "STAT: %p %p %p\n", host->mrq, host->cmd, - host->data); - if (host->cmd) { - struct mmc_command *cmd = host->cmd; - - i+= scnprintf(buf + i, max - i, "CMD : %.8x %.8x %.8x\n", - cmd->opcode, cmd->arg, cmd->flags); - } - if (host->data) { - struct mmc_data *data = host->data; - i+= scnprintf(buf + i, max - i, "DAT0: %.8x %.8x %.8x %.8x %.8x %.8x\n", - data->timeout_ns, data->timeout_clks, - data->blksz, data->blocks, data->error, - data->flags); - i+= scnprintf(buf + i, max - i, "DAT1: %.8x %.8x %.8x %p\n", - host->xfer_size, host->xfer_remain, - host->data_xfered, host->dma.sg); - } - - return simple_read_from_buffer(ubuf, count, ppos, buf, i); -} - -static const struct file_operations msmsdcc_dbg_state_ops = { - .read = msmsdcc_dbg_state_read, - .open = msmsdcc_dbg_state_open, -}; - -static void msmsdcc_dbg_createhost(struct msmsdcc_host *host) -{ - if (debugfs_dir) { - debugfs_create_file(mmc_hostname(host->mmc), 0644, debugfs_dir, - host, &msmsdcc_dbg_state_ops); - } -} - -static int __init msmsdcc_dbg_init(void) -{ - int err; - - debugfs_dir = debugfs_create_dir("msmsdcc", 0); - if (IS_ERR(debugfs_dir)) { - err = PTR_ERR(debugfs_dir); - debugfs_dir = NULL; - return err; - } - - return 0; -} - -device_initcall(msmsdcc_dbg_init); + static int + msmsdcc_dbg_state_open(struct inode *inode, struct file *file) + { + file->private_data = inode->i_private; + return 0; + } + + static ssize_t + msmsdcc_dbg_state_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) + { + struct msmsdcc_host *host = (struct msmsdcc_host *) file->private_data; + char buf[1024]; + int max, i; + + i = 0; + max = sizeof(buf) -1; + + i += scnprintf(buf + i, max - i, "STAT: %p %p %p\n", host->mrq, host->cmd, + host->data); + if (host->cmd) { + struct mmc_command *cmd = host->cmd; + + i+= scnprintf(buf + i, max - i, "CMD : %.8x %.8x %.8x\n", + cmd->opcode, cmd->arg, cmd->flags); + } + if (host->data) { + struct mmc_data *data = host->data; + i+= scnprintf(buf + i, max - i, "DAT0: %.8x %.8x %.8x %.8x %.8x %.8x\n", + data->timeout_ns, data->timeout_clks, + data->blksz, data->blocks, data->error, + data->flags); + i+= scnprintf(buf + i, max - i, "DAT1: %.8x %.8x %.8x %p\n", + host->xfer_size, host->xfer_remain, + host->data_xfered, host->dma.sg); + } + + return simple_read_from_buffer(ubuf, count, ppos, buf, i); + } + + static const struct file_operations msmsdcc_dbg_state_ops = { + .read = msmsdcc_dbg_state_read, + .open = msmsdcc_dbg_state_open, + }; + + static void msmsdcc_dbg_createhost(struct msmsdcc_host *host) + { + if (debugfs_dir) { + debugfs_create_file(mmc_hostname(host->mmc), 0644, debugfs_dir, + host, &msmsdcc_dbg_state_ops); + } + } + + static int __init msmsdcc_dbg_init(void) + { + int err; + + debugfs_dir = debugfs_create_dir("msmsdcc", 0); + if (IS_ERR(debugfs_dir)) { + err = PTR_ERR(debugfs_dir); + debugfs_dir = NULL; + return err; + } + + return 0; + } + + device_initcall(msmsdcc_dbg_init); #endif diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 7bdf26f..b54b446 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -549,4 +549,10 @@ config RTC_DRV_MSM7X00A help RTC driver for Qualcomm MSM7K chipsets +config RTC_DRV_MSM7X00 + tristate "MSM7X00" + depends on RTC_CLASS + help + RTC driver for Qualcomm MSM7K chipsets + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 416014b..59ce7a6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -56,3 +56,4 @@ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_MSM7X00A) += rtc-msm7x00a.o +obj-$(CONFIG_RTC_DRV_MSM7X00) += rtc-msm7x00.o diff --git a/drivers/rtc/rtc-msm7x00.c b/drivers/rtc/rtc-msm7x00.c new file mode 100644 index 0000000..ecef2f9 --- /dev/null +++ b/drivers/rtc/rtc-msm7x00.c @@ -0,0 +1,102 @@ +/* drivers/rtc/rtc-msm7x00.c + * + * Author: Martin Johnson + * + * 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 + + +#define PDEV_NAME "msm_rtc" + +#define SECSFROM_1970_TO_1980 315532800 + +struct rtc_device *rtc; + +int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2); + +static int +msmrtc_pmlib_set_time(struct device *dev, struct rtc_time *tm) +{ + unsigned long unix_time; + unsigned t; + + if (rtc_valid_tm(tm)) + return -EINVAL; + + rtc_tm_to_time(tm, &unix_time); + unix_time=unix_time-SECSFROM_1970_TO_1980; // MSM RTC starts 10 years after unix time + t = unix_time; + msm_proc_comm(0x182,&t,0); + + return 0; +} + +static int +msmrtc_pmlib_read_time(struct device *dev, struct rtc_time *tm) +{ + unsigned long secs; + + secs=msm_proc_comm(0x181,0,0); + secs=secs+SECSFROM_1970_TO_1980; // MSM RTC starts 10 years after unix time + rtc_time_to_tm(secs, tm); + return 0; +} + +static struct rtc_class_ops msm_rtc_ops = { + .read_time = msmrtc_pmlib_read_time, + .set_time = msmrtc_pmlib_set_time, +}; + +static int +msmrtc_probe(struct platform_device *pdev) +{ + printk("RTC probe\n"); + rtc = rtc_device_register("msm_rtc", + &pdev->dev, + &msm_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtc)) { + printk(KERN_ERR "%s: Can't register RTC device (%ld)\n", + pdev->name, PTR_ERR(rtc)); + return PTR_ERR(rtc); + } + printk("MSM RTC started\n"); + return 0; +} + + +static struct platform_driver msmrtc_driver = { + .probe = msmrtc_probe, + .driver = { + .name = "msm_rtc", + }, +}; + +static int __init msmrtc_init(void) +{ + printk("MSM RTC init\n"); + return platform_driver_register(&msmrtc_driver); +} + +module_init(msmrtc_init); + +MODULE_DESCRIPTION("RTC driver for Qualcomm MSM7x00 chipsets"); +MODULE_AUTHOR("Martin Johnson "); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index 2feca10..b5f288a 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -41,7 +41,6 @@ #define FLAG_DISABLE_HIBERNATION 0x0001 #define FLAG_HAVE_CAPS 0x0002 #define FLAG_HAS_VSYNC_IRQ 0x0004 -#define FLAG_HAVE_STATUS 0x0008 #define CMD_GET_CLIENT_CAP 0x0601 #define CMD_GET_CLIENT_STATUS 0x0602 @@ -68,7 +67,7 @@ struct reg_read_info struct mddi_info { const char *name; - uint16_t flags; + uint16_t flags; uint16_t version; uint32_t base; int irq; @@ -94,11 +93,9 @@ struct mddi_info struct reg_read_info *reg_read; struct mddi_client_caps caps; - struct mddi_client_status status; #ifdef CONFIG_ANDROID_POWER android_early_suspend_t early_suspend; - android_suspend_lock_t idle_lock; #endif void (*mddi_client_power)(int on); @@ -135,38 +132,23 @@ static void mddi_handle_link_list_done(struct mddi_info *mddi) { } -static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi) -{ - printk(KERN_INFO "mddi: resetting rev ptr\n"); - mddi->rev_data_curr = 0; - mddi_writel(mddi->rev_addr, REV_PTR); - mddi_writel(mddi->rev_addr, REV_PTR); - mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD); -} - static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev) { int i; struct reg_read_info *ri; - if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) && - (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) { + if ((rev->hdr.length < MDDI_REV_BUFFER_SIZE) && + (rev->hdr.length >= sizeof(struct mddi_rev_packet))) { /* printk(KERN_INFO "rev: len=%04x type=%04x\n", * rev->hdr.length, rev->hdr.type); */ switch (rev->hdr.type) { - case TYPE_CLIENT_CAPS: + case 66: /* client caps */ memcpy(&mddi->caps, &rev->caps, sizeof(struct mddi_client_caps)); mddi->flags |= FLAG_HAVE_CAPS; wake_up(&mddi->int_wait); break; - case TYPE_CLIENT_STATUS: - memcpy(&mddi->status, &rev->status, - sizeof(struct mddi_client_status)); - mddi->flags |= FLAG_HAVE_STATUS; - wake_up(&mddi->int_wait); - break; case TYPE_REGISTER_ACCESS: /* printk(KERN_INFO "rev: reg %x = %x\n", * rev->reg.register_address, @@ -203,17 +185,13 @@ static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev) printk(KERN_INFO " %02x", rev->raw[i]); } printk(KERN_INFO "\n"); - mddi_reset_rev_encap_ptr(mddi); } } else { printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n", rev->hdr.length, mddi_readl(CURR_REV_PTR)); - mddi_reset_rev_encap_ptr(mddi); } } -static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask); - static void mddi_handle_rev_data_avail(struct mddi_info *mddi) { union mddi_rev *rev = mddi->rev_data; @@ -232,8 +210,8 @@ static void mddi_handle_rev_data_avail(struct mddi_info *mddi) rev_crc_err_count = mddi_readl(REV_CRC_ERR); if (rev_data_count > 1) printk(KERN_INFO "rev_data_count %d\n", rev_data_count); - /* printk(KERN_INFO "rev_data_count %d, INT %x\n", rev_data_count, - * mddi_readl(INT)); */ + /* printk(KERN_INFO "rev_data_count %d, INT %x\n", rev_data_count, + * mddi_readl(INT)); */ if (rev_crc_err_count) { printk(KERN_INFO "rev_crc_err_count %d, INT %x\n", @@ -279,13 +257,8 @@ static void mddi_handle_rev_data_avail(struct mddi_info *mddi) mddi->rev_data_curr = mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE; - if (length > MDDI_REV_BUFFER_SIZE - 2) { - printk(KERN_INFO "mddi: rev data length greater than buffer" - "size\n"); - mddi_reset_rev_encap_ptr(mddi); - return; - } - + /* printk(KERN_INFO "rev_data_curr %d + 2 + %d = %d\n", + * prev_offset, length, mddi->rev_data_curr); */ if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) { union mddi_rev tmprev; size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset; @@ -325,8 +298,8 @@ static irqreturn_t mddi_isr(int irq, void *data) mddi_writel(active, INT); - /* printk(KERN_INFO "%s: isr a=%08x e=%08x s=%08x\n", - mddi->name, active, mddi->int_enable, status); */ + /* printk(KERN_INFO "%s: isr a=%08x e=%08x s=%08x\n", */ + /* mddi->name, active, mddi->int_enable, status); */ /* ignore any interrupts we have disabled */ active &= mddi->int_enable; @@ -334,13 +307,22 @@ static irqreturn_t mddi_isr(int irq, void *data) mddi->got_int |= active; wake_up(&mddi->int_wait); + if (active & MDDI_INT_LINK_ACTIVE) { + mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE); + mddi->int_enable |= MDDI_INT_IN_HIBERNATION; + /* printk(KERN_INFO "%s: active\n", mddi->name); */ + } + if (active & MDDI_INT_IN_HIBERNATION) { + mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION); + mddi->int_enable |= MDDI_INT_LINK_ACTIVE; + /* printk(KERN_INFO "%s: hibernate\n", mddi->name); */ + } if (active & MDDI_INT_PRI_LINK_LIST_DONE) { mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE); mddi_handle_link_list_done(mddi); } if (active & MDDI_INT_REV_DATA_AVAIL) mddi_handle_rev_data_avail(mddi); - if (active & ~MDDI_INT_NEED_CLEAR) mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR); @@ -366,10 +348,9 @@ static long mddi_wait_interrupt_timeout(struct mddi_info *mddi, uint32_t intmask static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask) { if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0) - printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout " - "waiting for %x, INT = %x, STAT = %x gotint = %x\n", - current->pid, intmask, mddi_readl(INT), mddi_readl(STAT), - mddi->got_int); + printk(KERN_INFO KERN_ERR "mddi_wait_interrupt, timeout " + "waiting for %x, INT = %x, STAT = %x\n", + intmask, mddi_readl(INT), mddi_readl(STAT)); } static void mddi_init_rev_encap(struct mddi_info *mddi) @@ -382,6 +363,9 @@ static void mddi_init_rev_encap(struct mddi_info *mddi) static void mddi_init_registers(struct mddi_info *mddi) { + mddi_writel(MDDI_CMD_RESET, CMD); + mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); + mddi_writel(0x0001, VERSION); mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS); mddi_writel(0x0003, SPM); /* subframes per media */ @@ -389,7 +373,7 @@ static void mddi_init_registers(struct mddi_info *mddi) mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN); mddi_writel(0x0096, DRIVE_HI); /* 0x32 normal, 0x50 for Toshiba display */ - mddi_writel(0x0050, DRIVE_LO); + mddi_writel(0x0032, DRIVE_LO); mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */ mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV); @@ -415,7 +399,13 @@ static void mddi_init_registers(struct mddi_info *mddi) /* Need an even number for counts */ mddi_writel(0x60006, DRIVER_START_CNT); - mddi_set_auto_hibernate(mddi, 0); + if (mddi->flags & FLAG_DISABLE_HIBERNATION) { + mddi_writel(MDDI_CMD_HIBERNATE | 0, CMD); + } else { + /* hibernate after 1 empty subframe */ + mddi_writel(MDDI_CMD_HIBERNATE | 1, CMD); + } + mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); #if 1 /* ignore listen */ mddi_writel(MDDI_CMD_DISP_IGNORE, CMD); @@ -427,12 +417,14 @@ static void mddi_init_registers(struct mddi_info *mddi) mddi_init_rev_encap(mddi); } -void mddi_set_auto_hibernate(struct mddi_info *mddi, int on) +void mddi_hibernate_disable(struct mddi_info *mddi, int on) { - mddi_writel(MDDI_CMD_POWERDOWN, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION); - mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); +# if 0 + if (on && !(mddi->flags & FLAG_DISABLE_HIBERNATION)) + mddi_writel(MDDI_CMD_HIBERNATE | 1, CMD); + else + mddi_writel(MDDI_CMD_HIBERNATE | 0, CMD); +#endif } void mddi_power_panel(struct mddi_panel_info *panel, int on) @@ -446,17 +438,16 @@ void mddi_power_panel(struct mddi_panel_info *panel, int on) #ifdef CONFIG_ANDROID_POWER static void mddi_early_suspend(android_early_suspend_t *h) { - struct mddi_info *mddi = container_of(h, struct mddi_info, - early_suspend); - android_lock_idle(&mddi->idle_lock); + struct mddi_info *mddi = container_of(h, struct mddi_info, early_suspend); +#if 0 + if (mddi->panel_power) + mddi->panel_power(&mddi->panel_info, 0); +#endif if (mddi->mddi_enable) mddi->mddi_enable(&mddi->panel_info, 0); if (mddi->mddi_client_power) mddi->mddi_client_power(0); - mddi_writel(MDDI_CMD_RESET, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - clk_disable(mddi->clk); - android_unlock_suspend(&mddi->idle_lock); +// clk_disable(mddi->clk); } static void mddi_early_resume(android_early_suspend_t *h) @@ -464,23 +455,13 @@ static void mddi_early_resume(android_early_suspend_t *h) struct mddi_info *mddi = container_of(h, struct mddi_info, early_suspend); - android_lock_idle(&mddi->idle_lock); - mddi_set_auto_hibernate(mddi, 0); if (mddi->mddi_client_power) mddi->mddi_client_power(1); - clk_enable(mddi->clk); - mddi->rev_data_curr = 0; - mddi_init_registers(mddi); - mddi_writel(mddi->int_enable, INTEN); - mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); - mddi_writel(MDDI_CMD_SEND_RTD, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - mddi_set_auto_hibernate(mddi, 1); +// clk_enable(mddi->clk); if (mddi->mddi_enable) mddi->mddi_enable(&mddi->panel_info, 1); - android_unlock_suspend(&mddi->idle_lock); } #endif @@ -504,10 +485,6 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, mutex_init(&mddi->reg_read_lock); spin_lock_init(&mddi->int_lock); init_waitqueue_head(&mddi->int_wait); -#ifdef CONFIG_ANDROID_POWER - mddi->idle_lock.name = "mddi_idle_lock"; - android_init_suspend_lock(&mddi->idle_lock); -#endif mddi->flags = FLAG_DISABLE_HIBERNATION; @@ -518,6 +495,7 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, if (pd->has_vsync_irq) mddi->flags |= FLAG_HAS_VSYNC_IRQ; } +/* mddi->clk = clk_get(&mddi->panel_pdev.dev, clk_name); if (IS_ERR(mddi->clk)) { ret = PTR_ERR(mddi->clk); @@ -532,7 +510,7 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, mddi->clk_rate, clk_get_rate(mddi->clk)); goto fail0; } - +*/ dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL); if (dma == 0) { ret = -ENOMEM; @@ -562,30 +540,27 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE; mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE; mddi->reg_read_data = mddi->reg_write_data + 1; - mddi->reg_read_addr = mddi->reg_write_addr + - sizeof(*mddi->reg_write_data); + mddi->reg_read_addr = mddi->reg_write_addr + sizeof(*mddi->reg_write_data); - /* put the link in hibernate -- in case the bootloader didn't */ - mddi_set_auto_hibernate(mddi, 0); - mddi_writel(MDDI_CMD_RESET, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); mddi_init_registers(mddi); if (mddi->version < 0x20) { printk(KERN_INFO "%s: unsupported version 0x%x\n", mddi->name, mddi->version); - ret = -ENODEV; - goto fail2; +// ret = -ENODEV; +// goto fail2; } /* clear any stale interrupts */ mddi_writel(0xffffffff, INT); - mddi->int_enable = MDDI_INT_PRI_LINK_LIST_DONE | - MDDI_INT_REV_DATA_AVAIL | - MDDI_INT_REV_OVERFLOW | - MDDI_INT_REV_OVERWRITE | - MDDI_INT_RTD_FAILURE; + mddi->int_enable = MDDI_INT_LINK_ACTIVE | + MDDI_INT_IN_HIBERNATION | + MDDI_INT_PRI_LINK_LIST_DONE | + MDDI_INT_REV_DATA_AVAIL | + MDDI_INT_REV_OVERFLOW | + MDDI_INT_REV_OVERWRITE | + MDDI_INT_RTD_FAILURE; mddi_writel(mddi->int_enable, INTEN); mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); @@ -606,7 +581,7 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, /* mddi_writel(mddi_readl(INTEN) | MDDI_INT_NO_CMD_PKTS_PEND, INTEN); */ /* printk(KERN_INFO "MDDI_CMD_SEND_RTD: stat %x, rtd val %x\n", mddi_readl(STAT), mddi_readl(RTD_VAL)); */ stat = mddi_readl(STAT); - printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, rtd val %x\n", mddi_readl(INT), stat, mddi_readl(RTD_VAL)); + printk(KERN_INFO "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x\n", mddi_readl(INT), stat, mddi_readl(RTD_VAL)); /* msleep(10); */ /* printk(KERN_INFO "MDDI_CMD_SEND_RTD: stat %x, rtd val %x\n", mddi_readl(STAT), mddi_readl(RTD_VAL)); */ /* if((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0) */ @@ -618,18 +593,16 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, mddi_writel(CMD_GET_CLIENT_CAP, CMD); mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS, - HZ / 100); - + wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS, HZ / 100); if (mddi->flags & FLAG_HAVE_CAPS) break; - printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for " - "caps\n"); + printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for caps\n"); } if (mddi->flags & FLAG_HAVE_CAPS) { /* hibernate after 1 empty subframe */ - mddi_set_auto_hibernate(mddi, 1); + mddi_writel(MDDI_CMD_HIBERNATE | 1, CMD); + mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); /* setup panel_info which will be used by the fb core */ mddi->panel_info.mddi = mddi; @@ -652,6 +625,8 @@ static int __init mddi_init(struct mddi_info *mddi, const char *name, if (mddi->mddi_enable) mddi->mddi_enable(&mddi->panel_info, 1); + if (mddi->panel_power) + mddi->panel_power(&mddi->panel_info, 1); printk(KERN_INFO "%s: publish: %s\n", mddi->name, mddi->client_name); @@ -671,48 +646,12 @@ fail2: fail1: dma_free_coherent(NULL, 0x1000, dma, dma_addr); fail0: - clk_put(mddi->clk); +// clk_put(mddi->clk); fail: printk(KERN_INFO "%s: mddi_init() failed (%d)\n", name, ret); return ret; } -/* link must be active when this is called */ -int mddi_check_status(struct mddi_info *mddi) -{ - int ret = -1, retry = 3; - mutex_lock(&mddi->reg_read_lock); - mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - - do { - mddi->flags &= ~FLAG_HAVE_STATUS; - mddi_writel(CMD_GET_CLIENT_STATUS, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - wait_event_timeout(mddi->int_wait, - mddi->flags & FLAG_HAVE_STATUS, - HZ / 100); - - if (mddi->flags & FLAG_HAVE_STATUS) { - if (mddi->status.crc_error_count) - printk("mddi status: crc_error count: %d\n", - mddi->status.crc_error_count); - else - ret = 0; - break; - } else - printk("mddi status: failed to get client status\n"); - mddi_writel(MDDI_CMD_SEND_RTD, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - } while (--retry); - - mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - mutex_unlock(&mddi->reg_read_lock); - return ret; -} - - void mddi_remote_write(struct mddi_info *mddi, unsigned val, unsigned reg) { struct mddi_llentry *ll; @@ -738,7 +677,8 @@ void mddi_remote_write(struct mddi_info *mddi, unsigned val, unsigned reg) ll->data_count = 4; ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry, u.r.register_data_list); - ll->next = 0; +// ll->next = 0; + ll->next = (ll->data)>>16; // different on 7x00 ll->reserved = 0; /* s = mddi_readl(STAT); */ @@ -810,7 +750,7 @@ unsigned mddi_remote_read(struct mddi_info *mddi, unsigned reg) /* Enable Periodic Reverse Encapsulation. */ mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 && + if (wait_for_completion_timeout(&ri.done, HZ/60) == 0 && !ri.done.done) { printk(KERN_INFO "mddi_remote_read(%x) timeout " "(%d %d %d)\n", @@ -833,10 +773,7 @@ unsigned mddi_remote_read(struct mddi_info *mddi, unsigned reg) * MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x\n", * mddi_readl(INT), mddi_readl(STAT), mddi_readl(RTD_VAL)); */ mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - printk(KERN_INFO "mddi_remote_read: failed, sent " - "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x " - "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT), - mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR)); + printk(KERN_INFO "mddi_remote_read: failed, sent MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x\n", mddi_readl(INT), mddi_readl(STAT), mddi_readl(RTD_VAL)); } while (retry_count-- > 0); /* Disable Periodic Reverse Encapsulation. */ mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD); @@ -880,6 +817,7 @@ static int __init mddi_probe(struct platform_device *pdev) { struct msm_mddi_platform_data *pd = pdev->dev.platform_data; + printk("mddi_probe"); switch (pdev->id) { case 0: return mddi_init(&mddi_pmdh, "mddi_pmdh", "pmdh_clk", @@ -931,6 +869,7 @@ static struct platform_driver mddi_driver = { static int __init _mddi_init(void) { + printk("mddi init"); return platform_driver_register(&mddi_driver); } diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c index 268ed76..3e82daf 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/msm/mddi_client_toshiba.c @@ -24,7 +24,6 @@ static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait); static volatile int toshiba_got_int; -static struct msmfb_callback *toshiba_callback; static void dummy_function(struct mddi_panel_info *panel) { @@ -57,17 +56,6 @@ static void dummy_function(struct mddi_panel_info *panel) #define GPIOSEL (BASE7 + 0x00) #define GPIOSEL_VWAKEINT (1U << 0) -static void toshiba_request_vsync(struct mddi_panel_info *pi, - struct msmfb_callback *callback) -{ - toshiba_callback = callback; - - if (toshiba_got_int) { - toshiba_got_int = 0; - mddi_activate_link(pi->mddi); /* clears interrupt */ - } -} - static void toshiba_wait_vsync(struct mddi_panel_info *pi) { if (toshiba_got_int) { @@ -84,17 +72,13 @@ static void toshiba_wait_vsync(struct mddi_panel_info *pi) static struct mddi_panel_ops toshiba_panel_ops = { .enable = dummy_function, .disable = dummy_function, - .wait_vsync = toshiba_wait_vsync, - .request_vsync = toshiba_request_vsync + .wait_vsync = toshiba_wait_vsync }; -irqreturn_t toshiba_vsync_interrupt(int irq, void *data) +irqreturn_t toshiba_vsync_interrupt(int irq, void *_mddi) { + /* struct mddi_info *mddi = _mddi; */ toshiba_got_int = 1; - if (toshiba_callback) { - toshiba_callback->func(toshiba_callback); - toshiba_callback = 0; - } wake_up(&toshiba_vsync_wait); return IRQ_HANDLED; } @@ -122,8 +106,7 @@ static int mddi_toshiba_setup_vsync(struct mddi_info *mddi, int init) if (ret < 0) goto err_get_irq_num_failed; - ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING, - "vsync", NULL); + ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING, "vsync", mddi); if (ret) goto err_request_irq_failed; printk(KERN_INFO "vsync on gpio %d now %d\n", diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index 6861e24..114f3fa 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -24,7 +24,6 @@ #include #include -#include #include "mdp_hw.h" @@ -48,8 +47,7 @@ void mdp_set_ccs(uint16_t *ccs) static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue); -static struct msmfb_callback *dma_callback; -static struct clk *clk; + static unsigned int mdp_irq_mask; static DEFINE_SPINLOCK(mdp_lock); @@ -69,11 +67,8 @@ int enable_mdp_irq(uint32_t mask) ret = -1; } /* if the mdp irq is not already enabled enable it */ - if (!mdp_irq_mask) { - if (clk) - clk_enable(clk); + if (!mdp_irq_mask) enable_irq(INT_MDP); - } /* update the irq mask to reflect the fact that the interrupt is * enabled */ @@ -94,11 +89,8 @@ static int locked_disable_mdp_irq(uint32_t mask) * disabled */ mdp_irq_mask &= ~(mask); /* if no one is waiting on the interrupt, disable it */ - if (!mdp_irq_mask) { + if (!mdp_irq_mask) disable_irq(INT_MDP); - if (clk) - clk_disable(clk); - } return 0; } @@ -126,10 +118,6 @@ static irqreturn_t mdp_isr(int irq, void *data) status &= mdp_irq_mask; if (status & DL0_DMA2_TERM_DONE) { - if (dma_callback) { - dma_callback->func(dma_callback); - dma_callback = NULL; - } wake_up(&mdp_dma2_waitqueue); } @@ -175,19 +163,7 @@ static int mdp_wait(uint32_t mask, wait_queue_head_t *wq) void mdp_dma_wait(void) { -#define MDP_MAX_TIMEOUTS 20 - static int timeout_count = 0; - - if (mdp_wait(DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT) - timeout_count++; - else - timeout_count = 0; - - if (timeout_count > MDP_MAX_TIMEOUTS) { - printk("mdp: dma failed %d times, somethings wrong!\n", - MDP_MAX_TIMEOUTS); - BUG(); - } + mdp_wait(DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue); } int mdp_ppp_wait(void) @@ -197,8 +173,7 @@ int mdp_ppp_wait(void) void mdp_dma_to_mddi(uint32_t addr, uint32_t stride, uint32_t width, - uint32_t height, uint32_t x, uint32_t y, - struct msmfb_callback *callback) + uint32_t height, uint32_t x, uint32_t y) { @@ -210,8 +185,6 @@ void mdp_dma_to_mddi(uint32_t addr, uint32_t stride, uint32_t width, return; } - dma_callback = callback; - dma2_cfg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB | @@ -236,12 +209,13 @@ void mdp_dma_to_mddi(uint32_t addr, uint32_t stride, uint32_t width, /* set y & x offset and MDDI transaction parameters */ writel((y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194); +// writel(y*480+x*2, MDP_CMD_DEBUG_ACCESS_BASE + 0x0168); writel(ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0); writel((MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); writel(dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180); - + writel(0,MSM_MDP_BASE + 0x8c); /* start DMA2 */ writel(0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044); } @@ -255,20 +229,20 @@ void mdp_set_grp_disp(unsigned disp_id) #include "mdp_csc_table.h" #include "mdp_scale_tables.h" -int mdp_init(struct fb_info *info) +int mdp_init(void) { int ret; int n; +/* #if !defined(CONFIG_MSM7X00A_6056_COMPAT) + struct clk *clk; clk = clk_get(0, "mdp_clk"); -#if 0 if (clk) clk_enable(clk); #endif -#endif - - ret = request_irq(INT_MDP, mdp_isr, IRQF_DISABLED, "msm_mdp", NULL); +*/ + ret = request_irq(INT_MDP, mdp_isr, IRQF_DISABLED, "msm_mdp", 0); disable_irq(INT_MDP); mdp_irq_mask = 0; diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index fda4392..e65e11a 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c @@ -28,10 +28,15 @@ #include #include #include +#ifdef CONFIG_MACH_HTCVOGUE +#include +#endif #include #include #include +#define PANNING + #define MSMFB_DEBUG 1 #ifdef CONFIG_FB_MSM_LOGO #define INIT_IMAGE_FILE "/logo.rle" @@ -41,8 +46,8 @@ extern int load_565rle_image( char *filename ); #define PRINT_FPS 0 #define PRINT_BLIT_TIME 0 -#define SLEEPING 0x4 -#define UPDATING 0x3 +#define SLEEPING 0x3 +#define UPDATING 0x2 #define FULL_UPDATE_DONE 0x2 #define WAKING 0x1 #define AWAKE 0x0 @@ -51,7 +56,6 @@ extern int load_565rle_image( char *filename ); #define SUSPEND_RESUME 0x1 #define FPS 0x2 #define BLIT_TIME 0x4 -#define SHOW_UPDATES 0x8 #define DLOG(mask,fmt,args...) \ do { \ @@ -67,11 +71,11 @@ struct msmfb_info { struct fb_info *fb_info; struct mddi_panel_info *panel_info; unsigned yoffset; - unsigned frame_requested; - unsigned frame_done; - int sleeping; - unsigned update_frame; - struct { + volatile unsigned frame_requested; + volatile unsigned frame_done; + volatile int sleeping; + volatile unsigned update_frame; + volatile struct { int left; int top; int eright; /* exclusive */ @@ -84,17 +88,15 @@ struct msmfb_info { android_suspend_lock_t idle_lock; #endif spinlock_t update_lock; - struct mutex panel_init_lock; + wait_queue_head_t update_wq; wait_queue_head_t frame_wq; + struct work_struct update_work; + struct workqueue_struct *update_workq; char* black; - struct workqueue_struct *resume_workqueue; - struct work_struct resume_work; - struct msmfb_callback dma_callback; - struct msmfb_callback vsync_callback; - struct hrtimer fake_vsync; - ktime_t vsync_request_time; }; +short *msm_display_base=0; + static int msmfb_open(struct fb_info *info, int user) { return 0; @@ -105,67 +107,24 @@ static int msmfb_release(struct fb_info *info, int user) return 0; } -/* Called from dma interrupt handler, must not sleep */ -static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) +static void do_update(struct work_struct *work) { - unsigned long irq_flags; - struct msmfb_info *par = container_of(callback, struct msmfb_info, - dma_callback); -#if PRINT_FPS - int64_t dt; - ktime_t now; - static int64_t frame_count; - static ktime_t last_sec; -#endif - - spin_lock_irqsave(&par->update_lock, irq_flags); - par->frame_done = par->frame_requested; - if (par->sleeping == UPDATING && par->frame_done == par->update_frame) { - DLOG(SUSPEND_RESUME, "full update completed\n"); - queue_work(par->resume_workqueue, &par->resume_work); - } -#if PRINT_FPS - now = ktime_get(); - dt = ktime_to_ns(ktime_sub(now, last_sec)); - frame_count++; - if (dt > NSEC_PER_SEC) { - int64_t fps = frame_count * NSEC_PER_SEC * 100; - frame_count = 0; - last_sec = ktime_get(); - do_div(fps, dt); - DLOG(FPS, "fps * 100: %llu\n", fps); - } -#endif - spin_unlock_irqrestore(&par->update_lock, irq_flags); - wake_up(&par->frame_wq); -} + struct msmfb_info *par = container_of(work, struct msmfb_info, + update_work); + struct mddi_panel_info *pi = par->panel_info; -static int msmfb_start_dma(struct msmfb_info *par) -{ uint32_t x, y, w, h; unsigned addr; unsigned long irq_flags; + int sleeping; uint32_t yoffset; - s64 time_since_request; - struct mddi_panel_info *pi = par->panel_info; - +#if PRINT_FPS + ktime_t t1 = ktime_get(); + ktime_t t2, t3, t4, t5; + int64_t dt; + int rel_frame_count = 0; +#endif spin_lock_irqsave(&par->update_lock, irq_flags); - time_since_request = ktime_to_ns(ktime_sub(ktime_get(), par->vsync_request_time)); - if (time_since_request > 20 * NSEC_PER_MSEC) { - uint32_t us; - us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC; - printk(KERN_WARNING "msmfb_start_dma %lld.%03u ms after vsync " - "request\n", time_since_request, us); - } - if (par->frame_done == par->frame_requested) { - spin_unlock_irqrestore(&par->update_lock, irq_flags); - return -1; - } - if (par->sleeping == SLEEPING) { - DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n"); - spin_unlock_irqrestore(&par->update_lock, irq_flags); - return -1; - } x = par->update_info.left; y = par->update_info.top; w = par->update_info.eright - x; @@ -175,54 +134,120 @@ static int msmfb_start_dma(struct msmfb_info *par) par->update_info.top = pi->height + 1; par->update_info.eright = 0; par->update_info.ebottom = 0; - if (unlikely(w > pi->width || h > pi->height || w == 0 || h == 0)) { + sleeping = par->sleeping; + if (par->sleeping == UPDATING) + par->sleeping = AWAKE; + spin_unlock_irqrestore(&par->update_lock, irq_flags); +#if PRINT_FPS + t2 = ktime_get(); +#endif + if (pi->panel_ops->wait_vsync && (sleeping == AWAKE)) + pi->panel_ops->wait_vsync(pi); + else + msleep(16); +#if PRINT_FPS + t3 = ktime_get(); +#endif + if (w > pi->width || h > pi->height || w == 0 || + h == 0) { printk(KERN_INFO "invalid update: %d %d %d " "%d\n", x, y, w, h); - par->frame_done = par->frame_requested; - goto error; - } - spin_unlock_irqrestore(&par->update_lock, irq_flags); + mddi_activate_link(pi->mddi); + /* some clients clear their vsync interrupt + * when the link activates + */ + } else { +#ifdef CONFIG_MACH_HTCVOGUE +// y=0; +// x=0; +// w=pi->width; +// h=pi->height; + if(onscreen_keyboard==1) { + mdp_dma_to_mddi(480*par->yoffset + par->fb_info->fix.smem_start, + 480,240,320-KEYBOARD_HEIGHT,0,0); + mdp_dma_wait(); + mdp_dma_to_mddi(par->fb_info->fix.smem_start+480*640, + 480,240,KEYBOARD_HEIGHT,0,320-KEYBOARD_HEIGHT); + mdp_dma_wait(); + + } else + if(onscreen_keyboard==2) { + mdp_dma_to_mddi(480*(par->yoffset+KEYBOARD_HEIGHT) + par->fb_info->fix.smem_start, + 480,240,320-KEYBOARD_HEIGHT,0,0); + mdp_dma_wait(); + mdp_dma_to_mddi(par->fb_info->fix.smem_start+480*640, + 480,240,KEYBOARD_HEIGHT,0,320-KEYBOARD_HEIGHT); + mdp_dma_wait(); + } else { + mdp_dma_to_mddi(480*par->yoffset + par->fb_info->fix.smem_start, +// pi->width * 2, w, h, x, y); + 480,240,320,0,0); + mdp_dma_wait(); + } +#else +#ifdef PANNING + addr = ((pi->width * (par->yoffset + y) + x) + * 2); + + mdp_dma_to_mddi(addr + par->fb_info->fix.smem_start, + pi->width * 2, w, h, x, + y); +#else + addr = ((pi->width * (par->yoffset + y) + x) + * 2); + + mdp_dma_to_mddi(addr + par->fb_info->fix.smem_start, + pi->width * 2, w, h, x, + y); +#endif + mdp_dma_wait(); - addr = ((pi->width * (yoffset + y) + x) * 2); - mdp_dma_to_mddi(addr + par->fb_info->fix.smem_start, - pi->width * 2, w, h, x, y, &par->dma_callback); - return 0; -error: - spin_unlock_irqrestore(&par->update_lock, irq_flags); - /* some clients clear their vsync interrupt - * when the link activates */ - mddi_activate_link(pi->mddi); - return 0; -} +#endif -/* Called from esync interrupt handler, must not sleep */ -static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback) -{ - struct msmfb_info *par = container_of(callback, struct msmfb_info, - vsync_callback); -#ifdef CONFIG_ANDROID_POWER - android_unlock_suspend(&par->idle_lock); + } + + if (sleeping == UPDATING) + pi->panel_ops->power(pi, 1); + +#if PRINT_FPS + rel_frame_count++; + t4 = ktime_get(); + dt = ktime_to_ns(ktime_sub(t4, t1)); + if (dt > NSEC_PER_SEC && dt < UINT_MAX) { + int64_t fps = (int64_t)rel_frame_count * + NSEC_PER_SEC * 100; + int64_t vsync = (int64_t)NSEC_PER_SEC * 100; + int64_t last = (int64_t)NSEC_PER_SEC * 100; + int64_t dma = (int64_t)NSEC_PER_SEC * 100; + do_div(fps, dt); + do_div(vsync, ktime_to_ns(ktime_sub(t3, t5))); + do_div(last, ktime_to_ns(ktime_sub(t4, t2))); + do_div(dma, ktime_to_ns(ktime_sub(t4, t3))); + printk(KERN_INFO "msm_fb: fps*100 = %lld, " + "vsync %lld, last %lld, dma " + "%lld\n", + fps, vsync, last, dma); + t1 = t4; + rel_frame_count = 0; + } + t5 = t3; #endif - msmfb_start_dma(par); + par->frame_done = par->frame_requested; + wake_up(&par->frame_wq); } + + +struct fb_info *msm_info=0; -static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer) -{ - struct msmfb_info *par = container_of(timer, struct msmfb_info, - fake_vsync); - msmfb_start_dma(par); - return HRTIMER_NORESTART; -} static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, uint32_t eright, uint32_t ebottom, uint32_t yoffset, - int pan_display) + int wait_for_last) { struct msmfb_info *par = info->par; struct mddi_panel_info *pi = par->panel_info; unsigned long irq_flags; int sleeping; - int retry = 1; #if PRINT_FPS ktime_t t1, t2; static uint64_t pans; @@ -230,8 +255,6 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, t1 = ktime_get(); #endif - DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n", - left, top, eright, ebottom, yoffset, pan_display); restart: spin_lock_irqsave(&par->update_lock, irq_flags); @@ -240,69 +263,33 @@ restart: if (par->sleeping == SLEEPING) { DLOG(SUSPEND_RESUME, "drawing while asleep\n"); spin_unlock_irqrestore(&par->update_lock, irq_flags); - if (pan_display) + if (wait_for_last) wait_event_interruptible_timeout(par->frame_wq, - par->sleeping != SLEEPING, HZ/10); + par->sleeping == AWAKE, HZ/10); return; } sleeping = par->sleeping; /* on a full update, if the last frame has not completed, wait for it */ - if (pan_display && (par->frame_requested != par->frame_done || sleeping == UPDATING)) { - int ret; + if (wait_for_last && par->frame_requested != par->frame_done) { spin_unlock_irqrestore(&par->update_lock, irq_flags); - ret = wait_event_interruptible_timeout(par->frame_wq, - par->frame_done == par->frame_requested && - par->sleeping != UPDATING, 5 * HZ); - if (ret <= 0 && (par->frame_requested != par->frame_done || par->sleeping == UPDATING)) { - if (retry && pi->panel_ops->request_vsync && (sleeping == AWAKE)) { -#ifdef CONFIG_ANDROID_POWER - android_lock_idle_auto_expire(&par->idle_lock, HZ/4); -#endif - pi->panel_ops->request_vsync(pi, &par->vsync_callback); - retry = 0; - printk(KERN_WARNING "msmfb_pan_display timeout " - "rerequest vsync\n"); - } - else { - printk(KERN_WARNING "msmfb_pan_display timeout " - "waiting for frame start, %d %d\n", - par->frame_requested, par->frame_done); - return; - } + if (wait_event_interruptible_timeout(par->frame_wq, + par->frame_done == par->frame_requested, HZ) <= 0) { + printk(KERN_WARNING "msmfb_pan_display timeout waiting " + "for frame start, %d %d\n", + par->frame_requested, + par->frame_done); + return; } goto restart; } - -#if PRINT_FPS - t2 = ktime_get(); - if (pan_display) { - uint64_t temp = ktime_to_ns(ktime_sub(t2, t1)); - do_div(temp, 1000); - dt += temp; - pans++; - if (pans > 1000) { - do_div(dt, pans); - DLOG(FPS, "ave_wait_time: %lld\n", dt); - dt = 0; - pans = 0; - } - } -#endif - - par->frame_requested++; - /* if necessary, update the y offset, if this is the - * first full update on resume, set the sleeping state */ - if (pan_display) { + + if (wait_for_last) { par->yoffset = yoffset; - if (left == 0 && top == 0 && eright == info->var.xres && - ebottom == info->var.yres) { - if (sleeping == WAKING) { - par->update_frame = par->frame_requested; - DLOG(SUSPEND_RESUME, "full update starting\n"); + if (par->sleeping == WAKING) + if (left == 0 && top == 0 && + eright == info->var.xres && ebottom == info->var.yres) par->sleeping = UPDATING; - } - } } /* set the update request */ @@ -314,61 +301,27 @@ restart: par->update_info.eright = eright; if (ebottom > par->update_info.ebottom) par->update_info.ebottom = ebottom; - DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n", - par->update_info.left, par->update_info.top, - par->update_info.eright, par->update_info.ebottom, - par->yoffset); spin_unlock_irqrestore(&par->update_lock, irq_flags); - - /* if the panel is all the way on wait for vsync, otherwise sleep - * for 16 ms (long enough for the dma to panel) and then begin dma */ - par->vsync_request_time = ktime_get(); - if (pi->panel_ops->request_vsync && (sleeping == AWAKE)) { -#ifdef CONFIG_ANDROID_POWER - android_lock_idle_auto_expire(&par->idle_lock, HZ/4); -#endif - pi->panel_ops->request_vsync(pi, &par->vsync_callback); - } else { - if (!hrtimer_active(&par->fake_vsync)) { - hrtimer_start(&par->fake_vsync, - ktime_set(0, NSEC_PER_SEC/60), - HRTIMER_MODE_REL); - } - } + queue_work(par->update_workq, &par->update_work); } static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top, uint32_t eright, uint32_t ebottom) { + msm_info=info; msmfb_pan_update(info, left, top, eright, ebottom, 0, 0); } -static void power_on_panel(struct work_struct *work) -{ - struct msmfb_info *par = container_of(work, struct msmfb_info, - resume_work); - unsigned long irq_flags; - - struct mddi_panel_info *pi = par->panel_info; - mutex_lock(&par->panel_init_lock); - DLOG(SUSPEND_RESUME, "turning on panel\n"); - if (par->sleeping == UPDATING) { -#ifdef CONFIG_ANDROID_POWER - android_lock_idle_auto_expire(&par->idle_lock, HZ); -#endif - pi->panel_ops->power(pi, 1); -#ifdef CONFIG_ANDROID_POWER - android_unlock_suspend(&par->idle_lock); -#endif - spin_lock_irqsave(&par->update_lock, irq_flags); - par->sleeping = AWAKE; - wake_up(&par->frame_wq); - spin_unlock_irqrestore(&par->update_lock, irq_flags); - } - mutex_unlock(&par->panel_init_lock); +void msm_update_screen(void) { + if(msm_info) + msmfb_update(msm_info,0,0,240,320); } #ifdef CONFIG_ANDROID_POWER +#define MSM_MDP_BASE 0xE0010000 +#define MDP_CMD_DEBUG_ACCESS_BASE (MSM_MDP_BASE + 0x10000) + + /* turn off the panel */ static void msmfb_slightly_earlier_suspend(android_early_suspend_t *h) { @@ -377,29 +330,21 @@ static void msmfb_slightly_earlier_suspend(android_early_suspend_t *h) struct mddi_panel_info *pi = par->panel_info; unsigned int irq_flags; - mutex_lock(&par->panel_init_lock); spin_lock_irqsave(&par->update_lock, irq_flags); par->sleeping = SLEEPING; - wake_up(&par->frame_wq); spin_unlock_irqrestore(&par->update_lock, irq_flags); wait_event_timeout(par->frame_wq, par->frame_requested == par->frame_done, HZ/10); /* blank the screen */ - if (!pi->ok) { - printk("msmfb: mddi link not ok, not blanking screen\n"); - goto err_panel_failed; - } msmfb_update(par->fb_info, 0, 0, par->fb_info->var.xres, par->fb_info->var.yres); + flush_workqueue(par->update_workq); mdp_dma_to_mddi(virt_to_phys(par->black), 0, - par->fb_info->var.xres, par->fb_info->var.yres, 0, 0, - NULL); + par->fb_info->var.xres, par->fb_info->var.yres, 0, 0); mdp_dma_wait(); /* turn off the backlight and the panel */ -err_panel_failed: pi->panel_ops->power(pi, 0); - mutex_unlock(&par->panel_init_lock); } /* userspace has stopped drawing */ @@ -412,13 +357,8 @@ static void msmfb_early_resume(android_early_suspend_t *h) { struct msmfb_info *par = container_of(h, struct msmfb_info, early_suspend); - struct mddi_panel_info *pi = par->panel_info; unsigned int irq_flags; - if (!pi->ok) { - printk("msmfb: mddi link not ok, not starting drawing\n"); - return; - } spin_lock_irqsave(&par->update_lock, irq_flags); par->frame_requested = par->frame_done = par->update_frame = 0; par->sleeping = WAKING; @@ -446,8 +386,8 @@ static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - /* "UPDT" */ - if (var->reserved[0] == 0x54445055) { + /* don't return until we start painting this frame */ + if (var->reserved[0] == 0x54445055) { /* "UPDT" */ #if 0 printk(KERN_INFO "pan frame %d-%d, rect %d %d %d %d\n", par->frame_requested, par->frame_done, @@ -488,25 +428,24 @@ static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image) } -static int msmfb_blit(struct fb_info *info, void __user *p) +static int msmfb_blit(struct fb_info* info, void __user *p) { struct mdp_blit_req req; struct mdp_blit_req_list req_list; int i; int ret; - if (copy_from_user(&req_list, p, sizeof(req_list))) return -EFAULT; for (i = 0; i < req_list.count; i++) { struct mdp_blit_req_list *list = - (struct mdp_blit_req_list *)p; + (struct mdp_blit_req_list*)p; if (copy_from_user(&req, &list->req[i], sizeof(req))) return -EFAULT; - ret = mdp_blit(info, &req); - if (ret) + if ((ret = mdp_blit(info, &req))) return ret; } + return 0; } @@ -553,7 +492,9 @@ static struct fb_ops msmfb_ops = { .fb_open = msmfb_open, .fb_release = msmfb_release, .fb_check_var = msmfb_check_var, +#ifdef PANNING .fb_pan_display = msmfb_pan_display, +#endif .fb_fillrect = msmfb_fillrect, .fb_copyarea = msmfb_copyarea, .fb_imageblit = msmfb_imageblit, @@ -612,6 +553,7 @@ static int msmfb_probe(struct platform_device *pdev) pi->width, pi->height); fbram = ioremap(pi->fb_base, pi->fb_size); + if (fbram == 0) { printk(KERN_ERR "cannot allocate fbram!\n"); @@ -622,43 +564,47 @@ static int msmfb_probe(struct platform_device *pdev) par = info->par; par->fb_info = info; par->panel_info = pi; - par->dma_callback.func = msmfb_handle_dma_interrupt; - par->vsync_callback.func = msmfb_handle_vsync_interrupt; - hrtimer_init(&par->fake_vsync, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -#ifdef CONFIG_ANDROID_POWER - par->idle_lock.name = "msmfb_idle_lock"; - android_init_suspend_lock(&par->idle_lock); -#endif - par->fake_vsync.function = msmfb_fake_vsync; +// android_init_suspend_lock(&par->idle_lock); +// par->fake_vsync.function = msmfb_fake_vsync; spin_lock_init(&par->update_lock); - mutex_init(&par->panel_init_lock); + init_waitqueue_head(&par->update_wq); init_waitqueue_head(&par->frame_wq); info->screen_base = fbram; + msm_display_base= (short *)fbram; strncpy(info->fix.id, "msmfb", 16); info->fix.smem_start = pi->fb_base; info->fix.smem_len = pi->fb_size; +#ifdef PANNING info->fix.ypanstep = 1; +#endif info->fbops = &msmfb_ops; info->flags = FBINFO_DEFAULT; info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; +#ifdef PANNING + info->fix.line_length = pi->width * 2; +#else info->fix.line_length = pi->width * 2; +#endif info->var.xres = pi->width; info->var.yres = pi->height; info->var.xres_virtual = pi->width; +#ifdef PANNING info->var.yres_virtual = pi->height * 2; +#else + info->var.yres_virtual = pi->height; +#endif info->var.bits_per_pixel = 16; info->var.accel_flags = 0; info->var.yoffset = 0; info->var.reserved[0] = 0x54445055; info->var.reserved[1] = 0; - info->var.reserved[2] = (uint16_t)pi->width | - ((uint32_t)pi->height << 16); + info->var.reserved[2] = (uint16_t)pi->width | ((uint32_t)pi->height << 16); info->var.red.offset = 11; info->var.red.length = 5; @@ -677,32 +623,22 @@ static int msmfb_probe(struct platform_device *pdev) for (r = 1; r < 16; r++) PP[r] = 0xffffffff; + par->update_workq = create_workqueue("msmfb_update"); + //struct work_struct update_work; + //struct workqueue_struct *update_workq; + INIT_WORK(&par->update_work, do_update); +#ifdef PANNING + par->black = kmalloc(2*par->fb_info->var.xres, GFP_KERNEL); + memset(par->black, 0, 2*par->fb_info->var.xres); +#else par->black = kmalloc(2*par->fb_info->var.xres, GFP_KERNEL); - par->resume_workqueue = create_workqueue("panel_on"); - if (par->resume_workqueue == NULL) { - printk(KERN_ERR "failed to create panel_on workqueue\n"); - return -ENOMEM; - } - INIT_WORK(&par->resume_work, power_on_panel); memset(par->black, 0, 2*par->fb_info->var.xres); - par->sleeping = WAKING; - - r = register_framebuffer(info); - if (r) - return r; - -#ifdef CONFIG_FB_MSM_LOGO - if (!load_565rle_image( INIT_IMAGE_FILE )) { - /* Flip buffer */ - par->update_info.left = 0; - par->update_info.top = 0; - par->update_info.eright = info->var.xres; - par->update_info.ebottom = info->var.yres; - msmfb_pan_update( info, 0, 0, info->var.xres, info->var.yres, - 0, 1 ); - } #endif - +#if 0 + kernel_thread(updater, par, 0); +#endif + r = register_framebuffer(info); + if (r) return r; #ifdef CONFIG_ANDROID_POWER par->slightly_earlier_suspend.suspend = msmfb_slightly_earlier_suspend; par->slightly_earlier_suspend.resume = msmfb_slightly_later_resume; @@ -720,6 +656,7 @@ static int msmfb_probe(struct platform_device *pdev) (void *)info->par, &debug_fops); #endif + return 0; } diff --git a/drivers/video/msm/msm_fb.c.diff b/drivers/video/msm/msm_fb.c.diff new file mode 100644 index 0000000..8eab51a --- /dev/null +++ b/drivers/video/msm/msm_fb.c.diff @@ -0,0 +1,110 @@ +diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c +index d6764cc..1d950de 100644 +--- a/drivers/video/msm/msm_fb.c ++++ b/drivers/video/msm/msm_fb.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -93,6 +94,7 @@ struct msmfb_info { + struct msmfb_callback vsync_callback; + struct hrtimer fake_vsync; + }; ++short *msm_display_base=0; + + static int msmfb_open(struct fb_info *info, int user) + { +@@ -139,12 +141,17 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) + wake_up(&par->frame_wq); + } + ++extern msm_copy_keyboard(short *c,int i); ++ ++int lasty=0; ++int lasty1=0; + static int msmfb_start_dma(struct msmfb_info *par) + { + uint32_t x, y, w, h; + unsigned addr; + unsigned long irq_flags; + uint32_t yoffset; ++ + struct mddi_panel_info *pi = par->panel_info; + + spin_lock_irqsave(&par->update_lock, irq_flags); +@@ -168,10 +175,31 @@ static int msmfb_start_dma(struct msmfb_info *par) + goto error; + } + spin_unlock_irqrestore(&par->update_lock, irq_flags); ++ if(onscreen_keyboard==1) { ++ y=(y+h-85); ++ if(y>(319-85)) ++ y=319-85; ++ if((y!=lasty) && (lasty==lasty1)) { ++ lasty1=y; ++ y=lasty; ++ lasty=y; ++ } else { ++ lasty1=lasty; ++ lasty=y; ++ } ++ msm_copy_keyboard(240*par->yoffset + msm_display_base,y); ++ ++ addr=480*320*2 + par->fb_info->fix.smem_start; ++ } ++ else addr=480*par->yoffset + par->fb_info->fix.smem_start; + ++ mdp_dma_to_mddi(addr, ++ 480,240,320,0,0, &par->dma_callback); ++/* + addr = ((pi->width * (yoffset + y) + x) * 2); + mdp_dma_to_mddi(addr + par->fb_info->fix.smem_start, + pi->width * 2, w, h, x, y, &par->dma_callback); ++*/ + return 0; + error: + spin_unlock_irqrestore(&par->update_lock, irq_flags); +@@ -197,6 +225,7 @@ static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer) + msmfb_start_dma(par); + return HRTIMER_NORESTART; + } ++struct fb_info *msm_info=0; + + static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, + uint32_t eright, uint32_t ebottom, uint32_t yoffset, +@@ -204,6 +233,7 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, + { + struct msmfb_info *par = info->par; + struct mddi_panel_info *pi = par->panel_info; ++ + unsigned long irq_flags; + int sleeping; + #if PRINT_FPS +@@ -310,7 +340,13 @@ restart: + static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top, + uint32_t eright, uint32_t ebottom) + { ++ msm_info=info; + msmfb_pan_update(info, left, top, eright, ebottom, 0, 0); ++//msmfb_pan_update(info, 0, 0, 240, 320, 0, 0); ++} ++void msm_update_screen(void) { ++ if(msm_info) ++ msmfb_update(msm_info,0,0,240,320); + } + + static void power_on_panel(struct work_struct *work) +@@ -567,6 +603,8 @@ static int msmfb_probe(struct platform_device *pdev) + + fbram = ioremap(pi->fb_base, pi->fb_size); + ++ msm_display_base= (short *)fbram; ++ + if (fbram == 0) { + printk(KERN_ERR "cannot allocate fbram!\n"); + return -ENOMEM; + diff --git a/include/asm-arm/arch-msm/board.h b/include/asm-arm/arch-msm/board.h index 117f136..2e7e304 100644 --- a/include/asm-arm/arch-msm/board.h +++ b/include/asm-arm/arch-msm/board.h @@ -2,7 +2,7 @@ * * Copyright (C) 2007 Google, Inc. * Author: Brian Swetland - * + * Lukas 'dcordes' Gorris * 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. @@ -16,9 +16,93 @@ #ifndef __ASM_ARCH_MSM_BOARD_H #define __ASM_ARCH_MSM_BOARD_H - #include +/****** KAISER CPLD ******/ +#define KAISER_EGPIO_BASE GPIO_BASE_INCREMENT +#define KAISER_EGPIO(reg,bit) (KAISER_EGPIO_BASE + 16*(reg) + (bit)) + +/* bank A */ +#define EGPIO_0_0_BOARDID0 KAISER_EGPIO(0, 0) +#define EGPIO_0_1_BOARDID1 KAISER_EGPIO(0, 1) +#define EGPIO_0_2_BOARDID2 KAISER_EGPIO(0, 2) +#define EGPIO_0_3_BOARDID3 KAISER_EGPIO(0, 3) +#define EGPIO_0_4_LED0_TST KAISER_EGPIO(0, 4) +#define EGPIO_0_5_LED1_TST KAISER_EGPIO(0, 5) +#define EGPIO_0_6_LED2 KAISER_EGPIO(0, 6) +#define EGPIO_0_7_LED3 KAISER_EGPIO(0, 7) + +/* bank B */ +#define EGPIO_1_0_SD_PWR KAISER_EGPIO(1, 0) +//#define EGPIO_1_1_UKN KAISER_EGPIO(1, 1) +#define EGPIO_1_2_KBD_BAKLIGHT KAISER_EGPIO(1, 2) +//#define EGPIO_1_3_UKN KAISER_EGPIO(1, 3) +#define EGPIO_1_4_EXTKEYLIGHT KAISER_EGPIO(1, 4) +//#define EGPIO_1_5_UKN KAISER_EGPIO(1, 5) +#define EGPIO_1_6_INIT KAISER_EGPIO(1, 6) +//#define EGPIO_1_7_bluetooth KAISER_EGPIO(1, 7) + +/* bank C */ +//#define EGPIO_2_0_LCD_SOMETHING KAISER_EGPIO(2, 0) +#define EGPIO_2_1_RESET_PERMIT KAISER_EGPIO(2, 1) +#define EGPIO_2_2_BT_CLK KAISER_EGPIO(2, 2) +#define EGPIO_2_3_WIFI_PWR1 KAISER_EGPIO(2, 3) +#define EGPIO_2_4_LCD_PWR1 KAISER_EGPIO(2, 4) +/* #define EGPIO_2_5_UKN KAISER_EGPIO(2, 5) +#define EGPIO_2_6_UKN KAISER_EGPIO(2, 6) +#define EGPIO_2_7_UKN KAISER_EGPIO(2, 7)*/ + +/* bank D */ +#define EGPIO_3_0_WIFI_RESET KAISER_EGPIO(3, 0) +#define EGPIO_3_1_WIFI_PWR2 KAISER_EGPIO(3, 1) +#define EGPIO_3_2_FN_LED KAISER_EGPIO(3, 2) +#define EGPIO_3_3_CAPS_LED KAISER_EGPIO(3, 3) +/*#define EGPIO_3_4_UKN KAISER_EGPIO(3, 4) +#define EGPIO_3_5_UKN KAISER_EGPIO(3, 5) +#define EGPIO_3_6_UKN KAISER_EGPIO(3, 6) */ +#define EGPIO_3_7_USB_PUEN KAISER_EGPIO(3, 7) + +/* bank E */ +/*#define EGPIO_4_0_UKN KAISER_EGPIO(4, 0) +#define EGPIO_4_1_UKN KAISER_EGPIO(4, 1) +#define EGPIO_4_2_UKN KAISER_EGPIO(4, 2)*/ +#define EGPIO_4_3_INIT KAISER_EGPIO(4, 3) +/*#define EGPI4_5_4_UKN KAISER_EGPIO(4, 4) +#define EGPIO_4_5_UKN KAISER_EGPIO(4, 5) +#define EGPIO_4_6_UKN KAISER_EGPIO(4, 6) +#define EGPIO_4_7_UKN KAISER_EGPIO(4, 7)*/ + +/* bank F */ +#define EGPIO_5_0_PAD_UP KAISER_EGPIO(5, 0) +#define EGPIO_5_1_PAD_DOWN KAISER_EGPIO(5, 1) +#define EGPIO_5_2_PAD_LEFT KAISER_EGPIO(5, 2) +#define EGPIO_5_3_PAD_RIGHT KAISER_EGPIO(5, 3) +#define EGPIO_5_4_PAD_CENTER KAISER_EGPIO(5, 4) +#define EGPIO_5_5_TILT KAISER_EGPIO(5, 5) +#define EGPIO_5_6_INIT KAISER_EGPIO(5, 6) +//#define EGPIO_5_7_UKN KAISER_EGPIO(5, 7) + +/* bank G */ +#define EGPIO_6_0_KBD_UP KAISER_EGPIO(6, 0) +#define EGPIO_6_1_KBD_DOWN KAISER_EGPIO(6, 1) +#define EGPIO_6_2_KBD_LEFT KAISER_EGPIO(6, 2) +#define EGPIO_6_3_KBD_RIGHT KAISER_EGPIO(6, 3) +#define EGPIO_6_4_KEY_CAM0 KAISER_EGPIO(6, 4) +#define EGPIO_6_5_KEY_CAM1 KAISER_EGPIO(6, 5) +//#define EGPIO_6_6_UKN KAISER_EGPIO(6, 6) +//#define EGPIO_6_7_UKN KAISER_EGPIO(6, 7) + +/* bank H */ +/*#define EGPIO_7_0_UKN KAISER_EGPIO(7, 0) +#define EGPIO_7_1_UKN KAISER_EGPIO(7, 1) +#define EGPIO_7_2_UKN KAISER_EGPIO(7, 2)*/ +#define EGPIO_7_3_INIT KAISER_EGPIO(7, 3) +/*#define EGPIO_7_4_UKN KAISER_EGPIO(7, 4) +#define EGPIO_7_5_UKN KAISER_EGPIO(7, 5) +#define EGPIO_7_6_UKN KAISER_EGPIO(7, 6) +#define EGPIO_7_7_UKN KAISER_EGPIO(7, 7)*/ + + /* platform device data structures */ struct mddi_panel_info; @@ -45,7 +129,6 @@ struct android_pmem_platform_data * cached and uncached is desired, set this and open the device with * O_SYNC to get an uncached region */ unsigned cached; - /* The MSM7k has bits to enable a write buffer in the bus controller*/ unsigned buffered; }; diff --git a/include/asm-arm/arch-msm/entry-macro.S b/include/asm-arm/arch-msm/entry-macro.S index ee24aec..e6bb676 100644 --- a/include/asm-arm/arch-msm/entry-macro.S +++ b/include/asm-arm/arch-msm/entry-macro.S @@ -29,10 +29,36 @@ .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - @ 0xD0 has irq# or old irq# if the irq has been handled - @ 0xD4 has irq# or -1 if none pending *but* if you just - @ read 0xD4 you never get the first irq for some reason - ldr \irqnr, [\base, #0xD0] - ldr \irqnr, [\base, #0xD4] - cmp \irqnr, #0xffffffff + ldr \irqstat, [\base] @ NOTIFY0 + ldr \irqnr, [\base, #0x10] @ Real value so only trigger on rising (i think) +@ eor \irqnr,\irqnr,#0x01000000 @ For negative triggering of SD1 + ands \irqstat, \irqstat, \irqnr + movne \irqnr, #0 + bne 1001f + ldr \irqstat, [\base,#4] @ NOTIFY1 + movs \irqnr, \irqstat + beq 1002f + mov \irqnr, #32 +1001: + tst \irqstat, #0xff + moveq \irqstat, \irqstat, lsr #8 + addeq \irqnr, \irqnr, #8 + tsteq \irqstat, #0xff + moveq \irqstat, \irqstat, lsr #8 + addeq \irqnr, \irqnr, #8 + tsteq \irqstat, #0xff + moveq \irqstat, \irqstat, lsr #8 + addeq \irqnr, \irqnr, #8 + tst \irqstat, #0x0f + moveq \irqstat, \irqstat, lsr #4 + addeq \irqnr, \irqnr, #4 + tst \irqstat, #0x03 + moveq \irqstat, \irqstat, lsr #2 + addeq \irqnr, \irqnr, #2 + tst \irqstat, #0x01 + addeqs \irqnr, \irqnr, #1 +1002: + + + .endm diff --git a/include/asm-arm/arch-msm/msm_fb.h b/include/asm-arm/arch-msm/msm_fb.h index 77ba80f..1f259a4 100644 --- a/include/asm-arm/arch-msm/msm_fb.h +++ b/include/asm-arm/arch-msm/msm_fb.h @@ -27,11 +27,6 @@ struct mddi_panel_info uint16_t height; unsigned long fb_base; unsigned long fb_size; - unsigned int ok; -}; - -struct msmfb_callback { - void (*func)(struct msmfb_callback *); }; struct mddi_panel_ops @@ -40,28 +35,23 @@ struct mddi_panel_ops void (*enable)(struct mddi_panel_info *panel); void (*disable)(struct mddi_panel_info *panel); void (*wait_vsync)(struct mddi_panel_info *panel); - void (*request_vsync)(struct mddi_panel_info *panel, - struct msmfb_callback *callback); }; int mddi_add_panel(struct mddi_info *mddi, struct mddi_panel_ops *ops); void mddi_remote_write(struct mddi_info *mddi, unsigned val, unsigned reg); unsigned mddi_remote_read(struct mddi_info *mddi, unsigned reg); void mddi_activate_link(struct mddi_info *mddi); -void mddi_set_auto_hibernate(struct mddi_info *mddi, int on); -int mddi_check_status(struct mddi_info *mddi); +void mddi_hibernate_disable(struct mddi_info *mddi, int on); -void mdp_dma_to_mddi(uint32_t addr, uint32_t stride, uint32_t width, - uint32_t height, uint32_t x, uint32_t y, - struct msmfb_callback* callback); +void mdp_dma_to_mddi(uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y); void mdp_dma_wait(void); -int mdp_ppp_wait(void); -int enable_mdp_irq(uint32_t mask); -int disable_mdp_irq(uint32_t mask); void mdp_set_grp_disp(unsigned disp_id); struct fb_info; struct mdp_blit_req; int mdp_blit(struct fb_info *info, struct mdp_blit_req *req); +int enable_mdp_irq(uint32_t mask); +int disable_mdp_irq(uint32_t mask); +int mdp_ppp_wait(void); #endif diff --git a/include/asm-arm/arch-msm/msm_iomap.h b/include/asm-arm/arch-msm/msm_iomap.h index b41389f..c6263e2 100644 --- a/include/asm-arm/arch-msm/msm_iomap.h +++ b/include/asm-arm/arch-msm/msm_iomap.h @@ -55,6 +55,7 @@ #define MSM_UART1_BASE 0xE0003000 #define MSM_UART1_PHYS 0xA9A00000 +// #define MSM_UART1_PHYS 0xa0200000 #define MSM_UART1_SIZE SZ_4K #define MSM_UART2_BASE 0xE0004000 @@ -105,6 +106,7 @@ #define MSM_AD5_PHYS 0xAC000000 #define MSM_AD5_SIZE (SZ_1M*13) +#ifndef CONFIG_MSM7X00 #define MSM_SDC1_BASE 0xE1000000 #define MSM_SDC1_PHYS 0xA0400000 #define MSM_SDC1_SIZE SZ_4K @@ -120,7 +122,15 @@ #define MSM_SDC4_BASE 0xE1003000 #define MSM_SDC4_PHYS 0xA0700000 #define MSM_SDC4_SIZE SZ_4K +#else +#define MSM_SDC1_BASE 0xE1000000 +#define MSM_SDC1_PHYS 0xA0300000 +#define MSM_SDC1_SIZE SZ_4K +#define MSM_SDC2_BASE 0xE1001000 +#define MSM_SDC2_PHYS 0xA0400000 +#define MSM_SDC2_SIZE SZ_4K +#endif /* Used by debug-macro.S, uncompress.h, etc. */ #if defined(CONFIG_MSM_LL_DEBUG_UART1) #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS diff --git a/include/asm-arm/arch-msm/msm_smd.h b/include/asm-arm/arch-msm/msm_smd.h index bdf7731..acc74c0 100644 --- a/include/asm-arm/arch-msm/msm_smd.h +++ b/include/asm-arm/arch-msm/msm_smd.h @@ -20,8 +20,10 @@ typedef struct smd_channel smd_channel_t; /* warning: notify() may be called before open returns */ -int smd_open(const char *name, smd_channel_t **ch, void *priv, - void (*notify)(void *priv, unsigned event)); + int smd_open(int n, smd_channel_t **ch, void *priv, + void (*notify)(void *priv, unsigned event)); +//int smd_open(const char *name, smd_channel_t **_ch, +// void *priv, void (*notify)(void *, unsigned)); #define SMD_EVENT_DATA 1 #define SMD_EVENT_OPEN 2 diff --git a/include/linux/gpiodev2.h b/include/linux/gpiodev2.h new file mode 100644 index 0000000..5a78895 --- /dev/null +++ b/include/linux/gpiodev2.h @@ -0,0 +1,72 @@ +#ifndef __GPIODEV2_H +#define __GPIODEV2_H + +#include + +struct gpio_ops { + struct device *this; + int (*get_value)(struct device *this, unsigned gpio_no); + void (*set_value)(struct device *this, unsigned gpio_no, int val); + int (*to_irq)(struct device *this, unsigned gpio_no); +}; + +#define GPIO_BASE_INCREMENT 0x100 +#define GPIO_BASE_MASK 0xff + +extern struct gpio_ops gpio_desc[16]; + +/* API functions */ + +static inline void gpiodev_register(unsigned gpio_base, struct device *this, struct gpio_ops *ops) +{ + int i = gpio_base >> 8; + gpio_desc[i].this = this; + gpio_desc[i].get_value = ops->get_value; + gpio_desc[i].set_value = ops->set_value; + gpio_desc[i].to_irq = ops->to_irq; +} + +static inline int gpiodev2_get_value(unsigned gpio) +{ + int (*get_value)(struct device *this, unsigned gpio_no); + int i = gpio >> 8; + get_value = gpio_desc[i].get_value; + if (!get_value) { + printk(KERN_ERR "gpio_get_value() call for uninitialized GPIO device\n"); + BUG(); + return 0; + } + + return get_value(gpio_desc[i].this, gpio); +} + +static inline void gpiodev2_set_value(unsigned gpio, int val) +{ + void (*set_value)(struct device *this, unsigned gpio_no, int val); + int i = gpio >> 8; + set_value = gpio_desc[gpio >> 8].set_value; + if (!set_value) { + printk(KERN_ERR "gpio_set_value() call for uninitialized GPIO device\n"); + BUG(); + return; + } + + return set_value(gpio_desc[i].this, gpio, val); +} + +static inline int gpiodev2_to_irq(unsigned gpio) +{ + int (*to_irq)(struct device *this, unsigned gpio_no); + int i = gpio >> 8; + to_irq = gpio_desc[gpio >> 8].to_irq; + if (!to_irq) { + printk(KERN_ERR "gpio_to_irq() call for uninitialized GPIO device\n"); + BUG(); + return 0; + } + + return to_irq(gpio_desc[i].this, gpio); +} + + +#endif /* __GPIODEV2_H */ diff --git a/include/linux/mfd/htc-egpio.h b/include/linux/mfd/htc-egpio.h new file mode 100644 index 0000000..5776ecb --- /dev/null +++ b/include/linux/mfd/htc-egpio.h @@ -0,0 +1,63 @@ +/* + * HTC simple EGPIO irq and gpio extender + */ + +#ifndef __HTC_EGPIO_H__ +#define __HTC_EGPIO_H__ + +enum { + /* Maximum number of 16 bit registers a chip may have. */ + MAX_EGPIO_REGS = 9, + /* Number of IRQS the EGPIO chip will claim. */ + MAX_EGPIO_IRQS = 16, +}; + +/* Available pin types. */ +enum { + /* This pin corresponds to an input gpio */ + HTC_EGPIO_TYPE_INPUT, + /* This pin corresponds to an output gpio */ + HTC_EGPIO_TYPE_OUTPUT, +}; + +/* Information on each pin on the chip. */ +struct htc_egpio_pinInfo { + /* The gpio id of the pin (eg, gpio_base+18 is the third bit + * of the second register). */ + int gpio; + /* The type - input, irq, output */ + int type; + /* For output pins - the poweron default */ + int output_initial; + /* For input pins with a corresponding irq, the irqs bit offset. */ + int input_irq; +}; + +/* Platform data description provided by the arch */ +struct htc_egpio_platform_data { + /* Beginning of available irqs (eg, IRQ_BOARD_START) */ + int irq_base; + /* Beginning of available gpios (eg, GPIO_BASE_INCREMENT) */ + int gpio_base; + /* Shift register number by this value (bus_shift=1 for 32bit register alignment) */ + int bus_shift; + /* Set if chip requires writing '0' to ack an irq */ + int invertAcks; + /* Number of registers (optional if all output pins specified + * below) */ + int nrRegs; + /* The location of the irq ack register */ + int ackRegister; + + /* List of pin descriptions. One must specify all input pins + * that have a corresponding irq pin and all output pins with + * a non-zero start value. Specifying other pins is + * optional. */ + struct htc_egpio_pinInfo *pins; + int nr_pins; +}; + +/* Determine the wakeup irq, to be called during early resume */ +extern int htc_egpio_get_wakeup_irq(struct device *dev); + +#endif