mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
rk3066 add phone pad modem support
This commit is contained in:
437
arch/arm/configs/rk3066_z600t_phonepad_defconfig
Normal file
437
arch/arm/configs/rk3066_z600t_phonepad_defconfig
Normal file
@@ -0,0 +1,437 @@
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_KERNEL_LZO=y
|
||||
CONFIG_LOG_BUF_SHIFT=19
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_DEBUG=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_PANIC_TIMEOUT=1
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_ASHMEM=y
|
||||
# CONFIG_AIO is not set
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_ARCH_RK30=y
|
||||
CONFIG_CLK_SWITCH_TO_32K=y
|
||||
CONFIG_MACH_RK30_Z600T=y
|
||||
CONFIG_FIQ_DEBUGGER=y
|
||||
CONFIG_FIQ_DEBUGGER_NO_SLEEP=y
|
||||
CONFIG_FIQ_DEBUGGER_CONSOLE=y
|
||||
CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_SMP_ON_UP is not set
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
# CONFIG_OABI_COMPAT is not set
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE="console=ttyFIQ0 androidboot.console=ttyFIQ0 init=/init"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_HOTPLUG=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_WAKELOCK=y
|
||||
CONFIG_PM_RUNTIME=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_SUSPEND_TIME=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_INET_ESP=y
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_TUNNEL=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_NETFILTER=y
|
||||
# CONFIG_BRIDGE_NETFILTER is not set
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_SCTP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_SIP=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_NF_CONNTRACK_IPV4=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_TARGET_REJECT_SKERR=y
|
||||
CONFIG_IP_NF_TARGET_LOG=y
|
||||
CONFIG_NF_NAT=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_CONNTRACK_IPV6=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_TARGET_LOG=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_BRIDGE=y
|
||||
# CONFIG_BRIDGE_IGMP_SNOOPING is not set
|
||||
CONFIG_PHONET=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_INGRESS=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_ACT_GACT=y
|
||||
CONFIG_NET_ACT_MIRRED=y
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_L2CAP=y
|
||||
CONFIG_BT_SCO=y
|
||||
CONFIG_BT_RFCOMM=y
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=y
|
||||
CONFIG_BT_HIDP=y
|
||||
CONFIG_BT_HCIUART=y
|
||||
CONFIG_BT_HCIUART_H4=y
|
||||
CONFIG_BT_HCIUART_LL=y
|
||||
CONFIG_BT_HCIBCM4325=y
|
||||
CONFIG_BT_AUTOSLEEP=y
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_RFKILL_RK=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_NAND_IDS=y
|
||||
CONFIG_MTD_RKNAND=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_MISC_DEVICES=y
|
||||
CONFIG_UID_STAT=y
|
||||
CONFIG_APANIC=y
|
||||
CONFIG_BP_AUTO=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_PHYLIB=y
|
||||
# CONFIG_NETDEV_1000 is not set
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
CONFIG_WLAN_80211=y
|
||||
CONFIG_RKWIFI=y
|
||||
CONFIG_RKWIFI_26M=y
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_ASYNC=y
|
||||
CONFIG_PPP_SYNC_TTY=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPPOLAC=y
|
||||
CONFIG_PPPOPNS=y
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_INPUT_KEYRESET=y
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TABLET=y
|
||||
CONFIG_TABLET_USB_ACECAD=y
|
||||
CONFIG_TABLET_USB_AIPTEK=y
|
||||
CONFIG_TABLET_USB_GTCO=y
|
||||
CONFIG_TABLET_USB_HANWANG=y
|
||||
CONFIG_TABLET_USB_KBTAB=y
|
||||
CONFIG_TABLET_USB_WACOM=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_CT36X=y
|
||||
CONFIG_TOUCHSCREEN_CT36X_PLATFORM_ROCKCHIP=y
|
||||
CONFIG_TOUCHSCREEN_CT36X_CHIP_CT365=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_KEYCHORD=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
CONFIG_GS_MMA8452=y
|
||||
CONFIG_SENSOR_DEVICE=y
|
||||
CONFIG_GSENSOR_DEVICE=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_CONSOLE_TRANSLATIONS is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_RK29=y
|
||||
CONFIG_UART0_RK29=y
|
||||
CONFIG_UART0_CTS_RTS_RK29=y
|
||||
CONFIG_UART3_RK29=y
|
||||
CONFIG_UART3_CTS_RTS_RK29=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
# CONFIG_I2C_COMPAT is not set
|
||||
CONFIG_I2C0_CONTROLLER_RK30=y
|
||||
CONFIG_I2C1_CONTROLLER_RK30=y
|
||||
CONFIG_I2C2_CONTROLLER_RK30=y
|
||||
CONFIG_I2C3_CONTROLLER_RK30=y
|
||||
CONFIG_I2C4_CONTROLLER_RK30=y
|
||||
CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_WM831X=y
|
||||
CONFIG_EXPANDED_GPIO_NUM=0
|
||||
CONFIG_EXPANDED_GPIO_IRQ_NUM=0
|
||||
CONFIG_SPI_FPGA_GPIO_NUM=0
|
||||
CONFIG_SPI_FPGA_GPIO_IRQ_NUM=0
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_WM831X_BACKUP=y
|
||||
CONFIG_BATTERY_RK30_ADC_FAC=y
|
||||
CONFIG_BATTERY_RK30_AC_CHARGE=y
|
||||
CONFIG_BATTERY_RK30_USB_CHARGE=y
|
||||
CONFIG_BATTERY_RK30_VOL3V8=y
|
||||
CONFIG_POWER_ON_CHARGER_DISPLAY=y
|
||||
CONFIG_WM8326_VBAT_LOW_DETECTION=y
|
||||
CONFIG_CHARGER_SMB347=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_MFD_TPS65910=y
|
||||
CONFIG_MFD_WM831X_I2C=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_TPS65910=y
|
||||
CONFIG_REGULATOR_WM831X=y
|
||||
CONFIG_RK30_PWM_REGULATOR=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_VIDEO_DEV=y
|
||||
CONFIG_SOC_CAMERA=y
|
||||
CONFIG_SOC_CAMERA_OV2659=y
|
||||
CONFIG_SOC_CAMERA_OV5640=y
|
||||
CONFIG_VIDEO_RK29=y
|
||||
CONFIG_VIDEO_RK29_CAMMEM_ION=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_ROCKCHIP=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
# CONFIG_BACKLIGHT_GENERIC is not set
|
||||
CONFIG_DISPLAY_SUPPORT=y
|
||||
CONFIG_LCD_HJ101NA=y
|
||||
CONFIG_FB_ROCKCHIP=y
|
||||
CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL=y
|
||||
CONFIG_LCDC_RK30=y
|
||||
CONFIG_RK_HDMI=y
|
||||
CONFIG_HDMI_RK30=y
|
||||
CONFIG_HDMI_SOURCE_LCDC1=y
|
||||
CONFIG_RGA_RK30=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
# CONFIG_SND_SUPPORT_OLD_API is not set
|
||||
# CONFIG_SND_VERBOSE_PROCFS is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
# CONFIG_SND_ARM is not set
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_RK29_SOC=y
|
||||
CONFIG_SND_RK_SOC_I2S2_2CH=y
|
||||
CONFIG_SND_I2S_DMA_EVENT_STATIC=y
|
||||
CONFIG_SND_RK29_SOC_RT3224=y
|
||||
CONFIG_SND_RK29_CODEC_SOC_SLAVE=y
|
||||
CONFIG_HID_A4TECH=y
|
||||
CONFIG_HID_ACRUX=y
|
||||
CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_BELKIN=y
|
||||
CONFIG_HID_CHERRY=y
|
||||
CONFIG_HID_CHICONY=y
|
||||
CONFIG_HID_CYPRESS=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_EMS_FF=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
CONFIG_HID_KEYTOUCH=y
|
||||
CONFIG_HID_KYE=y
|
||||
CONFIG_HID_UCLOGIC=y
|
||||
CONFIG_HID_WALTOP=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_KENSINGTON=y
|
||||
CONFIG_HID_LCPOWER=y
|
||||
CONFIG_HID_LOGITECH=y
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_LOGIG940_FF=y
|
||||
CONFIG_LOGIWII_FF=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_NTRIG=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_PICOLCD=y
|
||||
CONFIG_HID_QUANTA=y
|
||||
CONFIG_HID_ROCCAT_ARVO=y
|
||||
CONFIG_HID_ROCCAT_KONE=y
|
||||
CONFIG_HID_ROCCAT_KONEPLUS=y
|
||||
CONFIG_HID_ROCCAT_KOVAPLUS=y
|
||||
CONFIG_HID_ROCCAT_PYRA=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_THRUSTMASTER_FF=y
|
||||
CONFIG_HID_WACOM=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_ZEROPLUS_FF=y
|
||||
CONFIG_HID_ZYDACRON=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_DEVICEFS=y
|
||||
CONFIG_USB_OTG_BLACKLIST_HUB=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_SERIAL=y
|
||||
CONFIG_USB_SERIAL_GENERIC=y
|
||||
CONFIG_USB_SERIAL_OPTION=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB20_HOST=y
|
||||
CONFIG_USB20_OTG=y
|
||||
CONFIG_DWC_OTG_BOTH_HOST_SLAVE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_UNSAFE_RESUME=y
|
||||
CONFIG_MMC_EMBEDDED_SDIO=y
|
||||
CONFIG_MMC_PARANOID_SD_INIT=y
|
||||
CONFIG_SDMMC_RK29=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_SWITCH=y
|
||||
CONFIG_SWITCH_GPIO=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_WM831X=y
|
||||
CONFIG_TPS65910_RTC=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_LOGGER=y
|
||||
CONFIG_ANDROID_TIMED_GPIO=y
|
||||
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
|
||||
# CONFIG_CMMB is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_FS_XATTR is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_EXT4_FS_XATTR is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_EVENT_POWER_TRACING_DEPRECATED is not set
|
||||
CONFIG_ENABLE_DEFAULT_TRACERS=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_TWOFISH=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
@@ -73,7 +73,10 @@ config MACH_RK30_PHONE_A22
|
||||
|
||||
config MACH_RK30_PHONE_PAD
|
||||
bool "RK30 phone pad board"
|
||||
|
||||
|
||||
config MACH_RK30_Z600T
|
||||
bool "RK30 Z600T smart phone pad board"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
|
||||
@@ -26,10 +26,12 @@ obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_DVFS) += dvfs.o
|
||||
obj-$(CONFIG_RK30_I2C_INSRAM) += i2c_sram.o
|
||||
obj-y += board.o
|
||||
|
||||
obj-$(CONFIG_MACH_RK3066_SDK) += board-rk30-sdk.o
|
||||
obj-$(CONFIG_MACH_RK30_SDK) += board-rk30-sdk.o
|
||||
obj-$(CONFIG_MACH_RK30_DS975) += board-rk30-ds975.o
|
||||
board-$(CONFIG_MACH_RK3066_SDK) += board-rk30-sdk.o
|
||||
board-$(CONFIG_MACH_RK30_SDK) += board-rk30-sdk.o
|
||||
board-$(CONFIG_MACH_RK30_DS975) += board-rk30-ds975.o
|
||||
board-$(CONFIG_MACH_RK30_Z600T) += board-rk30-phonepad-z600t.o
|
||||
obj-$(CONFIG_MACH_RK30_PHONE) += board-rk30-phone.o board-rk30-phone-key.o
|
||||
obj-$(CONFIG_MACH_RK30_PHONE_PAD) += board-rk30-phonepad.o board-rk30-phonepad-key.o
|
||||
obj-$(CONFIG_MACH_RK30_PHONE_LOQUAT) += board-rk30-phone-loquat.o board-rk30-phone-loquat-key.o
|
||||
|
||||
2083
arch/arm/mach-rk30/board-rk30-phonepad-z600t.c
Normal file
2083
arch/arm/mach-rk30/board-rk30-phonepad-z600t.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,7 @@
|
||||
#include <linux/sensor-dev.h>
|
||||
#include <linux/regulator/rk29-pwm-regulator.h>
|
||||
|
||||
#include "../../../drivers/headset_observe/rk_headset.h"
|
||||
#if defined(CONFIG_MFD_RK610)
|
||||
#include <linux/mfd/rk610_core.h>
|
||||
#endif
|
||||
@@ -56,22 +57,24 @@
|
||||
#if defined(CONFIG_SPIM_RK29)
|
||||
#include "../../../drivers/spi/rk29_spim.h"
|
||||
#endif
|
||||
#if defined(CONFIG_MU509)
|
||||
#include <linux/mu509.h>
|
||||
#endif
|
||||
#if defined(CONFIG_MW100)
|
||||
#include <linux/mw100.h>
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229)
|
||||
#include <linux/mt6229.h>
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868)
|
||||
#include <linux/sew868.h>
|
||||
|
||||
#if defined (CONFIG_BP_AUTO)
|
||||
#include <linux/bp-auto.h>
|
||||
#endif
|
||||
#if defined(CONFIG_ANDROID_TIMED_GPIO)
|
||||
#include "../../../drivers/staging/android/timed_gpio.h"
|
||||
#endif
|
||||
|
||||
/* Android Parameter */
|
||||
static int ap_mdm = 0;
|
||||
module_param(ap_mdm, int, 0644);
|
||||
static int ap_has_alsa = 0;
|
||||
module_param(ap_has_alsa, int, 0644);
|
||||
static int ap_data_only = 2;
|
||||
module_param(ap_data_only, int, 0644);
|
||||
static int ap_has_earphone = 0;
|
||||
module_param(ap_has_earphone, int, 0644);
|
||||
|
||||
#if defined(CONFIG_MT6620)
|
||||
#include <linux/gps.h>
|
||||
#endif
|
||||
@@ -172,6 +175,39 @@ struct rk29_keys_platform_data rk29_keys_pdata = {
|
||||
.chn = 1, //chn: 0-7, if do not use ADC,set 'chn' -1
|
||||
};
|
||||
|
||||
#if defined (CONFIG_RK_HEADSET_DET) || defined (CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET)
|
||||
|
||||
static int rk_headset_io_init(int gpio, char *iomux_name, int iomux_mode)
|
||||
{
|
||||
int ret;
|
||||
ret = gpio_request(gpio, NULL);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
rk30_mux_api_set(iomux_name, iomux_mode);
|
||||
gpio_pull_updown(gpio, PullDisable);
|
||||
gpio_direction_input(gpio);
|
||||
mdelay(50);
|
||||
return 0;
|
||||
};
|
||||
|
||||
struct rk_headset_pdata rk_headset_info = {
|
||||
.Headset_gpio = RK30_PIN0_PC7,
|
||||
.headset_in_type = HEADSET_IN_LOW,
|
||||
.Hook_adc_chn = 2,
|
||||
.hook_key_code = KEY_MEDIA,
|
||||
.headset_gpio_info = {GPIO0C7_TRACECTL_SMCADDR3_NAME, GPIO0C_GPIO0C7},
|
||||
.headset_io_init = rk_headset_io_init,
|
||||
};
|
||||
|
||||
struct platform_device rk_device_headset = {
|
||||
.name = "rk_headsetdet",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &rk_headset_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_GT8XX)
|
||||
#define TOUCH_RESET_PIN RK30_PIN4_PD0
|
||||
#define TOUCH_PWR_PIN INVALID_GPIO
|
||||
@@ -318,6 +354,94 @@ static struct platform_device rk29_device_backlight = {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT3224) || defined (CONFIG_SND_SOC_RT3261)
|
||||
|
||||
#define DIFFERENTIAL 1
|
||||
#define SINGLE_END 0
|
||||
#define TWO_SPK 2
|
||||
#define ONE_SPK 1
|
||||
|
||||
enum {
|
||||
SPK_AMPLIFY_ZERO_POINT_FIVE_WATT=1,
|
||||
SPK_AMPLIFY_ZERO_POINT_SIX_WATT,
|
||||
SPK_AMPLIFY_ZERO_POINT_EIGHT_WATT,
|
||||
SPK_AMPLIFY_ONE_WATT,
|
||||
};
|
||||
|
||||
enum {
|
||||
LR_NORMAL,
|
||||
LR_SWAP,
|
||||
LEFT_COPY_TO_RIGHT,
|
||||
RIGHT_COPY_LEFT,
|
||||
};
|
||||
|
||||
static int rt3261_io_init(int gpio, char *iomux_name, int iomux_mode)
|
||||
{
|
||||
gpio_request(gpio,NULL);
|
||||
rk30_mux_api_set(iomux_name, iomux_mode);
|
||||
gpio_direction_output(gpio,1);
|
||||
|
||||
};
|
||||
|
||||
static struct rt3261_platform_data rt3261_info = {
|
||||
.codec_en_gpio = RK30_PIN4_PD7,
|
||||
.codec_en_gpio_info = {GPIO4D7_SMCDATA15_TRACEDATA15_NAME,GPIO4D_GPIO4D7},
|
||||
.io_init = rt3261_io_init,
|
||||
.spk_num = TWO_SPK,
|
||||
.modem_input_mode = DIFFERENTIAL,
|
||||
.lout_to_modem_mode = DIFFERENTIAL,
|
||||
.spk_amplify = SPK_AMPLIFY_ZERO_POINT_SIX_WATT,
|
||||
.playback_if1_data_control = LR_NORMAL,
|
||||
.playback_if2_data_control = LR_NORMAL,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BP_AUTO)
|
||||
static int bp_io_init(void)
|
||||
{
|
||||
rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6);
|
||||
rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2);
|
||||
rk30_mux_api_set(GPIO4C6_SMCDATA6_TRACEDATA6_NAME, GPIO4C_GPIO4C6);
|
||||
rk30_mux_api_set(GPIO4C4_SMCDATA4_TRACEDATA4_NAME, GPIO4C_GPIO4C4);
|
||||
//rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7);
|
||||
//rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bp_io_deinit(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int bp_id_get(void)
|
||||
{
|
||||
return ap_mdm; //internally 3G modem ID, defined in include\linux\Bp-auto.h
|
||||
}
|
||||
|
||||
struct bp_platform_data bp_auto_info = {
|
||||
.init_platform_hw = bp_io_init,
|
||||
.exit_platform_hw = bp_io_deinit,
|
||||
.get_bp_id = bp_id_get,
|
||||
.bp_power = RK30_PIN6_PB2, // 3g_power
|
||||
.bp_en = RK30_PIN2_PB6, // 3g_en
|
||||
.bp_reset = RK30_PIN4_PD2,
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_wakeup_ap = RK30_PIN4_PC6, //
|
||||
.ap_wakeup_bp = RK30_PIN4_PC4,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.gpio_valid = 1, //if 1:gpio is define in bp_auto_info,if 0:is not use gpio in bp_auto_info
|
||||
};
|
||||
|
||||
struct platform_device device_bp_auto = {
|
||||
.name = "bp-auto",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &bp_auto_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_RK29_SUPPORT_MODEM
|
||||
|
||||
#define RK30_MODEM_POWER RK30_PIN4_PD1
|
||||
@@ -346,144 +470,7 @@ static struct platform_device rk30_device_modem = {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#if defined(CONFIG_MU509)
|
||||
static int mu509_io_init(void)
|
||||
{
|
||||
|
||||
rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6);
|
||||
rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2);
|
||||
rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7);
|
||||
rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mu509_io_deinit(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rk29_mu509_data rk29_mu509_info = {
|
||||
.io_init = mu509_io_init,
|
||||
.io_deinit = mu509_io_deinit,
|
||||
.modem_power_en = RK30_PIN6_PB2,//RK30_PIN4_PD1,
|
||||
.bp_power = RK30_PIN2_PB6,//RK30_PIN4_PD1,
|
||||
.bp_reset = RK30_PIN4_PD2,
|
||||
.ap_wakeup_bp = RK30_PIN2_PB7,
|
||||
.bp_wakeup_ap = RK30_PIN6_PA0,
|
||||
};
|
||||
struct platform_device rk29_device_mu509 = {
|
||||
.name = "mu509",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk29_mu509_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#if defined(CONFIG_MW100)
|
||||
static int mw100_io_init(void)
|
||||
{
|
||||
rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6);
|
||||
rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2);
|
||||
rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7);
|
||||
rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mw100_io_deinit(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rk29_mw100_data rk29_mw100_info = {
|
||||
.io_init = mw100_io_init,
|
||||
.io_deinit = mw100_io_deinit,
|
||||
.modem_power_en = RK30_PIN6_PB2,
|
||||
.bp_power = RK30_PIN2_PB6,
|
||||
.bp_reset = RK30_PIN4_PD2,
|
||||
.ap_wakeup_bp = RK30_PIN2_PB7,
|
||||
.bp_wakeup_ap = RK30_PIN6_PA0,
|
||||
};
|
||||
struct platform_device rk29_device_mw100 = {
|
||||
.name = "mw100",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk29_mw100_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229)
|
||||
static int mt6229_io_init(void)
|
||||
{
|
||||
rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6);
|
||||
rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2);
|
||||
rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7);
|
||||
rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0);
|
||||
rk30_mux_api_set(GPIO2C1_LCDC1DATA17_SMCBLSN0_HSADCDATA6_NAME, GPIO2C_GPIO2C1);
|
||||
rk30_mux_api_set(GPIO2C1_LCDC1DATA17_SMCBLSN0_HSADCDATA6_NAME, GPIO2C_GPIO2C1);
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt6229_io_deinit(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rk29_mt6229_data rk29_mt6229_info = {
|
||||
.io_init = mt6229_io_init,
|
||||
.io_deinit = mt6229_io_deinit,
|
||||
.modem_power_en = RK30_PIN6_PB2,
|
||||
.bp_power = RK30_PIN2_PB6,
|
||||
.modem_usb_en = RK30_PIN2_PC0,
|
||||
.modem_uart_en = RK30_PIN2_PC1,
|
||||
.bp_wakeup_ap = RK30_PIN6_PA1,
|
||||
.ap_ready = RK30_PIN2_PB7,
|
||||
|
||||
};
|
||||
struct platform_device rk29_device_mt6229 = {
|
||||
.name = "mt6229",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk29_mt6229_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868)
|
||||
static int sew868_io_init(void)
|
||||
{
|
||||
rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME, GPIO2B_GPIO2B6);
|
||||
rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME, GPIO4D_GPIO4D2);
|
||||
rk30_mux_api_set(GPIO4D4_SMCDATA12_TRACEDATA12_NAME, GPIO4D_GPIO4D4);
|
||||
return 0;
|
||||
}
|
||||
static int sew868_io_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
struct rk30_sew868_data rk30_sew868_info = {
|
||||
.io_init = sew868_io_init,
|
||||
.io_deinit = sew868_io_deinit,
|
||||
.bp_power = RK30_PIN6_PB2,
|
||||
.bp_power_active_low = 1,
|
||||
.bp_sys = RK30_PIN2_PB6,
|
||||
.bp_reset = RK30_PIN4_PD2,
|
||||
.bp_reset_active_low = 1,
|
||||
.bp_wakeup_ap = RK30_PIN4_PD4,
|
||||
.ap_wakeup_bp = NULL,
|
||||
};
|
||||
|
||||
struct platform_device rk30_device_sew868 = {
|
||||
.name = "sew868",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk30_sew868_info,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*MMA8452 gsensor*/
|
||||
#if defined (CONFIG_GS_MMA8452)
|
||||
@@ -1453,18 +1440,10 @@ static struct platform_device *devices[] __initdata = {
|
||||
#ifdef CONFIG_RK29_SUPPORT_MODEM
|
||||
&rk30_device_modem,
|
||||
#endif
|
||||
#if defined(CONFIG_MU509)
|
||||
&rk29_device_mu509,
|
||||
#endif
|
||||
#if defined(CONFIG_MW100)
|
||||
&rk29_device_mw100,
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229)
|
||||
&rk29_device_mt6229,
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868)
|
||||
&rk30_device_sew868,
|
||||
#if defined (CONFIG_RK_HEADSET_DET) || defined (CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET)
|
||||
&rk_device_headset,
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BATTERY_RK30_ADC)||defined(CONFIG_BATTERY_RK30_ADC_FAC)
|
||||
&rk30_device_adc_battery,
|
||||
#endif
|
||||
@@ -1474,6 +1453,9 @@ static struct platform_device *devices[] __initdata = {
|
||||
#ifdef CONFIG_MT5931_MT6622
|
||||
&device_mt6622,
|
||||
#endif
|
||||
#if defined(CONFIG_BP_AUTO)
|
||||
&device_bp_auto,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1609,6 +1591,14 @@ static struct i2c_board_info __initdata i2c0_info[] = {
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_RT3224) || defined (CONFIG_SND_SOC_RT3261)
|
||||
{
|
||||
.type = "rt3261",
|
||||
.addr = 0x1c,
|
||||
.flags = 0,
|
||||
.platform_data = &rt3261_info,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MFD_RK610
|
||||
{
|
||||
@@ -1832,6 +1822,12 @@ static void __init machine_rk30_board_init(void)
|
||||
#if defined(CONFIG_MT6620)
|
||||
clk_set_rate(clk_get_sys("rk_serial.0", "uart"), 48*1000000);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_RT3224) || defined (CONFIG_SND_SOC_RT3261)
|
||||
//add for codec_en
|
||||
gpio_request(RK30_PIN4_PD7, "codec_en");
|
||||
rk30_mux_api_set(GPIO4D7_SMCDATA15_TRACEDATA15_NAME, GPIO4D_GPIO4D7);
|
||||
gpio_direction_output(RK30_PIN4_PD7, GPIO_HIGH);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init rk30_reserve(void)
|
||||
|
||||
@@ -217,6 +217,13 @@ struct board_id_platform_data {
|
||||
int (*init_parameter)(int id);
|
||||
};
|
||||
|
||||
struct ft5506_platform_data {
|
||||
int (*get_pendown_state)(void);
|
||||
int (*init_platform_hw)(void);
|
||||
int (*platform_sleep)(void);
|
||||
int (*platform_wakeup)(void);
|
||||
void (*exit_platform_hw)(void);
|
||||
};
|
||||
struct cm3217_platform_data {
|
||||
int irq_pin;
|
||||
int power_pin;
|
||||
|
||||
@@ -144,6 +144,7 @@ config TOUCHSCREEN_GT8XX
|
||||
goodix touch max y resolution
|
||||
|
||||
config TOUCHSCREEN_CT36X
|
||||
default n
|
||||
tristate "CT36X based touchscreens"
|
||||
|
||||
config RK28_I2C_TS_NTP070
|
||||
@@ -1063,6 +1064,17 @@ config TOUCHSCREEN_FT5406
|
||||
config TOUCHSCREEN_FT5X0X
|
||||
tristate "ft5x0x touchscreen panel support "
|
||||
depends on I2C2_RK29 || I2C2_RK30
|
||||
config TOUCHSCREEN_FT5506
|
||||
tristate "FT5506 based touchscreens: FT5506 Interface"
|
||||
depends on I2C2_RK29 || I2C2_RK30
|
||||
help
|
||||
say Y here if you have a touchscreen interface using the FT5506
|
||||
controller,and your board-specific initialization code includes that
|
||||
in its table of I2C devices.
|
||||
|
||||
If unsure, say N(but it's safe to say "Y").
|
||||
# VTL TouchScreen Driver Config
|
||||
source "drivers/input/touchscreen/ct36x_ts/Kconfig"
|
||||
|
||||
config ATMEL_MXT1386
|
||||
tristate "ATMEL_MXT1386 touchscreen panel support"
|
||||
|
||||
@@ -85,6 +85,7 @@ obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC) += ili2102_ts.o
|
||||
obj-$(CONFIG_D70_L3188A) += goodix_touch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_GT8XX) += rk29_i2c_goodix.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5406) += ft5406_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5506) += ft5506_wgj.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5306) += ft5306_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_SITRONIX_A720) += sitronix_ts_a720.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5306_WPX2) += ft5306_ts_wpx2.o
|
||||
@@ -99,4 +100,6 @@ obj-$(CONFIG_TOUCHSCREEN_I30) += i30_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_BYD693X) += byd693x_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FT5X0X) += ft5x0x.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_GSLX680) += rockchip_gslX680.o
|
||||
# Make VTL TouchScreen Driver
|
||||
obj-$(CONFIG_TOUCHSCREEN_CT36X) += ct36x_ts/
|
||||
|
||||
|
||||
63
drivers/input/touchscreen/ct36x_ts/Kconfig
Normal file
63
drivers/input/touchscreen/ct36x_ts/Kconfig
Normal file
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# Touchscreen driver configuration
|
||||
#
|
||||
|
||||
|
||||
config TOUCHSCREEN_CT36X
|
||||
tristate "VTL ct36x based touchscreens"
|
||||
default y
|
||||
|
||||
if TOUCHSCREEN_CT36X
|
||||
#config TOUCHSCREEN_CT36X_I2C
|
||||
# tristate "VTL ct36x based touchscreens"
|
||||
# depends on I2C
|
||||
|
||||
choice
|
||||
prompt "Device driver platform support"
|
||||
default TOUCHSCREEN_CT36X_PLATFORM_GENERIC
|
||||
|
||||
config TOUCHSCREEN_CT36X_PLATFORM_GENERIC
|
||||
bool "Generic"
|
||||
|
||||
config TOUCHSCREEN_CT36X_PLATFORM_ROCKCHIP
|
||||
bool "RockChip"
|
||||
|
||||
config TOUCHSCREEN_CT36X_PLATFORM_ALLWINNER
|
||||
bool "AllWinner"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Device driver chip support"
|
||||
default TOUCHSCREEN_CT36X_CHIP_CT360
|
||||
|
||||
config TOUCHSCREEN_CT36X_CHIP_CT360
|
||||
bool "ct360"
|
||||
|
||||
config TOUCHSCREEN_CT36X_CHIP_CT365
|
||||
bool "ct363/ct365"
|
||||
endchoice
|
||||
|
||||
config TOUCHSCREEN_CT36X_MISC
|
||||
bool "Device driver misc support"
|
||||
default y
|
||||
|
||||
config TOUCHSCREEN_CT36X_MISC_X_REVERSE
|
||||
bool "reverse X axis"
|
||||
default n
|
||||
depends on TOUCHSCREEN_CT36X_MISC
|
||||
|
||||
config TOUCHSCREEN_CT36X_MISC_Y_REVERSE
|
||||
bool "reverse Y axis"
|
||||
default n
|
||||
depends on TOUCHSCREEN_CT36X_MISC
|
||||
|
||||
config TOUCHSCREEN_CT36X_MISC_XY_SWAP
|
||||
bool "swap X, Y"
|
||||
default n
|
||||
depends on TOUCHSCREEN_CT36X_MISC
|
||||
|
||||
config TOUCHSCREEN_CT36X_MISC_NEW_TPS
|
||||
bool "uses new touch point structure"
|
||||
default y
|
||||
depends on TOUCHSCREEN_CT36X_MISC
|
||||
endif
|
||||
26
drivers/input/touchscreen/ct36x_ts/Makefile
Normal file
26
drivers/input/touchscreen/ct36x_ts/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Makefile for the touchscreen drivers.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
# Core
|
||||
ct36x_ts-y := tscore.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CT36X) += ct36x_ts.o
|
||||
|
||||
# platform
|
||||
# Generic
|
||||
ct36x_ts-$(CONFIG_TOUCHSCREEN_CT36X_PLATFORM_GENERIC) += generic.o
|
||||
# RockChip
|
||||
ct36x_ts-$(CONFIG_TOUCHSCREEN_CT36X_PLATFORM_ROCKCHIP) += rockchip.o
|
||||
# AllWinner
|
||||
ct36x_ts-$(CONFIG_TOUCHSCREEN_CT36X_PLATFORM_ALLWINNER) += allwinner.o
|
||||
|
||||
# Chip
|
||||
# ct360
|
||||
ct36x_ts-$(CONFIG_TOUCHSCREEN_CT36X_CHIP_CT360) += ct360.o
|
||||
# ct362/ct363/365
|
||||
ct36x_ts-$(CONFIG_TOUCHSCREEN_CT36X_CHIP_CT365) += ct365.o
|
||||
|
||||
# Misc
|
||||
|
||||
99
drivers/input/touchscreen/ct36x_ts/allwinner.c
Normal file
99
drivers/input/touchscreen/ct36x_ts/allwinner.c
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "tscore.h"
|
||||
//#include "generic.h"
|
||||
|
||||
|
||||
|
||||
static struct i2c_device_id ct36x_ts_id[] = {
|
||||
{ DRIVER_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_board_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO(DRIVER_NAME, 0x01),
|
||||
.platform_data = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
struct i2c_driver ct36x_ts_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRIVER_NAME
|
||||
},
|
||||
.id_table = ct36x_ts_id,
|
||||
.probe = ct36x_ts_probe,
|
||||
.suspend = ct36x_ts_suspend,
|
||||
.resume = ct36x_ts_resume,
|
||||
.remove = __devexit_p(ct36x_ts_remove),
|
||||
};
|
||||
|
||||
void ct36x_platform_get_cfg(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
/* I2C config */
|
||||
ct36x_ts->i2c_bus = CT36X_TS_I2C_BUS;
|
||||
ct36x_ts->i2c_address = CT36X_TS_I2C_ADDRESS;
|
||||
|
||||
/* GPIO config */
|
||||
ct36x_ts->rst = CT36X_TS_RST_PIN;
|
||||
ct36x_ts->ss = CT36X_TS_IRQ_PIN;
|
||||
|
||||
/* IRQ config*/
|
||||
ct36x_ts->irq = gpio_to_irq(ct36x_ts->ss);
|
||||
|
||||
ct36x_ts->ready = 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_set_dev(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *client;
|
||||
|
||||
adapter = i2c_get_adapter(ct36x_ts->i2c_bus);
|
||||
if ( !adapter ) {
|
||||
printk("Unable to get i2c adapter on bus %d.\n", ct36x_ts->i2c_bus);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
client = i2c_new_device(adapter, i2c_board_info);
|
||||
i2c_put_adapter(adapter);
|
||||
if (!client) {
|
||||
printk("Unable to create i2c device on bus %d.\n", ct36x_ts->i2c_bus);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ct36x_ts->client = client;
|
||||
i2c_set_clientdata(client, ct36x_ts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_get_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
// Init Reset pin
|
||||
err = gpio_request(ct36x_ts->rst, "ct36x_ts_rst");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_output(ct36x_ts->rst, 1);
|
||||
gpio_set_value(ct36x_ts->rst, 1);
|
||||
|
||||
// Init Int pin
|
||||
err = gpio_request(ct36x_ts->ss, "ct36x_ts_int");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_input(ct36x_ts->ss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_platform_put_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
gpio_free(ct36x_ts->rst);
|
||||
gpio_free(ct36x_ts->ss);
|
||||
}
|
||||
13
drivers/input/touchscreen/ct36x_ts/chip.h
Normal file
13
drivers/input/touchscreen/ct36x_ts/chip.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef CHIP_H
|
||||
#define CHIP_H
|
||||
|
||||
#if defined(CONFIG_TOUCHSCREEN_CT36X_CHIP_CT360)
|
||||
#include "ct360.h"
|
||||
#elif defined(CONFIG_TOUCHSCREEN_CT36X_CHIP_CT365)
|
||||
#include "ct365.h"
|
||||
#else
|
||||
#error XXXXXXXXXXXXXXXXXXXXXXXX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
363
drivers/input/touchscreen/ct36x_ts/ct360.c
Normal file
363
drivers/input/touchscreen/ct36x_ts/ct360.c
Normal file
@@ -0,0 +1,363 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "tscore.h"
|
||||
#include "platform.h"
|
||||
#include "ct360.h"
|
||||
|
||||
|
||||
#define CT36X_CHIP_FLASH_SECTOR_NUM 8
|
||||
#define CT36X_CHIP_FLASH_SECTOR_SIZE 2048
|
||||
#define CT36X_CHIP_FLASH_SOURCE_SIZE 8
|
||||
|
||||
static unsigned char binary_data[] = {
|
||||
//#include "CT365Five3020D_V42120523A.dat"
|
||||
#include "CT365_THSD_40X28_V05_120827_I2C0X01.dat"
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Private functions
|
||||
*/
|
||||
static void ct36x_chip_set_idle(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xA5;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 2);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static void ct36x_chip_rst_offset(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0x00;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 1);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static int ct36x_chip_get_busstatus(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ct36x_ts_reg_read(client, 0x7F, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static int ct36x_chip_erase_flash(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
int sec;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Erase 16k flash
|
||||
for ( sec = 0; sec < CT36X_CHIP_FLASH_SECTOR_NUM; sec++ ) {
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x33;
|
||||
buf[2] = sec*8;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 3);
|
||||
mdelay(100);
|
||||
|
||||
// Reset I2C offset address
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
// Read I2C bus status
|
||||
ret = ct36x_chip_get_busstatus(client, buf);
|
||||
if ( ret != 0xAA ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Prepare code segment
|
||||
*/
|
||||
static int ct36x_chip_set_code(unsigned int flash_addr, unsigned char *buf)
|
||||
{
|
||||
unsigned char cod_chksum;
|
||||
|
||||
//if ( CT36X_TS_CHIP_DEBUG )
|
||||
//printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Flash address
|
||||
// data length
|
||||
buf[2] = (char)(flash_addr >> 8);
|
||||
buf[3] = (char)(flash_addr & 0xFF);
|
||||
buf[4] = 0x08;
|
||||
|
||||
// Fill firmware source data
|
||||
//if ( (sec == 1 && cod == 4) || (sec == 1 && cod == 5) ) {
|
||||
//if ( flash_addr == (CT36X_CHIP_FLASH_SECTOR_SIZE + 32) ||
|
||||
//flash_addr == (CT36X_CHIP_FLASH_SECTOR_SIZE + 40) ) {
|
||||
if ( flash_addr == (160) || flash_addr == (168) ) {
|
||||
buf[6] = ~binary_data[flash_addr + 0];
|
||||
buf[7] = ~binary_data[flash_addr + 1];
|
||||
buf[8] = ~binary_data[flash_addr + 2];
|
||||
buf[9] = ~binary_data[flash_addr + 3];
|
||||
buf[10] = ~binary_data[flash_addr + 4];
|
||||
buf[11] = ~binary_data[flash_addr + 5];
|
||||
buf[12] = ~binary_data[flash_addr + 6];
|
||||
buf[13] = ~binary_data[flash_addr + 7];
|
||||
} else {
|
||||
buf[6] = binary_data[flash_addr + 0];
|
||||
buf[7] = binary_data[flash_addr + 1];
|
||||
buf[8] = binary_data[flash_addr + 2];
|
||||
buf[9] = binary_data[flash_addr + 3];
|
||||
buf[10] = binary_data[flash_addr + 4];
|
||||
buf[11] = binary_data[flash_addr + 5];
|
||||
buf[12] = binary_data[flash_addr + 6];
|
||||
buf[13] = binary_data[flash_addr + 7];
|
||||
}
|
||||
|
||||
/* Calculate a checksum by Host controller.
|
||||
** Checksum = ~(FLASH_ADRH+FLASH_ADRL+LENGTH+
|
||||
** Binary_Data1+Binary_Data2+Binary_Data3+Binary_Data4+
|
||||
** Binary_Data5+Binary_Data6+Binary_Data7+Binary_Data8) + 1
|
||||
*/
|
||||
cod_chksum = ~(buf[2]+buf[3]+buf[4]+
|
||||
buf[6]+buf[7]+buf[8]+buf[9]+
|
||||
buf[10]+buf[11]+buf[12]+buf[13]) + 1;
|
||||
buf[5] = cod_chksum;
|
||||
|
||||
return cod_chksum;
|
||||
}
|
||||
|
||||
static int ct36x_chip_write_firmware(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
int sec, cod;
|
||||
unsigned char cod_chksum;
|
||||
unsigned int fin_chksum;
|
||||
unsigned int flash_addr;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Code checksum, final checksum
|
||||
cod_chksum = 0x00; fin_chksum = 0x00;
|
||||
|
||||
// Flash write command
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x55;
|
||||
|
||||
// 8 sectors, 2048 bytes per sectors
|
||||
for ( sec = 0; sec < CT36X_CHIP_FLASH_SECTOR_NUM; sec++ ) {
|
||||
flash_addr = sec * CT36X_CHIP_FLASH_SECTOR_SIZE;
|
||||
// 256 segments, 8 bytes per segment
|
||||
for ( cod = 0; cod < (CT36X_CHIP_FLASH_SECTOR_SIZE/CT36X_CHIP_FLASH_SOURCE_SIZE); cod++ ) {
|
||||
// Fill binary data
|
||||
cod_chksum = ct36x_chip_set_code(flash_addr, buf);
|
||||
fin_chksum += cod_chksum;
|
||||
|
||||
// Write firmware source data
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 14);
|
||||
|
||||
//
|
||||
mdelay(1);
|
||||
|
||||
// Increase flash address 8bytes for each write command
|
||||
flash_addr += CT36X_CHIP_FLASH_SOURCE_SIZE;
|
||||
}
|
||||
//
|
||||
mdelay(20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** public functions
|
||||
*/
|
||||
int ct36x_chip_get_binchksum(unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
int sec, cod;
|
||||
unsigned char cod_chksum;
|
||||
unsigned int fin_chksum = 0;
|
||||
unsigned int flash_addr;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// 8 sectors, 2048 bytes per sectors
|
||||
for ( sec = 0; sec < CT36X_CHIP_FLASH_SECTOR_NUM; sec++ ) {
|
||||
flash_addr = sec * CT36X_CHIP_FLASH_SECTOR_SIZE;
|
||||
// 256 segments, 8 bytes per segment
|
||||
for ( cod = 0; cod < (CT36X_CHIP_FLASH_SECTOR_SIZE/CT36X_CHIP_FLASH_SOURCE_SIZE); cod++ ) {
|
||||
// Fill binary data
|
||||
cod_chksum = ct36x_chip_set_code(flash_addr, buf);
|
||||
fin_chksum += cod_chksum;
|
||||
|
||||
// Increase flash address 8bytes for each write command
|
||||
flash_addr += CT36X_CHIP_FLASH_SOURCE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return (unsigned short)fin_chksum;
|
||||
}
|
||||
|
||||
int ct36x_chip_get_fwchksum(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int fwchksum = 0x00;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE1;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(500);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0A;
|
||||
buf[2] = 0x0D;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
ct36x_ts_reg_read(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
fwchksum = ((buf[0]<<8) | buf[1]);
|
||||
|
||||
return fwchksum;
|
||||
}
|
||||
|
||||
int ct36x_chip_get_ver(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Read version command
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x3F;
|
||||
buf[2] = 0xFF;
|
||||
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(10);
|
||||
|
||||
buf[0] = 0x00;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
// do read version
|
||||
ct36x_ts_reg_read(client, client->addr, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
int ct36x_chip_get_vendor(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_chip_go_sleep(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0x2B;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x00;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
|
||||
//mdelay(50);
|
||||
}
|
||||
|
||||
int ct36x_chip_go_bootloader(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Init bootloader
|
||||
ct36x_chip_set_idle(client, buf);
|
||||
|
||||
// Reset I2C offset address
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
// Get I2C bus status
|
||||
ret = ct36x_chip_get_busstatus(client, buf);
|
||||
if ( ret != 0xAA ) {
|
||||
printk("I2C bus status: 0x%x.\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Erase flash
|
||||
ret = ct36x_chip_erase_flash(client, buf);
|
||||
if ( ret ) {
|
||||
printk("Erase flash failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write source data
|
||||
ct36x_chip_write_firmware(client, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_chip_set_adapter_on(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE3;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
}
|
||||
|
||||
void ct36x_chip_set_adapter_off(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE2;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
}
|
||||
|
||||
77
drivers/input/touchscreen/ct36x_ts/ct360.h
Normal file
77
drivers/input/touchscreen/ct36x_ts/ct360.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef CT360_H
|
||||
#define CT360_H
|
||||
|
||||
#define CT36X_TS_CHIP_DEBUG 1
|
||||
|
||||
/* max touch points supported */
|
||||
#define CT36X_TS_POINT_NUM 5
|
||||
|
||||
#define CT36X_TS_ABS_X_MAX 1024
|
||||
#define CT36X_TS_ABS_Y_MAX 768
|
||||
|
||||
/* data structure of point event */
|
||||
/* Old Touch Points Protocol
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte0|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Finger ID|Statu|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte1|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte2|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Y High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte3|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X Low |X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
/* New Touch Points Protocol
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte0|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte1|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Y High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte2|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X Low |X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte3|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Finger ID|Statu|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
struct ct36x_finger_info {
|
||||
#ifndef CONFIG_TOUCHSCREEN_CT36X_MISC_NEW_TPS
|
||||
unsigned char status : 4; // Action information, 1: Down; 2: Move; 3: Up
|
||||
unsigned char id : 4; // ID information, from 1 to CFG_MAX_POINT_NUM
|
||||
#endif
|
||||
unsigned char xhi; // X coordinate Hi
|
||||
unsigned char yhi; // Y coordinate Hi
|
||||
unsigned char ylo : 4; // Y coordinate Lo
|
||||
unsigned char xlo : 4; // X coordinate Lo
|
||||
#ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_NEW_TPS
|
||||
unsigned char status : 4; // Action information, 1: Down; 2: Move; 3: Up
|
||||
unsigned char id : 4; // ID information, from 1 to CFG_MAX_POINT_NUM
|
||||
#endif
|
||||
};
|
||||
|
||||
int ct36x_chip_get_binchksum(unsigned char *buf);
|
||||
int ct36x_chip_get_fwchksum(struct i2c_client *client, unsigned char *buf);
|
||||
|
||||
int ct36x_chip_get_ver(struct i2c_client *client, unsigned char *buf);
|
||||
int ct36x_chip_get_vendor(struct i2c_client *client, unsigned char *buf);
|
||||
void ct36x_chip_go_sleep(struct i2c_client *client, unsigned char *buf);
|
||||
int ct36x_chip_go_bootloader(struct i2c_client *client, unsigned char *buf);
|
||||
|
||||
void ct36x_chip_set_adapter_on(struct i2c_client *client, unsigned char *buf);
|
||||
void ct36x_chip_set_adapter_off(struct i2c_client *client, unsigned char *buf);
|
||||
|
||||
#endif
|
||||
439
drivers/input/touchscreen/ct36x_ts/ct365.c
Normal file
439
drivers/input/touchscreen/ct36x_ts/ct365.c
Normal file
@@ -0,0 +1,439 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "tscore.h"
|
||||
#include "platform.h"
|
||||
#include "ct365.h"
|
||||
|
||||
/*
|
||||
* Private functions
|
||||
*/
|
||||
#define CT36X_CHIP_FLASH_SECTOR_NUM 256
|
||||
#define CT36X_CHIP_FLASH_SECTOR_SIZE 128
|
||||
#define CT36X_CHIP_FLASH_SOURCE_SIZE 8
|
||||
|
||||
static unsigned char binary_data[] = {
|
||||
//#include "CT365Five3020D_V42120523A.dat"
|
||||
//#include "CT365_THSD_40X28_V05_120827_I2C0X01.dat"
|
||||
};
|
||||
|
||||
|
||||
static void ct36x_chip_set_idle(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xA5;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 2);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static void ct36x_chip_rst_offset(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0x00;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 1);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static int ct36x_chip_get_busstatus(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ct36x_ts_reg_read(client, 0x7F, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
static int ct36x_chip_erase_flash(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Erase 32k flash
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x33;
|
||||
buf[2] = 0x00;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 3);
|
||||
mdelay(10);
|
||||
|
||||
// Reset I2C offset address
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
// Read I2C bus status
|
||||
ret = ct36x_chip_get_busstatus(client, buf);
|
||||
if ( ret != 0xAA ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Prepare code segment
|
||||
*/
|
||||
static int ct36x_chip_set_code(unsigned int flash_addr, unsigned char *buf)
|
||||
{
|
||||
unsigned char cod_chksum;
|
||||
|
||||
//if ( CT36X_TS_CHIP_DEBUG )
|
||||
//printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Flash address
|
||||
// data length
|
||||
buf[2] = (char)(flash_addr >> 8);
|
||||
buf[3] = (char)(flash_addr & 0xFF);
|
||||
buf[4] = 0x08;
|
||||
|
||||
// Fill firmware source data
|
||||
//if ( (sec == 1 && cod == 4) || (sec == 1 && cod == 5) ) {
|
||||
//if ( flash_addr == (CT36X_CHIP_FLASH_SECTOR_SIZE + 32) ||
|
||||
//flash_addr == (CT36X_CHIP_FLASH_SECTOR_SIZE + 40) ) {
|
||||
if ( flash_addr == (160) || flash_addr == (168) ) {
|
||||
buf[6] = ~binary_data[flash_addr + 0];
|
||||
buf[7] = ~binary_data[flash_addr + 1];
|
||||
buf[8] = ~binary_data[flash_addr + 2];
|
||||
buf[9] = ~binary_data[flash_addr + 3];
|
||||
buf[10] = ~binary_data[flash_addr + 4];
|
||||
buf[11] = ~binary_data[flash_addr + 5];
|
||||
buf[12] = ~binary_data[flash_addr + 6];
|
||||
buf[13] = ~binary_data[flash_addr + 7];
|
||||
} else {
|
||||
buf[6] = binary_data[flash_addr + 0];
|
||||
buf[7] = binary_data[flash_addr + 1];
|
||||
buf[8] = binary_data[flash_addr + 2];
|
||||
buf[9] = binary_data[flash_addr + 3];
|
||||
buf[10] = binary_data[flash_addr + 4];
|
||||
buf[11] = binary_data[flash_addr + 5];
|
||||
buf[12] = binary_data[flash_addr + 6];
|
||||
buf[13] = binary_data[flash_addr + 7];
|
||||
}
|
||||
|
||||
/* Calculate a checksum by Host controller.
|
||||
** Checksum = ~(FLASH_ADRH+FLASH_ADRL+LENGTH+
|
||||
** Binary_Data1+Binary_Data2+Binary_Data3+Binary_Data4+
|
||||
** Binary_Data5+Binary_Data6+Binary_Data7+Binary_Data8) + 1
|
||||
*/
|
||||
cod_chksum = ~(buf[2]+buf[3]+buf[4]+
|
||||
buf[6]+buf[7]+buf[8]+buf[9]+
|
||||
buf[10]+buf[11]+buf[12]+buf[13]) + 1;
|
||||
buf[5] = cod_chksum;
|
||||
|
||||
return cod_chksum;
|
||||
}
|
||||
|
||||
static int ct36x_chip_write_firmware(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
int sec, cod;
|
||||
unsigned char cod_chksum;
|
||||
unsigned int fin_chksum;
|
||||
unsigned int flash_addr;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Code checksum, final checksum
|
||||
cod_chksum = 0x00; fin_chksum = 0x00;
|
||||
|
||||
// Flash write command
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x55;
|
||||
|
||||
// 256 sectors, 128 bytes per sectors
|
||||
for ( sec = 0; sec < CT36X_CHIP_FLASH_SECTOR_NUM; sec++ ) {
|
||||
flash_addr = sec * CT36X_CHIP_FLASH_SECTOR_SIZE;
|
||||
// 16 segments, 8 bytes per segment
|
||||
for ( cod = 0; cod < (CT36X_CHIP_FLASH_SECTOR_SIZE/CT36X_CHIP_FLASH_SOURCE_SIZE); cod++ ) {
|
||||
// Fill binary data
|
||||
cod_chksum = ct36x_chip_set_code(flash_addr, buf);
|
||||
fin_chksum += cod_chksum;
|
||||
|
||||
// Write firmware source data
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 14);
|
||||
|
||||
//
|
||||
mdelay(1);
|
||||
|
||||
// Increase flash address 8bytes for each write command
|
||||
flash_addr += CT36X_CHIP_FLASH_SOURCE_SIZE;
|
||||
}
|
||||
//
|
||||
mdelay(20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ct36x_chip_read_infoblk(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ct36x_chip_erase_infoblk(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// info block erase command
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x60;
|
||||
buf[2] = 0x00;
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 3);
|
||||
mdelay(10);
|
||||
|
||||
// Reset I2C offset address
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
// Read I2C bus status
|
||||
ret = ct36x_chip_get_busstatus(client, buf);
|
||||
if ( ret != 0xAA ) {
|
||||
printk("trim data erase error!!! \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ct36x_chip_write_infoblk(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
//int ret = -1;
|
||||
int sec, cod;
|
||||
unsigned int flash_addr;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
flash_addr = 0x00;
|
||||
|
||||
// write info block 0
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x61;
|
||||
|
||||
for ( cod = 0; cod < 16; cod++ ) {
|
||||
// Flash address
|
||||
// data length
|
||||
buf[2] = (char)(flash_addr >> 8);
|
||||
buf[3] = (char)(flash_addr & 0xFF);
|
||||
buf[4] = 0x08;
|
||||
if ( flash_addr == 0x0000 )
|
||||
buf[6] = 0x17;
|
||||
else
|
||||
buf[6] = 0x00;
|
||||
|
||||
buf[7] = 0x00;
|
||||
buf[8] = 0x00;
|
||||
buf[9] = 0x00;
|
||||
buf[10] = 0x00;
|
||||
buf[11] = 0x00;
|
||||
buf[12] = 0x00;
|
||||
buf[13] = 0x00;
|
||||
|
||||
buf[5] = (~(buf[2]+buf[3]+buf[4]+buf[6]+buf[7]+buf[8]+buf[9]+buf[10]+buf[11]+buf[12]+buf[13]))+1;
|
||||
|
||||
ct36x_ts_reg_write(client, 0x7F, buf, 14);
|
||||
mdelay(10);
|
||||
|
||||
flash_addr += 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ct36x_chip_get_binchksum(unsigned char *buf)
|
||||
{
|
||||
int sec, cod;
|
||||
unsigned char cod_chksum;
|
||||
unsigned int fin_chksum = 0;
|
||||
unsigned int flash_addr;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// 256 sectors, 128 bytes per sectors
|
||||
for ( sec = 0; sec < CT36X_CHIP_FLASH_SECTOR_NUM; sec++ ) {
|
||||
flash_addr = sec * CT36X_CHIP_FLASH_SECTOR_SIZE;
|
||||
// 16 segments, 8 bytes per segment
|
||||
for ( cod = 0; cod < (CT36X_CHIP_FLASH_SECTOR_SIZE/CT36X_CHIP_FLASH_SOURCE_SIZE); cod++ ) {
|
||||
// Fill binary data
|
||||
cod_chksum = ct36x_chip_set_code(flash_addr, buf);
|
||||
fin_chksum += cod_chksum;
|
||||
|
||||
// Increase flash address 8bytes for each write command
|
||||
flash_addr += CT36X_CHIP_FLASH_SOURCE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return (unsigned short)fin_chksum;
|
||||
}
|
||||
|
||||
int ct36x_chip_get_fwchksum(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int fwchksum = 0x00;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x8F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE1;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(500);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x8E;
|
||||
buf[2] = 0x0E;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
ct36x_ts_reg_read(client, client->addr, buf, 3);
|
||||
mdelay(20);
|
||||
|
||||
fwchksum = ((buf[0]<<8) | buf[1]);
|
||||
|
||||
return fwchksum;
|
||||
}
|
||||
|
||||
int ct36x_chip_get_ver(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Read version command
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x3F;
|
||||
buf[2] = 0xFF;
|
||||
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(10);
|
||||
|
||||
buf[0] = 0x00;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
// do read version
|
||||
ct36x_ts_reg_read(client, client->addr, buf, 1);
|
||||
mdelay(10);
|
||||
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
int ct36x_chip_get_vendor(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_chip_go_sleep(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x8F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xAF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
|
||||
//mdelay(50);
|
||||
}
|
||||
|
||||
int ct36x_chip_go_bootloader(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
// Init bootloader
|
||||
ct36x_chip_set_idle(client, buf);
|
||||
|
||||
// Reset I2C offset address
|
||||
ct36x_chip_rst_offset(client, buf);
|
||||
|
||||
// Get I2C bus status
|
||||
ret = ct36x_chip_get_busstatus(client, buf);
|
||||
if ( ret != 0xAA ) {
|
||||
printk("I2C bus status: 0x%x.\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// trim adc
|
||||
ct36x_chip_read_infoblk(client, buf);
|
||||
ct36x_chip_erase_infoblk(client, buf);
|
||||
ct36x_chip_write_infoblk(client, buf);
|
||||
|
||||
// Erase flash
|
||||
//ret = ct36x_chip_erase_flash(client, buf);
|
||||
//if ( ret ) {
|
||||
// printk("Erase flash failed.\n");
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
// Write source data
|
||||
//ct36x_chip_write_firmware(client, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_chip_set_adapter_on(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE3;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
}
|
||||
|
||||
void ct36x_chip_set_adapter_off(struct i2c_client *client, unsigned char *buf)
|
||||
{
|
||||
if ( CT36X_TS_CHIP_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
buf[0] = 0xFF;
|
||||
buf[1] = 0x0F;
|
||||
buf[2] = 0xFF;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 3);
|
||||
mdelay(3);
|
||||
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0xE2;
|
||||
ct36x_ts_reg_write(client, client->addr, buf, 2);
|
||||
mdelay(3);
|
||||
}
|
||||
|
||||
96
drivers/input/touchscreen/ct36x_ts/ct365.h
Normal file
96
drivers/input/touchscreen/ct36x_ts/ct365.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef CT365_H
|
||||
#define CT365_H
|
||||
|
||||
#define CT36X_TS_CHIP_DEBUG 0
|
||||
|
||||
/* max touch points supported */
|
||||
#define CT36X_TS_POINT_NUM 10
|
||||
|
||||
#define CT36X_TS_ABS_X_MAX 1280
|
||||
#define CT36X_TS_ABS_Y_MAX 800
|
||||
|
||||
/* data structure of point event */
|
||||
/* Old Touch Points Protocol
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte0|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Finger ID|Statu|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte1|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte2|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Y High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte3|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X Low |X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte4|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Area |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte5|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Pressure |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
/* New Touch Points Protocol
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte0|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte1|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Y High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte2|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|X Low |X High |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte3|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Finger ID|Statu|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte4|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Area |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
Byte5|Bit|7|6|5|4|3|2|1|0|
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
|Pressure |
|
||||
---------+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
struct ct36x_finger_info {
|
||||
#ifndef CONFIG_TOUCHSCREEN_CT36X_MISC_NEW_TPS
|
||||
unsigned char status : 3; // Action information, 1: Down; 2: Move; 3: Up
|
||||
unsigned char id : 5; // ID information, from 1 to CFG_MAX_POINT_NUM
|
||||
#endif
|
||||
unsigned char xhi; // X coordinate Hi
|
||||
unsigned char yhi; // Y coordinate Hi
|
||||
unsigned char ylo : 4; // Y coordinate Lo
|
||||
unsigned char xlo : 4; // X coordinate Lo
|
||||
#ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_NEW_TPS
|
||||
unsigned char status : 3; // Action information, 1: Down; 2: Move; 3: Up
|
||||
unsigned char id : 5; // ID information, from 1 to CFG_MAX_POINT_NUM
|
||||
#endif
|
||||
unsigned char area; // Touch area
|
||||
unsigned char pressure; // Touch Pressure
|
||||
};
|
||||
|
||||
|
||||
int ct36x_chip_get_binchksum(unsigned char *buf);
|
||||
int ct36x_chip_get_fwchksum(struct i2c_client *client, unsigned char *buf);
|
||||
|
||||
int ct36x_chip_get_ver(struct i2c_client *client, unsigned char *buf);
|
||||
int ct36x_chip_get_vendor(struct i2c_client *client, unsigned char *buf);
|
||||
void ct36x_chip_go_sleep(struct i2c_client *client, unsigned char *buf);
|
||||
int ct36x_chip_go_bootloader(struct i2c_client *client, unsigned char *buf);
|
||||
|
||||
void ct36x_chip_set_adapter_on(struct i2c_client *client, unsigned char *buf);
|
||||
void ct36x_chip_set_adapter_off(struct i2c_client *client, unsigned char *buf);
|
||||
#endif
|
||||
109
drivers/input/touchscreen/ct36x_ts/generic.c
Normal file
109
drivers/input/touchscreen/ct36x_ts/generic.c
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "tscore.h"
|
||||
#include "generic.h"
|
||||
|
||||
|
||||
static struct i2c_device_id ct36x_ts_id[] = {
|
||||
{ DRIVER_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
struct i2c_driver ct36x_ts_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRIVER_NAME
|
||||
},
|
||||
.id_table = ct36x_ts_id,
|
||||
.probe = ct36x_ts_probe,
|
||||
.suspend = ct36x_ts_suspend,
|
||||
.resume = ct36x_ts_resume,
|
||||
.remove = __devexit_p(ct36x_ts_remove),
|
||||
};
|
||||
|
||||
void ct36x_ts_reg_read(struct i2c_client *client, unsigned short addr, char *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs;
|
||||
|
||||
msgs.addr = addr;
|
||||
msgs.flags = 0x01; // 0x00: write 0x01:read
|
||||
msgs.len = len;
|
||||
msgs.buf = buf;
|
||||
msgs.scl_rate = CT36X_TS_I2C_SPEED;
|
||||
|
||||
i2c_transfer(client->adapter, &msgs, 1);
|
||||
}
|
||||
|
||||
void ct36x_ts_reg_write(struct i2c_client *client, unsigned short addr, char *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs;
|
||||
|
||||
msgs.addr = addr;
|
||||
msgs.flags = 0x00; // 0x00: write 0x01:read
|
||||
msgs.len = len;
|
||||
msgs.buf = buf;
|
||||
msgs.scl_rate = CT36X_TS_I2C_SPEED;
|
||||
|
||||
i2c_transfer(client->adapter, &msgs, 1);
|
||||
}
|
||||
|
||||
void ct36x_platform_get_cfg(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
/* I2C config */
|
||||
//ct36x_ts->i2c_bus = CT36X_TS_I2C_BUS;
|
||||
//ct36x_ts->i2c_address = CT36X_TS_I2C_ADDRESS;
|
||||
|
||||
/* GPIO config */
|
||||
//ct36x_ts->rst = ct36x_ts->pdata->rst;
|
||||
//ct36x_ts->ss = ct36x_ts->pdata->ss;
|
||||
|
||||
/* IRQ config*/
|
||||
ct36x_ts->irq = gpio_to_irq(ct36x_ts->ss);
|
||||
|
||||
ct36x_ts->ready = 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_set_dev(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_get_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
// Init Reset pin
|
||||
err = gpio_request(ct36x_ts->rst, "ct36x_ts_rst");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_output(ct36x_ts->rst, 1);
|
||||
gpio_set_value(ct36x_ts->rst, 1);
|
||||
|
||||
// Init Int pin
|
||||
err = gpio_request(ct36x_ts->ss, "ct36x_ts_int");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_input(ct36x_ts->ss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_platform_put_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
gpio_free(ct36x_ts->rst);
|
||||
gpio_free(ct36x_ts->ss);
|
||||
}
|
||||
|
||||
void ct36x_platform_hw_reset(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
mdelay(500);
|
||||
gpio_set_value(ct36x_ts->rst, 0);
|
||||
mdelay(50);
|
||||
gpio_set_value(ct36x_ts->rst, 1);
|
||||
mdelay(500);
|
||||
}
|
||||
8
drivers/input/touchscreen/ct36x_ts/generic.h
Normal file
8
drivers/input/touchscreen/ct36x_ts/generic.h
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef GENERIC_H
|
||||
#define GENERIC_H
|
||||
|
||||
#define CT36X_TS_I2C_SPEED 400000
|
||||
|
||||
#endif
|
||||
|
||||
22
drivers/input/touchscreen/ct36x_ts/platform.h
Normal file
22
drivers/input/touchscreen/ct36x_ts/platform.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
// Platform data
|
||||
struct ct36x_platform_data {
|
||||
int rst;
|
||||
int ss;
|
||||
};
|
||||
|
||||
extern struct i2c_driver ct36x_ts_driver;
|
||||
|
||||
void ct36x_ts_reg_read(struct i2c_client *client, unsigned short addr, char *buf, int len);
|
||||
void ct36x_ts_reg_write(struct i2c_client *client, unsigned short addr, char *buf, int len);
|
||||
|
||||
void ct36x_platform_get_cfg(struct ct36x_ts_info *ct36x_ts);
|
||||
int ct36x_platform_set_dev(struct ct36x_ts_info *ct36x_ts);
|
||||
|
||||
int ct36x_platform_get_resource(struct ct36x_ts_info *ct36x_ts);
|
||||
void ct36x_platform_put_resource(struct ct36x_ts_info *ct36x_ts);
|
||||
|
||||
void ct36x_platform_hw_reset(struct ct36x_ts_info *ct36x_ts);
|
||||
#endif
|
||||
136
drivers/input/touchscreen/ct36x_ts/rockchip.c
Normal file
136
drivers/input/touchscreen/ct36x_ts/rockchip.c
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "tscore.h"
|
||||
#include "rockchip.h"
|
||||
|
||||
|
||||
|
||||
static struct i2c_device_id ct36x_ts_id[] = {
|
||||
{ DRIVER_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_board_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO(DRIVER_NAME, 0x01),
|
||||
.platform_data = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
struct i2c_driver ct36x_ts_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRIVER_NAME
|
||||
},
|
||||
.id_table = ct36x_ts_id,
|
||||
.probe = ct36x_ts_probe,
|
||||
.shutdown = ct36x_ts_shutdown,
|
||||
.suspend = ct36x_ts_suspend,
|
||||
.resume = ct36x_ts_resume,
|
||||
.remove = __devexit_p(ct36x_ts_remove),
|
||||
};
|
||||
|
||||
void ct36x_ts_reg_read(struct i2c_client *client, unsigned short addr, char *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs;
|
||||
|
||||
msgs.addr = addr;
|
||||
msgs.flags = 0x01; // 0x00: write 0x01:read
|
||||
msgs.len = len;
|
||||
msgs.buf = buf;
|
||||
msgs.scl_rate = CT36X_TS_I2C_SPEED;
|
||||
|
||||
i2c_transfer(client->adapter, &msgs, 1);
|
||||
}
|
||||
|
||||
void ct36x_ts_reg_write(struct i2c_client *client, unsigned short addr, char *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs;
|
||||
|
||||
msgs.addr = addr;
|
||||
msgs.flags = 0x00; // 0x00: write 0x01:read
|
||||
msgs.len = len;
|
||||
msgs.buf = buf;
|
||||
msgs.scl_rate = CT36X_TS_I2C_SPEED;
|
||||
|
||||
i2c_transfer(client->adapter, &msgs, 1);
|
||||
}
|
||||
|
||||
void ct36x_platform_get_cfg(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
/* I2C config */
|
||||
ct36x_ts->i2c_bus = CT36X_TS_I2C_BUS;
|
||||
ct36x_ts->i2c_address = CT36X_TS_I2C_ADDRESS;
|
||||
|
||||
/* GPIO config */
|
||||
ct36x_ts->rst = CT36X_TS_RST_PIN;
|
||||
ct36x_ts->ss = CT36X_TS_IRQ_PIN;
|
||||
|
||||
/* IRQ config*/
|
||||
ct36x_ts->irq = gpio_to_irq(ct36x_ts->ss);
|
||||
|
||||
ct36x_ts->ready = 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_set_dev(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *client;
|
||||
|
||||
adapter = i2c_get_adapter(ct36x_ts->i2c_bus);
|
||||
if ( !adapter ) {
|
||||
printk("Unable to get i2c adapter on bus %d.\n", ct36x_ts->i2c_bus);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
client = i2c_new_device(adapter, i2c_board_info);
|
||||
i2c_put_adapter(adapter);
|
||||
if (!client) {
|
||||
printk("Unable to create i2c device on bus %d.\n", ct36x_ts->i2c_bus);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ct36x_ts->client = client;
|
||||
i2c_set_clientdata(client, ct36x_ts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ct36x_platform_get_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
// Init Reset pin
|
||||
err = gpio_request(ct36x_ts->rst, "ct36x_ts_rst");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_output(ct36x_ts->rst, 1);
|
||||
gpio_set_value(ct36x_ts->rst, 1);
|
||||
|
||||
// Init Int pin
|
||||
err = gpio_request(ct36x_ts->ss, "ct36x_ts_int");
|
||||
if ( err ) {
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_input(ct36x_ts->ss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ct36x_platform_put_resource(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
gpio_free(ct36x_ts->rst);
|
||||
gpio_free(ct36x_ts->ss);
|
||||
}
|
||||
|
||||
void ct36x_platform_hw_reset(struct ct36x_ts_info *ct36x_ts)
|
||||
{
|
||||
mdelay(500);
|
||||
gpio_set_value(ct36x_ts->rst, 0);
|
||||
mdelay(50);
|
||||
gpio_set_value(ct36x_ts->rst, 1);
|
||||
mdelay(500);
|
||||
}
|
||||
15
drivers/input/touchscreen/ct36x_ts/rockchip.h
Normal file
15
drivers/input/touchscreen/ct36x_ts/rockchip.h
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef ROCKCHIP_H
|
||||
#define ROCKCHIP_H
|
||||
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#define CT36X_TS_I2C_BUS 2 // I2C Bus
|
||||
#define CT36X_TS_I2C_ADDRESS 0x01
|
||||
#define CT36X_TS_I2C_SPEED 400000
|
||||
|
||||
#define CT36X_TS_IRQ_PIN RK30_PIN4_PC2
|
||||
#define CT36X_TS_RST_PIN RK30_PIN4_PD0
|
||||
|
||||
#endif
|
||||
|
||||
572
drivers/input/touchscreen/ct36x_ts/tscore.c
Normal file
572
drivers/input/touchscreen/ct36x_ts/tscore.c
Normal file
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* drivers/input/touchscreen/ct36x_ts.c
|
||||
*
|
||||
* VTL ct36x TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010 VTL tech Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* George Chen, 2012-06-15
|
||||
*/
|
||||
|
||||
// ****************************************************************************
|
||||
// Includes
|
||||
// ****************************************************************************
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
|
||||
#include "tscore.h"
|
||||
#include "platform.h"
|
||||
|
||||
enum enum_ct36x_ts_cmds {
|
||||
CT36X_TS_CHIP_ID,
|
||||
CT36X_TS_CHIP_RESET,
|
||||
CT36X_TS_FW_VER,
|
||||
CT36X_TS_FW_CHKSUM,
|
||||
CT36X_TS_FW_UPDATE,
|
||||
CT36X_TS_BIN_VER,
|
||||
CT36X_TS_BIN_CHKSUM,
|
||||
};
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Globel or static variables
|
||||
// ****************************************************************************
|
||||
static struct ct36x_ts_info ct36x_ts;
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Function declaration
|
||||
// ****************************************************************************
|
||||
int ct36x_cmd_list_ind[] = {
|
||||
CT36X_TS_CHIP_ID,
|
||||
CT36X_TS_CHIP_RESET,
|
||||
CT36X_TS_FW_VER,
|
||||
CT36X_TS_FW_CHKSUM,
|
||||
CT36X_TS_FW_UPDATE,
|
||||
CT36X_TS_BIN_VER,
|
||||
CT36X_TS_BIN_CHKSUM,
|
||||
};
|
||||
|
||||
char ct36x_cmd_list_cmd[] = { 'i','r','v','c','u','b','k',0, };
|
||||
|
||||
static int ct36x_ts_cmd(char *cmdlist, const char cmd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// search cmd
|
||||
while ( cmdlist[i] ) {
|
||||
if ( cmd == cmdlist[i] )
|
||||
return ct36x_cmd_list_ind[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ct36x_ts_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ct36x_ts_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ct36x_ts_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset)
|
||||
{
|
||||
int cmd = 0;
|
||||
int rslt = 0;
|
||||
|
||||
if ( CT36X_TS_CORE_DEBUG ) {
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
printk("%s(): count=0x%x \n", __FUNCTION__, count);
|
||||
}
|
||||
|
||||
// search cmd
|
||||
cmd = ct36x_ts_cmd(ct36x_cmd_list_cmd, buffer[0]);
|
||||
|
||||
switch ( cmd ) {
|
||||
case CT36X_TS_CHIP_ID:
|
||||
break;
|
||||
|
||||
case CT36X_TS_CHIP_RESET:
|
||||
printk("%s(): CT36X_TS_CHIP_RESET\n", __FUNCTION__);
|
||||
ct36x_platform_hw_reset(&ct36x_ts);
|
||||
break;
|
||||
|
||||
case CT36X_TS_FW_VER:
|
||||
break;
|
||||
|
||||
case CT36X_TS_FW_CHKSUM:
|
||||
printk("%s(): CT36X_TS_FW_CHKSUM\n", __FUNCTION__);
|
||||
rslt = ct36x_chip_get_fwchksum(ct36x_ts.client, ct36x_ts.data.buf);
|
||||
printk("%s(): Fw checksum: 0x%x\n", __FUNCTION__, rslt);
|
||||
break;
|
||||
|
||||
case CT36X_TS_FW_UPDATE:
|
||||
printk("%s(): CT36X_TS_FW_UPDATE\n", __FUNCTION__);
|
||||
ct36x_chip_go_bootloader(ct36x_ts.client, ct36x_ts.data.buf);
|
||||
break;
|
||||
|
||||
case CT36X_TS_BIN_VER:
|
||||
break;
|
||||
|
||||
case CT36X_TS_BIN_CHKSUM:
|
||||
printk("%s(): CT36X_TS_BIN_CHKSUM\n", __FUNCTION__);
|
||||
rslt = ct36x_chip_get_binchksum(ct36x_ts.data.buf);
|
||||
printk("%s(): bin checksum: 0x%x\n", __FUNCTION__, rslt);
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("%s(): No such command (0x%x). \n", __FUNCTION__, buffer[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ct36x_ts_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
if ( CT36X_TS_CORE_DEBUG ) {
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
printk("%s(): count=0x%x \n", __FUNCTION__, count);
|
||||
}
|
||||
|
||||
if ( !ct36x_ts.ready )
|
||||
return 0;
|
||||
|
||||
//ct36x_ts_reg_read(ct36x_ts->client, buf[0], buf+1, buf[]);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct file_operations ct36x_ts_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ct36x_ts_open,
|
||||
.release = ct36x_ts_close,
|
||||
.write = ct36x_ts_write,
|
||||
.read = ct36x_ts_read,
|
||||
};
|
||||
|
||||
static irqreturn_t ct36x_ts_irq(int irq, void *dev)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = (struct ct36x_ts_info *)dev;
|
||||
|
||||
// touch device is ready??
|
||||
if ( ts->ready ) {
|
||||
// Disable ts interrupt
|
||||
disable_irq_nosync(ts->irq);
|
||||
|
||||
queue_work(ts->workqueue, &ts->event_work);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void ct36x_ts_workfunc(struct work_struct *work)
|
||||
{
|
||||
int iter;
|
||||
int sync;
|
||||
int x, y;
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = container_of(work, struct ct36x_ts_info, event_work);
|
||||
|
||||
/* read touch points */
|
||||
ct36x_ts_reg_read(ts->client, ts->i2c_address, (char *) ts->data.pts, sizeof(struct ct36x_finger_info) * CT36X_TS_POINT_NUM);
|
||||
|
||||
/* report points */
|
||||
sync = 0; ts->press = 0;
|
||||
for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
|
||||
if ( ts->data.pts[iter].xhi != 0xFF && ts->data.pts[iter].yhi != 0xFF &&
|
||||
(ts->data.pts[iter].status == 1 || ts->data.pts[iter].status == 2) ) {
|
||||
#ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_XY_SWAP
|
||||
x = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
|
||||
y = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
|
||||
#else
|
||||
x = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
|
||||
y = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
|
||||
#endif
|
||||
#ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_X_REVERSE
|
||||
x = CT36X_TS_ABS_X_MAX - x;
|
||||
#endif
|
||||
#ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_Y_REVERSE
|
||||
y = CT36X_TS_ABS_Y_MAX - y;
|
||||
#endif
|
||||
|
||||
if ( CT36X_TS_EVENT_DEBUG ) {
|
||||
printk("ID: %d\n", ts->data.pts[iter].id);
|
||||
printk("status: %d\n", ts->data.pts[iter].status);
|
||||
printk("X Lo: %d\n", ts->data.pts[iter].xlo);
|
||||
printk("Y Lo: %d\n", ts->data.pts[iter].ylo);
|
||||
printk("X Hi: %d\n", ts->data.pts[iter].xhi);
|
||||
printk("Y Hi: %d\n", ts->data.pts[iter].yhi);
|
||||
printk("X: %d\n", x);
|
||||
printk("Y: %d\n", y);
|
||||
}
|
||||
|
||||
input_report_abs(ts->input, ABS_MT_POSITION_X, x);
|
||||
input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
|
||||
|
||||
input_mt_sync(ts->input);
|
||||
|
||||
sync = 1;
|
||||
ts->press |= 0x01 << (ts->data.pts[iter].id - 1);
|
||||
}
|
||||
}
|
||||
|
||||
ts->release &= ts->release ^ ts->press;
|
||||
for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
|
||||
if ( ts->release & (0x01<<iter) ) {
|
||||
input_mt_sync(ts->input);
|
||||
sync = 1;
|
||||
}
|
||||
}
|
||||
ts->release = ts->press;
|
||||
|
||||
if ( sync ) input_sync(ts->input);
|
||||
|
||||
// Enable ts interrupt
|
||||
enable_irq(ts->irq);
|
||||
|
||||
}
|
||||
|
||||
static void ct36x_ts_adapter(int state)
|
||||
{
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
if ( !ct36x_ts.ready ) return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void ct36x_early_suspend(struct early_suspend *handler)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = container_of(handler, struct ct36x_ts_info, early_suspend);
|
||||
|
||||
ct36x_ts_suspend(ts->client, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static void ct36x_early_resume(struct early_suspend *handler)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = container_of(handler, struct ct36x_ts_info, early_suspend);
|
||||
|
||||
ct36x_ts_resume(ts->client);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
int err = -1;
|
||||
int binchksum, fwchksum;
|
||||
int updcnt;
|
||||
struct ct36x_ts_info *ts;
|
||||
struct ct36x_platform_data *pdata;
|
||||
struct device *dev;
|
||||
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
dev = &client->dev;
|
||||
|
||||
pdata = dev->platform_data;
|
||||
|
||||
if ( pdata ) {
|
||||
ct36x_ts.i2c_address = client->addr;
|
||||
ct36x_ts.rst = pdata->rst;
|
||||
ct36x_ts.ss = pdata->ss;
|
||||
ct36x_platform_get_cfg(&ct36x_ts);
|
||||
|
||||
ct36x_ts.client = client;
|
||||
i2c_set_clientdata(client, &ct36x_ts);
|
||||
} else {
|
||||
printk("No platform data for device %s.\n", DRIVER_NAME);
|
||||
}
|
||||
ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
|
||||
|
||||
/* Create Proc Entry File */
|
||||
ts->proc_entry = create_proc_entry(DRIVER_NAME, 0666/*S_IFREG | S_IRUGO | S_IWUSR*/, NULL);
|
||||
if ( ts->proc_entry == NULL ) {
|
||||
dev_err(dev, "Failed creating proc dir entry file.\n");
|
||||
} else {
|
||||
ts->proc_entry->proc_fops = &ct36x_ts_fops;
|
||||
}
|
||||
|
||||
/* register early suspend */
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
||||
ts->early_suspend.suspend = ct36x_early_suspend;
|
||||
ts->early_suspend.resume = ct36x_early_resume;
|
||||
register_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
|
||||
/* Check I2C Functionality */
|
||||
err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
|
||||
if ( !err ) {
|
||||
dev_err(dev, "Check I2C Functionality Failed.\n");
|
||||
goto ERR_I2C_CHK;
|
||||
}
|
||||
|
||||
/* Request platform resources (gpio/interrupt pins) */
|
||||
err = ct36x_platform_get_resource(ts);
|
||||
if ( err ) {
|
||||
dev_err(dev, "Unable to request platform resource for device %s.\n", DRIVER_NAME);
|
||||
goto ERR_PLAT_RSC;
|
||||
}
|
||||
|
||||
/* Hardware reset */
|
||||
ct36x_platform_hw_reset(ts);
|
||||
|
||||
// Get binary Checksum
|
||||
binchksum = ct36x_chip_get_binchksum(ts->data.buf);
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk("Bin checksum: 0x%x\n", binchksum);
|
||||
|
||||
// Get firmware Checksum
|
||||
fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk("Fw checksum: 0x%x\n", fwchksum);
|
||||
|
||||
updcnt = 5;
|
||||
while ( binchksum != fwchksum && updcnt--) {
|
||||
/* Update Firmware */
|
||||
ct36x_chip_go_bootloader(client, ts->data.buf);
|
||||
|
||||
/* Hardware reset */
|
||||
ct36x_platform_hw_reset(ts);
|
||||
|
||||
// Get firmware Checksum
|
||||
fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
|
||||
if ( CT36X_TS_CORE_DEBUG )
|
||||
printk("Fw checksum: 0x%x\n", fwchksum);
|
||||
}
|
||||
|
||||
printk("Fw update %s. 0x%x, 0x%x\n", binchksum != fwchksum ? "Failed" : "Success", binchksum, fwchksum);
|
||||
|
||||
/* Hardware reset */
|
||||
ct36x_platform_hw_reset(ts);
|
||||
|
||||
/* allocate input device */
|
||||
ts->input = input_allocate_device();
|
||||
if ( !ts->input ) {
|
||||
dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME);
|
||||
err = -ENOMEM;
|
||||
goto ERR_INPUT_ALLOC;
|
||||
}
|
||||
|
||||
/* config input device */
|
||||
__set_bit(EV_SYN, ts->input->evbit);
|
||||
__set_bit(EV_KEY, ts->input->evbit);
|
||||
__set_bit(EV_ABS, ts->input->evbit);
|
||||
|
||||
__set_bit(INPUT_PROP_DIRECT, ts->input->propbit);
|
||||
|
||||
input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0);
|
||||
input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0);
|
||||
|
||||
ts->input->name = DRIVER_NAME;
|
||||
ts->input->id.bustype = BUS_I2C;
|
||||
|
||||
/* register input device */
|
||||
err = input_register_device(ts->input);
|
||||
if ( err ) {
|
||||
dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME);
|
||||
goto ERR_INPUT_REGIS;
|
||||
}
|
||||
|
||||
/* Create work queue */
|
||||
INIT_WORK(&ts->event_work, ct36x_ts_workfunc);
|
||||
ts->workqueue = create_singlethread_workqueue(dev_name(&client->dev));
|
||||
|
||||
/* Init irq */
|
||||
err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts);
|
||||
if ( err ) {
|
||||
dev_err(dev, "Unable to request irq for device %s.\n", DRIVER_NAME);
|
||||
goto ERR_IRQ_REQ;
|
||||
}
|
||||
|
||||
/* Set device is ready */
|
||||
ts->ready = 1;
|
||||
ts->state = CT36X_STATE_NORMAL;
|
||||
|
||||
/* power denoisy*/
|
||||
//ct36x_chip_set_adapter_on(client, ts->data.buf);
|
||||
//ct36x_chip_set_adapter_off(client, ts->data.buf);
|
||||
ct36x_ts_adapter(0);
|
||||
|
||||
return 0;
|
||||
|
||||
ERR_IRQ_REQ:
|
||||
destroy_workqueue(ts->workqueue);
|
||||
ERR_INPUT_REGIS:
|
||||
input_free_device(ts->input);
|
||||
ERR_INPUT_ALLOC:
|
||||
ERR_PLAT_RSC:
|
||||
ct36x_platform_put_resource(ts);
|
||||
ERR_I2C_CHK:
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
remove_proc_entry(DRIVER_NAME, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
void ct36x_ts_shutdown(struct i2c_client *client)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
|
||||
|
||||
ct36x_chip_go_sleep(client, ts->data.buf);
|
||||
}
|
||||
|
||||
int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
|
||||
|
||||
if ( ts->state == CT36X_STATE_SLEEP ) return 0;
|
||||
|
||||
disable_irq(ts->irq);
|
||||
|
||||
cancel_work_sync(&ts->event_work);
|
||||
|
||||
ct36x_chip_go_sleep(client, ts->data.buf);
|
||||
|
||||
ts->state = CT36X_STATE_SLEEP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ct36x_ts_resume(struct i2c_client *client)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
|
||||
|
||||
if ( ts->state == CT36X_STATE_NORMAL ) return 0;
|
||||
|
||||
/* Hardware reset */
|
||||
ct36x_platform_hw_reset(ts);
|
||||
|
||||
enable_irq(ts->irq);
|
||||
|
||||
ts->state = CT36X_STATE_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devexit ct36x_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ct36x_ts_info *ts;
|
||||
|
||||
if (CT36X_TS_CORE_DEBUG)
|
||||
printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
|
||||
|
||||
ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
|
||||
|
||||
/* Driver clean up */
|
||||
disable_irq(ts->irq);
|
||||
cancel_work_sync(&ts->event_work);
|
||||
destroy_workqueue(ts->workqueue);
|
||||
input_free_device(ts->input);
|
||||
free_irq(ts->irq, ts);
|
||||
ct36x_platform_put_resource(ts);
|
||||
i2c_unregister_device(client);
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
remove_proc_entry(DRIVER_NAME, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init ct36x_ts_init(void)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
printk("VTL ct36x TouchScreen driver, <george.chen@vtl.com.cn>.\n");
|
||||
|
||||
ct36x_platform_get_cfg(&ct36x_ts);
|
||||
|
||||
err = ct36x_platform_set_dev(&ct36x_ts);
|
||||
if ( err ) goto ERR_INIT;
|
||||
|
||||
err = i2c_add_driver(&ct36x_ts_driver);
|
||||
if ( err ) goto ERR_INIT;
|
||||
|
||||
return 0;
|
||||
|
||||
ERR_INIT:
|
||||
return err;
|
||||
}
|
||||
|
||||
void __exit ct36x_ts_exit(void)
|
||||
{
|
||||
i2c_del_driver(&ct36x_ts_driver);
|
||||
}
|
||||
|
||||
module_init(ct36x_ts_init);
|
||||
module_exit(ct36x_ts_exit);
|
||||
|
||||
MODULE_AUTHOR("<george.chen@vtl.com>");
|
||||
MODULE_DESCRIPTION("VTL ct36x TouchScreen driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
80
drivers/input/touchscreen/ct36x_ts/tscore.h
Normal file
80
drivers/input/touchscreen/ct36x_ts/tscore.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef TSCORE_H
|
||||
#define TSCORE_H
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#endif
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
// ****************************************************************************
|
||||
// Defines
|
||||
// ****************************************************************************
|
||||
#define CT36X_TS_CORE_DEBUG 0
|
||||
#define CT36X_TS_EVENT_DEBUG 0
|
||||
|
||||
|
||||
#define DRIVER_NAME "ct36x_ts"
|
||||
|
||||
enum enum_ct36x_state {
|
||||
CT36X_STATE_INIT,
|
||||
CT36X_STATE_NORMAL,
|
||||
CT36X_STATE_SLEEP,
|
||||
CT36X_STATE_UPDATE,
|
||||
};
|
||||
|
||||
union ct36x_i2c_data {
|
||||
struct ct36x_finger_info pts[CT36X_TS_POINT_NUM];
|
||||
unsigned char buf[CT36X_TS_POINT_NUM * sizeof(struct ct36x_finger_info)];
|
||||
};
|
||||
|
||||
struct ct36x_ts_info {
|
||||
/* Chip ID */
|
||||
int chip_id;
|
||||
|
||||
// Communication settings
|
||||
int i2c_bus;
|
||||
unsigned short i2c_address;
|
||||
struct i2c_client *client;
|
||||
|
||||
// Devices
|
||||
struct input_dev *input;
|
||||
int irq;
|
||||
int rst;
|
||||
int ss;
|
||||
int ready;
|
||||
int state;
|
||||
|
||||
// Early suspend
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
|
||||
// Proc Control
|
||||
struct proc_dir_entry *proc_entry;
|
||||
|
||||
// Work thread settings
|
||||
struct work_struct event_work;
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
// touch event data
|
||||
union ct36x_i2c_data data;
|
||||
|
||||
int press;
|
||||
int release;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id);
|
||||
void ct36x_ts_shutdown(struct i2c_client *client);
|
||||
int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg);
|
||||
int ct36x_ts_resume(struct i2c_client *client);
|
||||
int __devexit ct36x_ts_remove(struct i2c_client *client);
|
||||
|
||||
int __init ct36x_ts_init(void);
|
||||
void __exit ct36x_ts_exit(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1793
drivers/input/touchscreen/ft5506_app.f
Normal file
1793
drivers/input/touchscreen/ft5506_app.f
Normal file
File diff suppressed because it is too large
Load Diff
1172
drivers/input/touchscreen/ft5506_wgj.c
Normal file
1172
drivers/input/touchscreen/ft5506_wgj.c
Normal file
File diff suppressed because it is too large
Load Diff
120
drivers/input/touchscreen/ft5506_wgj.h
Normal file
120
drivers/input/touchscreen/ft5506_wgj.h
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef __LINUX_FT5X0X_TS_H__
|
||||
#define __LINUX_FT5X0X_TS_H__
|
||||
|
||||
//#define CONFIG_SUPPORT_FTS_CTP_UPG
|
||||
#define CONFIG_FTS_CUSTOME_ENV
|
||||
|
||||
#define FT5X0X_I2C_SPEED 200*1000
|
||||
|
||||
#define CFG_DBG_DUMMY_INFO_SUPPORT 1 //output touch point information
|
||||
#define CFG_DBG_FUCTION_INFO_SUPPORT 0 //output fouction name
|
||||
#define CFG_DBG_INPUT_EVENT 1 //debug input event
|
||||
|
||||
|
||||
#define CFG_MAX_POINT_NUM 10 //max touch points supported
|
||||
#define CFG_NUMOFKEYS 0x00//0x4 //number of touch keys
|
||||
|
||||
#ifdef CONFIG_FTS_CUSTOME_ENV
|
||||
//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD>ӱ߽绮<DFBD><E7BBAE>ʱ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>꽫<EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define SCREEN_BOUNDARY_ADJUST_VALUE 10
|
||||
|
||||
#define SCREEN_MAX_X 1280
|
||||
#define SCREEN_MAX_Y 800//600
|
||||
#else
|
||||
#define SCREEN_MAX_X 1024
|
||||
#define SCREEN_MAX_Y 768
|
||||
#endif
|
||||
#define PRESS_MAX 255
|
||||
|
||||
#define KEY_PRESS 0x1
|
||||
#define KEY_RELEASE 0x0
|
||||
|
||||
#define FT5X0X_NAME "laibao_touch"//"ft5x0x_ts"
|
||||
|
||||
#define FTS_NULL 0x0
|
||||
#define FTS_TRUE 0x1
|
||||
#define FTS_FALSE 0x0
|
||||
#define I2C_CTPM_ADDRESS 0x70
|
||||
|
||||
typedef unsigned char FTS_BYTE;
|
||||
typedef unsigned short FTS_WORD;
|
||||
typedef unsigned int FTS_DWRD;
|
||||
typedef unsigned char FTS_BOOL;
|
||||
|
||||
|
||||
|
||||
typedef struct _REPORT_FINGER_INFO_T
|
||||
{
|
||||
short ui2_id; /* ID information, from 0 to CFG_MAX_POINT_NUM - 1*/
|
||||
short u2_pressure; /* ***pressure information, valid from 0 -63 **********/
|
||||
short i2_x; /*********** X coordinate, 0 - 2047 ****************/
|
||||
short i2_y; /* **********Y coordinate, 0 - 2047 ****************/
|
||||
} REPORT_FINGER_INFO_T;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_OK,
|
||||
ERR_MODE,
|
||||
ERR_READID,
|
||||
ERR_ERASE,
|
||||
ERR_STATUS,
|
||||
ERR_ECC,
|
||||
ERR_DL_ERASE_FAIL,
|
||||
ERR_DL_PROGRAM_FAIL,
|
||||
ERR_DL_VERIFY_FAIL
|
||||
}E_UPGRADE_ERR_TYPE;
|
||||
|
||||
|
||||
struct FTS_TS_EVENT_T {
|
||||
short x1;
|
||||
short y1;
|
||||
short x2;
|
||||
short y2;
|
||||
short x3;
|
||||
short y3;
|
||||
short x4;
|
||||
short y4;
|
||||
short x5;
|
||||
short y5;
|
||||
short pressure1;
|
||||
short pressure2;
|
||||
short pressure3;
|
||||
short pressure4;
|
||||
short pressure5;
|
||||
u8 touch_point;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
enum ft5x0x_ts_regs {
|
||||
FT5X0X_REG_THRES = 0x80, /* Thresshold, the threshold be low, the sensitivy will be high */
|
||||
FT5X0X_REG_REPORT_RATE = 0x88, /* **************report rate, in unit of 10Hz **************/
|
||||
FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode 0 -- active, 1 -- monitor, 3 -- sleep */
|
||||
FT5X0X_REG_FIRMID = 0xA6, /* ***************firmware version **********************/
|
||||
FT5X0X_REG_NOISE_MODE = 0xb2 /* to enable or disable power noise, 1 -- enable, 0 -- disable */
|
||||
};
|
||||
|
||||
#define PMODE_ACTIVE 0x00
|
||||
#define PMODE_MONITOR 0x01
|
||||
#define PMODE_STANDBY 0x02
|
||||
#define PMODE_HIBERNATE 0x03
|
||||
|
||||
|
||||
#ifndef ABS_MT_TOUCH_MAJOR
|
||||
#define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */
|
||||
#define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */
|
||||
#define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */
|
||||
#define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */
|
||||
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
|
||||
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
|
||||
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
|
||||
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
|
||||
#define ABS_MT_BLOB_ID 0x38 /* Group set of pkts as blob */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#
|
||||
# 3G device configuration
|
||||
#
|
||||
|
||||
menuconfig 3G_MODULE
|
||||
tristate "3G module for phonepad"
|
||||
---help---
|
||||
Say Y here if you have a support modem
|
||||
|
||||
choice
|
||||
depends on 3G_MODULE
|
||||
prompt "Select 3G Module"
|
||||
|
||||
config MU509
|
||||
bool "MU509"
|
||||
|
||||
config MT6229
|
||||
bool "MT6229"
|
||||
|
||||
config MW100
|
||||
bool "MW100"
|
||||
|
||||
config SEW868
|
||||
bool "SEW868"
|
||||
|
||||
config MI700
|
||||
bool "MI700"
|
||||
config SC6610
|
||||
bool "SC6610"
|
||||
endchoice
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
obj-$(CONFIG_MU509) += mu509.o
|
||||
obj-$(CONFIG_MW100) += mw100.o
|
||||
obj-$(CONFIG_MT6229) += mt6229.o
|
||||
obj-$(CONFIG_SEW868) += sew868.o
|
||||
obj-$(CONFIG_MI700) += mi700.o
|
||||
obj-$(CONFIG_SC6610) += sc6610.o
|
||||
@@ -1,352 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mi700.h>
|
||||
#include <mach/iomux.h>
|
||||
#include<linux/ioctl.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
|
||||
#define MW100IO 0XA1
|
||||
#define MW_IOCTL_RESET _IO(MW100IO,0X01)
|
||||
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
#define MI700_RESET 0x01
|
||||
static struct wake_lock modem_wakelock;
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
struct rk29_mi700_data *gpdata = NULL;
|
||||
static int bp_wakeup_ap_irq = 0;
|
||||
struct class *modem_class = NULL;
|
||||
static int do_wakeup_irq = 1;
|
||||
static int modem_status;
|
||||
static int online = 0;
|
||||
|
||||
static void ap_wakeup_bp(struct platform_device *pdev, int wake)
|
||||
{
|
||||
struct rk29_mi700_data *pdata = pdev->dev.platform_data;
|
||||
MODEMDBG("ap_wakeup_bp\n");
|
||||
|
||||
gpio_set_value(pdata->ap_wakeup_bp, wake);
|
||||
|
||||
}
|
||||
extern void rk28_send_wakeup_key(void);
|
||||
|
||||
static void do_wakeup(struct work_struct *work)
|
||||
{
|
||||
MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
//rk28_send_wakeup_key();
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
if(do_wakeup_irq)
|
||||
{
|
||||
do_wakeup_irq = 0;
|
||||
printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
wake_lock_timeout(&modem_wakelock, 10 * HZ);
|
||||
schedule_delayed_work(&wakeup_work, HZ / 10);
|
||||
} else
|
||||
printk("%s: already wakeup\n", __FUNCTION__);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
int modem_poweron_off(int on_off)
|
||||
{
|
||||
struct rk29_mi700_data *pdata = gpdata;
|
||||
|
||||
mutex_lock(&pdata->bp_mutex);
|
||||
if(on_off)
|
||||
{
|
||||
MODEMDBG("------------modem_poweron\n");
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(700);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
MODEMDBG("------------modem_poweroff\n");
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(2500);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
}
|
||||
mutex_unlock(&pdata->bp_mutex);
|
||||
return 0;
|
||||
}
|
||||
static int mi700_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
//MODEMDBG("-------------%s\n",__FUNCTION__);
|
||||
struct rk29_mi700_data *pdata = gpdata;
|
||||
// struct platform_data *pdev = container_of(pdata, struct device, platform_data);
|
||||
device_init_wakeup(pdata->dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mi700_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
|
||||
//modem_poweron_off(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mi700_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk29_mi700_data *pdata = gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case MI700_RESET:
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(700);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations mi700_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mi700_open,
|
||||
.release = mi700_release,
|
||||
.unlocked_ioctl = mi700_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice mi700_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "mi700",
|
||||
.fops = &mi700_fops
|
||||
};
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_read(struct class *cls, struct class_attribute *attr, char *_buf)
|
||||
#else
|
||||
static ssize_t modem_status_read(struct class *cls, char *_buf)
|
||||
#endif
|
||||
{
|
||||
|
||||
return sprintf(_buf, "%d\n", modem_status);
|
||||
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
|
||||
#else
|
||||
static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
|
||||
#endif
|
||||
{
|
||||
int new_state = simple_strtoul(_buf, NULL, 16);
|
||||
if(new_state == modem_status)
|
||||
return _count;
|
||||
|
||||
if (new_state == 1){
|
||||
printk("%s, c(%d), open modem \n", __FUNCTION__, new_state);
|
||||
modem_poweron_off(1);
|
||||
}else if(new_state == 0){
|
||||
printk("%s, c(%d), close modem \n", __FUNCTION__, new_state);
|
||||
modem_poweron_off(0);
|
||||
}else{
|
||||
printk("%s, invalid parameter \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
modem_status = new_state;
|
||||
return _count;
|
||||
}
|
||||
static CLASS_ATTR(modem_status, 0777, modem_status_read, modem_status_write);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t online_read(struct class *cls, struct class_attribute *attr, char *_buf)
|
||||
#else
|
||||
static ssize_t online_read(struct class *cls, char *_buf)
|
||||
#endif
|
||||
{
|
||||
return sprintf(_buf, "%d\n", online);
|
||||
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t online_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
|
||||
#else
|
||||
static ssize_t online_write(struct class *cls, const char *_buf, size_t _count)
|
||||
#endif
|
||||
{
|
||||
int new_value = simple_strtoul(_buf, NULL, 16);
|
||||
if(new_value == online) return _count;
|
||||
online = new_value;
|
||||
return _count;
|
||||
}
|
||||
static CLASS_ATTR(online, 0777, online_read, online_write);
|
||||
static int mi700_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mi700_data *pdata = gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mi700_data = NULL;
|
||||
int result, irq = 0;
|
||||
MODEMDBG("-------------%s\n",__FUNCTION__);
|
||||
|
||||
pdata->dev = &pdev->dev;
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
|
||||
mi700_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(mi700_data == NULL)
|
||||
{
|
||||
printk("failed to request mi700_data\n");
|
||||
goto err2;
|
||||
}
|
||||
platform_set_drvdata(pdev, mi700_data);
|
||||
#if 0
|
||||
result = gpio_request(pdata->ap_wakeup_bp, "mi700");
|
||||
if (result) {
|
||||
printk("failed to request AP_BP_WAKEUP gpio\n");
|
||||
goto err1;
|
||||
}
|
||||
#endif
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
enable_irq_wake(irq);
|
||||
if(irq < 0)
|
||||
{
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
printk("failed to request bp_wakeup_ap\n");
|
||||
}
|
||||
result = gpio_request(pdata->bp_wakeup_ap, "bp_wakeup_ap");
|
||||
if (result < 0) {
|
||||
printk("%s: gpio_request(%d) failed\n", __func__, pdata->bp_wakeup_ap);
|
||||
}
|
||||
wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
|
||||
gpio_direction_input(pdata->bp_wakeup_ap);
|
||||
gpio_pull_updown(pdata->bp_wakeup_ap, 1);
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
goto err0;
|
||||
}
|
||||
enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap));
|
||||
|
||||
mutex_init(&pdata->bp_mutex);
|
||||
|
||||
modem_poweron_off(1);
|
||||
modem_status = 1;
|
||||
|
||||
result = misc_register(&mi700_misc);
|
||||
if(result)
|
||||
{
|
||||
printk("misc_register err\n");
|
||||
}
|
||||
return result;
|
||||
err0:
|
||||
cancel_work_sync(&mi700_data->work);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
err1:
|
||||
//gpio_free(pdata->ap_wakeup_bp);
|
||||
err2:
|
||||
kfree(mi700_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mi700_suspend(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
struct rk29_mi700_data *pdata = pdev->dev.platform_data;
|
||||
do_wakeup_irq = 1;
|
||||
MODEMDBG("%s::%d--\n",__func__,__LINE__);
|
||||
//gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mi700_resume(struct platform_device *pdev)
|
||||
{
|
||||
MODEMDBG("-------------%s\n",__FUNCTION__);
|
||||
//ap_wakeup_bp(pdev, 0);
|
||||
//rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mi700_shutdown(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rk29_mi700_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mi700_data = platform_get_drvdata(pdev);
|
||||
|
||||
MODEMDBG("-------------%s\n",__FUNCTION__);
|
||||
modem_poweron_off(0);
|
||||
|
||||
if(pdata->io_deinit)
|
||||
pdata->io_deinit();
|
||||
cancel_work_sync(&mi700_data->work);
|
||||
//gpio_free(pdata->bp_power);
|
||||
//gpio_free(pdata->bp_reset);
|
||||
//gpio_free(pdata->ap_wakeup_bp);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
kfree(mi700_data);
|
||||
}
|
||||
|
||||
static struct platform_driver mi700_driver = {
|
||||
.probe = mi700_probe,
|
||||
.shutdown = mi700_shutdown,
|
||||
.suspend = mi700_suspend,
|
||||
.resume = mi700_resume,
|
||||
.driver = {
|
||||
.name = "MW100",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mi700_init(void)
|
||||
{
|
||||
MODEMDBG("-------------%s\n",__FUNCTION__);
|
||||
int ret ;
|
||||
|
||||
modem_class = class_create(THIS_MODULE, "rk291x_modem");
|
||||
ret = class_create_file(modem_class, &class_attr_modem_status);
|
||||
ret = class_create_file(modem_class, &class_attr_online);
|
||||
if (ret)
|
||||
{
|
||||
printk("Fail to class rk291x_modem.\n");
|
||||
}
|
||||
return platform_driver_register(&mi700_driver);
|
||||
}
|
||||
|
||||
static void __exit mi700_exit(void)
|
||||
{
|
||||
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
|
||||
platform_driver_unregister(&mi700_driver);
|
||||
class_remove_file(modem_class, &class_attr_modem_status);
|
||||
class_remove_file(modem_class, &class_attr_online);
|
||||
}
|
||||
|
||||
module_init(mi700_init);
|
||||
module_exit(mi700_exit);
|
||||
@@ -1,358 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mt6229.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
static struct wake_lock modem_wakelock;
|
||||
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
#define MT6229_RESET 0x01
|
||||
struct rk29_mt6229_data *gpdata = NULL;
|
||||
struct class *modem_class = NULL;
|
||||
static int do_wakeup_irq = 0;
|
||||
static int modem_status;
|
||||
static void ap_wakeup_bp(struct platform_device *pdev, int wake)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
gpio_set_value(pdata->modem_usb_en,wake);
|
||||
if(wake == 1)
|
||||
wake = 0;
|
||||
else
|
||||
wake = 1;
|
||||
gpio_set_value(pdata->modem_uart_en,wake);
|
||||
|
||||
}
|
||||
extern void rk28_send_wakeup_key(void);
|
||||
|
||||
static void do_wakeup(struct work_struct *work)
|
||||
{
|
||||
gpio_set_value(gpdata->ap_ready,GPIO_HIGH);
|
||||
gpio_set_value(gpdata->modem_usb_en,GPIO_HIGH);
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
if(do_wakeup_irq)
|
||||
{
|
||||
do_wakeup_irq = 0;
|
||||
wake_lock_timeout(&modem_wakelock, 10 * HZ);
|
||||
//schedule_delayed_work(&wakeup_work, 2*HZ);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
int modem_poweron_off(int on_off)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = gpdata;
|
||||
if(on_off)
|
||||
{
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->modem_usb_en, GPIO_HIGH);
|
||||
gpio_set_value(pdata->modem_uart_en, GPIO_LOW);
|
||||
gpio_set_value(pdata->ap_ready, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
gpio_set_value(pdata->modem_usb_en, GPIO_LOW);
|
||||
gpio_set_value(pdata->modem_uart_en, GPIO_HIGH);
|
||||
gpio_set_value(pdata->ap_ready, GPIO_LOW);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int mt6229_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = gpdata;
|
||||
device_init_wakeup(pdata->dev, 1);
|
||||
return 0;
|
||||
}
|
||||
static ssize_t mt6229_write(struct file *file, const char __user *buf,size_t len, loff_t *off)
|
||||
{
|
||||
static char cmd[2];
|
||||
int ret = 0;
|
||||
if (len > 2)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = copy_from_user(&cmd, buf, len);
|
||||
if (ret != 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
printk(" received cmd = %c\n",cmd[0]);
|
||||
if (cmd[0] == '0')
|
||||
{
|
||||
gpio_set_value(gpdata->ap_ready, GPIO_LOW);
|
||||
}
|
||||
if (cmd[0] == '1')
|
||||
{
|
||||
gpio_set_value(gpdata->ap_ready, GPIO_HIGH);
|
||||
}
|
||||
if (cmd[0] == '2')
|
||||
{
|
||||
gpio_set_value(gpdata->modem_uart_en, GPIO_LOW);
|
||||
}
|
||||
if (cmd[0] == '3')
|
||||
{
|
||||
gpio_set_value(gpdata->modem_uart_en, GPIO_HIGH);
|
||||
}
|
||||
if (cmd[0] == '4')
|
||||
{
|
||||
gpio_set_value(gpdata->modem_usb_en, GPIO_HIGH);
|
||||
}if (cmd[0] == '5')
|
||||
{
|
||||
gpio_set_value(gpdata->modem_usb_en, GPIO_LOW);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
static int mt6229_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mt6229_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case MT6229_RESET:
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(10);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations mt6229_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mt6229_open,
|
||||
.write = mt6229_write,
|
||||
.release = mt6229_release,
|
||||
.unlocked_ioctl = mt6229_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice mt6229_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = MODEM_NAME,
|
||||
.fops = &mt6229_fops
|
||||
};
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_read(struct class *cls, struct class_attribute *attr, char *_buf)
|
||||
#else
|
||||
static ssize_t modem_status_read(struct class *cls, char *_buf)
|
||||
#endif
|
||||
{
|
||||
|
||||
return sprintf(_buf, "%d\n", modem_status);
|
||||
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
|
||||
#else
|
||||
static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
|
||||
#endif
|
||||
{
|
||||
int new_state = simple_strtoul(_buf, NULL, 16);
|
||||
if(new_state == modem_status) return _count;
|
||||
if (new_state == 1){
|
||||
printk("%s, c(%d), modem resume \n", __FUNCTION__, new_state);
|
||||
gpio_set_value(gpdata->modem_usb_en, GPIO_HIGH);
|
||||
gpio_set_value(gpdata->modem_uart_en,GPIO_LOW);
|
||||
}else if(new_state == 0){
|
||||
printk("%s, c(%d), modem suspend \n", __FUNCTION__, new_state);
|
||||
gpio_set_value(gpdata->modem_usb_en, GPIO_LOW);
|
||||
gpio_set_value(gpdata->modem_uart_en,GPIO_HIGH);
|
||||
}else{
|
||||
printk("%s, invalid parameter \n", __FUNCTION__);
|
||||
}
|
||||
modem_status = new_state;
|
||||
return _count;
|
||||
}
|
||||
static CLASS_ATTR(modem_status, 0777, modem_status_read, modem_status_write);
|
||||
static int mt6229_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mt6229_data = NULL;
|
||||
int result, irq = 0;
|
||||
pdata->dev = &pdev->dev;
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
mt6229_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(mt6229_data == NULL)
|
||||
{
|
||||
printk("failed to request mt6229_data\n");
|
||||
goto err0;
|
||||
}
|
||||
platform_set_drvdata(pdev, mt6229_data);
|
||||
result = gpio_request(pdata->modem_power_en,"modem_power_en");
|
||||
if(result){
|
||||
printk("failed to request modem_power_en gpio\n");
|
||||
goto err1;
|
||||
}
|
||||
gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
result = gpio_request(pdata->bp_power,"modem_power");
|
||||
if(result){
|
||||
printk("failed to request modem_power gpio\n");
|
||||
goto err2;
|
||||
}
|
||||
result = gpio_request(pdata->modem_usb_en, "modem_usb_en");
|
||||
if (result) {
|
||||
printk("failed to request modem_usb_en gpio\n");
|
||||
goto err3;
|
||||
}
|
||||
result = gpio_request(pdata->modem_uart_en,"modem_uart_en");
|
||||
if(result){
|
||||
printk("failed to request modem_uart_en gpio\n");
|
||||
goto err4;
|
||||
}
|
||||
result = gpio_request(pdata->bp_wakeup_ap, "bp_wakeup_ap");
|
||||
if (result) {
|
||||
printk("failed to request bp_wakeup_ap gpio\n");
|
||||
goto err5;
|
||||
}
|
||||
gpio_direction_input(pdata->bp_wakeup_ap);
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
if(irq < 0)
|
||||
{
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
printk("failed to request bp_wakeup_ap\n");
|
||||
}
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
goto err5;
|
||||
}
|
||||
enable_irq_wake(irq);
|
||||
wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
|
||||
result = gpio_request(pdata->ap_ready, "ap_ready");
|
||||
if (result < 0) {
|
||||
printk("failed to request ap_ready gpio\n");
|
||||
goto err6;
|
||||
}
|
||||
|
||||
modem_poweron_off(1);
|
||||
modem_status = 1;
|
||||
|
||||
result = misc_register(&mt6229_misc);
|
||||
if(result)
|
||||
{
|
||||
printk("misc_register err\n");
|
||||
}
|
||||
return result;
|
||||
err0:
|
||||
kfree(mt6229_data);
|
||||
err1:
|
||||
gpio_free(pdata->modem_power_en);
|
||||
err2:
|
||||
gpio_free(pdata->bp_power);
|
||||
err3:
|
||||
gpio_free(pdata->modem_usb_en);
|
||||
err4:
|
||||
gpio_free(pdata->modem_uart_en);
|
||||
err5:
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
err6:
|
||||
gpio_free(pdata->ap_ready);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt6229_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
do_wakeup_irq = 1;
|
||||
ap_wakeup_bp(pdev, 0);
|
||||
gpio_set_value(gpdata->ap_ready,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt6229_resume(struct platform_device *pdev)
|
||||
{
|
||||
gpio_set_value(gpdata->modem_uart_en,GPIO_LOW);
|
||||
schedule_delayed_work(&wakeup_work, 2*HZ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt6229_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mt6229_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mt6229_data = platform_get_drvdata(pdev);
|
||||
|
||||
modem_poweron_off(0);
|
||||
|
||||
if(pdata->io_deinit)
|
||||
pdata->io_deinit();
|
||||
cancel_work_sync(&mt6229_data->work);
|
||||
gpio_free(pdata->modem_power_en);
|
||||
gpio_free(pdata->bp_power);
|
||||
gpio_free(pdata->modem_usb_en);
|
||||
gpio_free(pdata->modem_uart_en);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
kfree(mt6229_data);
|
||||
}
|
||||
|
||||
static struct platform_driver mt6229_driver = {
|
||||
.probe = mt6229_probe,
|
||||
.shutdown = mt6229_shutdown,
|
||||
.suspend = mt6229_suspend,
|
||||
.resume = mt6229_resume,
|
||||
.driver = {
|
||||
.name = "mt6229",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mt6229_init(void)
|
||||
{
|
||||
int ret ;
|
||||
modem_class = class_create(THIS_MODULE, "rk291x_modem");
|
||||
ret = class_create_file(modem_class, &class_attr_modem_status);
|
||||
if (ret)
|
||||
{
|
||||
printk("Fail to class rk291x_modem.\n");
|
||||
}
|
||||
return platform_driver_register(&mt6229_driver);
|
||||
}
|
||||
|
||||
static void __exit mt6229_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&mt6229_driver);
|
||||
class_remove_file(modem_class, &class_attr_modem_status);
|
||||
}
|
||||
|
||||
module_init(mt6229_init);
|
||||
|
||||
module_exit(mt6229_exit);
|
||||
@@ -1,339 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mu509.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
static struct wake_lock modem_wakelock;
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
|
||||
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
#define MU509_RESET 0x01
|
||||
struct rk29_mu509_data *gpdata = NULL;
|
||||
struct class *modem_class = NULL;
|
||||
static int do_wakeup_irq = 0;
|
||||
static int modem_status;
|
||||
int suspend_int =0;
|
||||
static void ap_wakeup_bp(struct platform_device *pdev, int wake)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
gpio_set_value(pdata->ap_wakeup_bp, wake);
|
||||
|
||||
}
|
||||
extern void rk28_send_wakeup_key(void);
|
||||
|
||||
static void do_wakeup(struct work_struct *work)
|
||||
{
|
||||
if(suspend_int)
|
||||
{
|
||||
gpio_set_value(gpdata->ap_wakeup_bp, 0);
|
||||
suspend_int = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
if(do_wakeup_irq)
|
||||
{
|
||||
do_wakeup_irq = 0;
|
||||
// MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
wake_lock_timeout(&modem_wakelock, 10 * HZ);
|
||||
schedule_delayed_work(&wakeup_work, 2*HZ);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
int modem_poweron_off(int on_off)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = gpdata;
|
||||
if(on_off)
|
||||
{
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(700);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(2500);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int mu509_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = gpdata;
|
||||
device_init_wakeup(pdata->dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mu509_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mu509_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case MU509_RESET:
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(700);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations mu509_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mu509_open,
|
||||
.release = mu509_release,
|
||||
.unlocked_ioctl = mu509_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice mu509_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = MODEM_NAME,
|
||||
.fops = &mu509_fops
|
||||
};
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_read(struct class *cls, struct class_attribute *attr, char *_buf)
|
||||
#else
|
||||
static ssize_t modem_status_read(struct class *cls, char *_buf)
|
||||
#endif
|
||||
{
|
||||
|
||||
return sprintf(_buf, "%d\n", modem_status);
|
||||
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
|
||||
static ssize_t modem_status_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
|
||||
#else
|
||||
static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
|
||||
#endif
|
||||
{
|
||||
int new_state = simple_strtoul(_buf, NULL, 16);
|
||||
if(new_state == modem_status) return _count;
|
||||
if (new_state == 1){
|
||||
printk("%s, c(%d), open modem \n", __FUNCTION__, new_state);
|
||||
modem_poweron_off(1);
|
||||
}else if(new_state == 0){
|
||||
printk("%s, c(%d), close modem \n", __FUNCTION__, new_state);
|
||||
modem_poweron_off(0);
|
||||
}else{
|
||||
printk("%s, invalid parameter \n", __FUNCTION__);
|
||||
}
|
||||
modem_status = new_state;
|
||||
return _count;
|
||||
}
|
||||
static CLASS_ATTR(modem_status, 0777, modem_status_read, modem_status_write);
|
||||
static void rk29_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
|
||||
}
|
||||
static void rk29_early_resume(struct early_suspend *h)
|
||||
{
|
||||
if(suspend_int)
|
||||
{
|
||||
gpio_set_value(gpdata->ap_wakeup_bp, 0);
|
||||
suspend_int = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct early_suspend mu509_early_suspend = {
|
||||
.suspend = rk29_early_suspend,
|
||||
.resume = rk29_early_resume,
|
||||
.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1,
|
||||
};
|
||||
static int mu509_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mu509_data = NULL;
|
||||
int result, irq = 0;
|
||||
|
||||
pdata->dev = &pdev->dev;
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
modem_poweron_off(1);
|
||||
modem_status = 1;
|
||||
|
||||
register_early_suspend(&mu509_early_suspend);
|
||||
mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(mu509_data == NULL)
|
||||
{
|
||||
printk("failed to request mu509_data\n");
|
||||
goto err2;
|
||||
}
|
||||
platform_set_drvdata(pdev, mu509_data);
|
||||
result = gpio_request(pdata->ap_wakeup_bp, "mu509");
|
||||
if (result) {
|
||||
printk("failed to request AP_BP_WAKEUP gpio\n");
|
||||
goto err1;
|
||||
}
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
enable_irq_wake(irq);
|
||||
if(irq < 0)
|
||||
{
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
printk("failed to request bp_wakeup_ap\n");
|
||||
}
|
||||
result = gpio_request(pdata->bp_wakeup_ap, "bp_wakeup_ap");
|
||||
if (result < 0) {
|
||||
printk("%s: gpio_request(%d) failed\n", __func__, pdata->bp_wakeup_ap);
|
||||
}
|
||||
wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
|
||||
gpio_direction_input(pdata->bp_wakeup_ap);
|
||||
gpio_pull_updown(pdata->bp_wakeup_ap, 1);
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
goto err0;
|
||||
}
|
||||
enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap));
|
||||
|
||||
result = misc_register(&mu509_misc);
|
||||
if(result)
|
||||
{
|
||||
printk("misc_register err\n");
|
||||
}
|
||||
return result;
|
||||
err0:
|
||||
cancel_work_sync(&mu509_data->work);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
err1:
|
||||
gpio_free(pdata->ap_wakeup_bp);
|
||||
err2:
|
||||
kfree(mu509_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mu509_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
suspend_int = 1;
|
||||
do_wakeup_irq = 1;
|
||||
ap_wakeup_bp(pdev, 1);
|
||||
#if defined(CONFIG_ARCH_RK29)
|
||||
rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_RK30)
|
||||
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_GPIO1A7);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mu509_resume(struct platform_device *pdev)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_RK29)
|
||||
rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_RK30)
|
||||
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_UART1_RTS_N);
|
||||
#endif
|
||||
if(gpio_get_value(gpdata->bp_wakeup_ap))
|
||||
{
|
||||
schedule_delayed_work(&wakeup_work, 2*HZ);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mu509_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mu509_data = platform_get_drvdata(pdev);
|
||||
|
||||
modem_poweron_off(0);
|
||||
|
||||
if(pdata->io_deinit)
|
||||
pdata->io_deinit();
|
||||
cancel_work_sync(&mu509_data->work);
|
||||
gpio_free(pdata->modem_power_en);
|
||||
gpio_free(pdata->bp_power);
|
||||
gpio_free(pdata->bp_reset);
|
||||
gpio_free(pdata->ap_wakeup_bp);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
kfree(mu509_data);
|
||||
}
|
||||
|
||||
static struct platform_driver mu509_driver = {
|
||||
.probe = mu509_probe,
|
||||
.shutdown = mu509_shutdown,
|
||||
.suspend = mu509_suspend,
|
||||
.resume = mu509_resume,
|
||||
.driver = {
|
||||
.name = "mu509",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mu509_init(void)
|
||||
{
|
||||
int ret ;
|
||||
modem_class = class_create(THIS_MODULE, "rk291x_modem");
|
||||
ret = class_create_file(modem_class, &class_attr_modem_status);
|
||||
if (ret)
|
||||
{
|
||||
printk("Fail to class rk291x_modem.\n");
|
||||
}
|
||||
return platform_driver_register(&mu509_driver);
|
||||
}
|
||||
|
||||
static void __exit mu509_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&mu509_driver);
|
||||
class_remove_file(modem_class, &class_attr_modem_status);
|
||||
}
|
||||
|
||||
module_init(mu509_init);
|
||||
|
||||
module_exit(mu509_exit);
|
||||
@@ -1,235 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mw100.h>
|
||||
#include <mach/iomux.h>
|
||||
#include<linux/ioctl.h>
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
|
||||
#define MW100IO 0XA1
|
||||
#define MW_IOCTL_RESET _IO(MW100IO,0X01)
|
||||
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
#define MW100_RESET 0x01
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
struct rk29_mw100_data *gpdata = NULL;
|
||||
static int bp_wakeup_ap_irq = 0;
|
||||
|
||||
static struct wake_lock bp_wakelock;
|
||||
static bool bpstatus_irq_enable = false;
|
||||
|
||||
static void do_wakeup(struct work_struct *work)
|
||||
{
|
||||
enable_irq(bp_wakeup_ap_irq);
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
wake_lock_timeout(&bp_wakelock, 10 * HZ);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mw100_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mw100_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mw100_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk29_mw100_data *pdata = gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case MW_IOCTL_RESET:
|
||||
gpio_direction_output(pdata->bp_reset,GPIO_LOW);
|
||||
mdelay(120);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations mw100_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mw100_open,
|
||||
.release = mw100_release,
|
||||
.unlocked_ioctl = mw100_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice mw100_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "mw100",
|
||||
.fops = &mw100_fops
|
||||
};
|
||||
|
||||
static int mw100_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mw100_data *pdata = gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mw100_data = NULL;
|
||||
int result, irq = 0;
|
||||
|
||||
gpio_request(pdata->bp_power,"bp_power");
|
||||
gpio_request(pdata->bp_reset,"bp_reset");
|
||||
gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap");
|
||||
gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp");
|
||||
gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_direction_output(pdata->bp_reset,GPIO_LOW);
|
||||
mdelay(120);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
|
||||
gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH);
|
||||
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
gpio_direction_output(pdata->bp_power,GPIO_HIGH);
|
||||
mdelay(120);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_direction_output(pdata->bp_power,GPIO_LOW);
|
||||
|
||||
mw100_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(mw100_data == NULL){
|
||||
printk("failed to request mw100_data\n");
|
||||
goto err2;
|
||||
}
|
||||
platform_set_drvdata(pdev, mw100_data);
|
||||
|
||||
gpio_direction_input(pdata->bp_wakeup_ap);
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
if(irq < 0){
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
printk("failed to request bp_wakeup_ap\n");
|
||||
}
|
||||
|
||||
bp_wakeup_ap_irq = irq;
|
||||
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
enable_irq_wake(bp_wakeup_ap_irq);
|
||||
|
||||
wake_lock_init(&bp_wakelock, WAKE_LOCK_SUSPEND, "bp_resume");
|
||||
|
||||
result = misc_register(&mw100_misc);
|
||||
if(result){
|
||||
MODEMDBG("misc_register err\n");
|
||||
}
|
||||
return result;
|
||||
err0:
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
err2:
|
||||
kfree(mw100_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mw100_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
|
||||
struct rk29_mw100_data *pdata = pdev->dev.platform_data;
|
||||
int irq;
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
if (irq < 0) {
|
||||
printk("can't get pdata->bp_statue irq \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
bpstatus_irq_enable = true;
|
||||
enable_irq_wake(irq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mw100_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mw100_data *pdata = pdev->dev.platform_data;
|
||||
int irq;
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
if (irq ) {
|
||||
disable_irq_wake(irq);
|
||||
bpstatus_irq_enable = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mw100_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_mw100_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *mw100_data = platform_get_drvdata(pdev);
|
||||
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
mdelay(2010);
|
||||
gpio_free(pdata->modem_power_en);
|
||||
gpio_free(pdata->bp_power);
|
||||
gpio_free(pdata->bp_reset);
|
||||
gpio_free(pdata->ap_wakeup_bp);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
kfree(mw100_data);
|
||||
}
|
||||
|
||||
static struct platform_driver mw100_driver = {
|
||||
.probe = mw100_probe,
|
||||
.shutdown = mw100_shutdown,
|
||||
.suspend = mw100_suspend,
|
||||
.resume = mw100_resume,
|
||||
.driver = {
|
||||
.name = "mw100",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mw100_init(void)
|
||||
{
|
||||
return platform_driver_register(&mw100_driver);
|
||||
}
|
||||
|
||||
static void __exit mw100_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&mw100_driver);
|
||||
}
|
||||
|
||||
module_init(mw100_init);
|
||||
|
||||
module_exit(mw100_exit);
|
||||
@@ -1,231 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sc6610.h>
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEBUG 1
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
#define MODEM_RESET 2
|
||||
#define MODEM_ON 1
|
||||
#define MODEM_OFF 0
|
||||
struct rk29_sc6610_data *s_gpdata = NULL;
|
||||
|
||||
struct class *modem_class = NULL;
|
||||
static int do_wakeup_irq = 0;
|
||||
static struct wake_lock modem_wakelock;
|
||||
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
int modem_poweron_off(int on_off)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = s_gpdata;
|
||||
if(on_off){
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
|
||||
}else{
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
if(do_wakeup_irq)
|
||||
{
|
||||
do_wakeup_irq = 0;
|
||||
|
||||
wake_lock_timeout(&modem_wakelock, 10 * HZ);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static int sc6610_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sc6610_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long sc6610_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = s_gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case MODEM_RESET:
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
msleep(2000);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
break;
|
||||
case MODEM_ON:
|
||||
modem_poweron_off(MODEM_ON);
|
||||
break;
|
||||
case MODEM_OFF:
|
||||
modem_poweron_off(MODEM_OFF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations sc6610_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = sc6610_open,
|
||||
.release = sc6610_release,
|
||||
.unlocked_ioctl = sc6610_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice sc6610_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = MODEM_NAME,
|
||||
.fops = &sc6610_fops
|
||||
};
|
||||
|
||||
static int sc6610_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = s_gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *sc6610_data = NULL;
|
||||
int result;
|
||||
int irq;
|
||||
pdata->dev = &pdev->dev;
|
||||
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
result = gpio_request(pdata->ap_wakeup_bp, "ap_wakeup_bp");
|
||||
if (result) {
|
||||
printk("failed to request ap_wakeup_bp gpio\n");
|
||||
goto err0;
|
||||
}
|
||||
result = gpio_request(pdata->bp_power, "bp_power");
|
||||
if (result) {
|
||||
printk("failed to request bp_power gpio\n");
|
||||
goto err1;
|
||||
}
|
||||
result = gpio_request(pdata->bp_wakeup_ap, "bp_wakeup_ap");
|
||||
if (result) {
|
||||
printk("failed to request bp_wakeup_ap gpio\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
goto err2;
|
||||
}
|
||||
enable_irq_wake(irq);
|
||||
wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
|
||||
sc6610_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(sc6610_data == NULL)
|
||||
{
|
||||
printk("failed to request sc6610_data\n");
|
||||
goto err3;
|
||||
}
|
||||
platform_set_drvdata(pdev, sc6610_data);
|
||||
result = misc_register(&sc6610_misc);
|
||||
if(result)
|
||||
{
|
||||
printk("misc_register err\n");
|
||||
}
|
||||
modem_poweron_off(MODEM_ON);
|
||||
return result;
|
||||
|
||||
err0:
|
||||
gpio_free(pdata->ap_wakeup_bp);
|
||||
err1:
|
||||
gpio_free(pdata->bp_power);
|
||||
err2:
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
err3:
|
||||
kfree(sc6610_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c6610_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = s_gpdata = pdev->dev.platform_data;
|
||||
pdata->dev = &pdev->dev;
|
||||
do_wakeup_irq = 1;
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c6610_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = s_gpdata = pdev->dev.platform_data;
|
||||
pdata->dev = &pdev->dev;
|
||||
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void c6610_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct rk29_sc6610_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *sc6610_data = platform_get_drvdata(pdev);
|
||||
modem_poweron_off(MODEM_OFF);
|
||||
if(pdata->io_deinit)
|
||||
pdata->io_deinit();
|
||||
cancel_work_sync(&sc6610_data->work);
|
||||
gpio_free(pdata->bp_power);
|
||||
gpio_free(pdata->ap_wakeup_bp);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
kfree(sc6610_data);
|
||||
}
|
||||
|
||||
static struct platform_driver sc6610_driver = {
|
||||
.probe = sc6610_probe,
|
||||
.shutdown = c6610_shutdown,
|
||||
.suspend = c6610_suspend,
|
||||
.resume = c6610_resume,
|
||||
.driver = {
|
||||
.name = "SC6610",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sc6610_init(void)
|
||||
{
|
||||
|
||||
return platform_driver_register(&sc6610_driver);
|
||||
}
|
||||
|
||||
static void __exit sc6610_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sc6610_driver);
|
||||
|
||||
}
|
||||
|
||||
module_init(sc6610_init);
|
||||
|
||||
module_exit(sc6610_exit);
|
||||
@@ -1,228 +0,0 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sew868.h>
|
||||
#include<linux/ioctl.h>
|
||||
#include<linux/slab.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define MODEMDBG(x...) printk(x)
|
||||
#else
|
||||
#define MODEMDBG(fmt,argss...)
|
||||
#endif
|
||||
#define SLEEP 1
|
||||
#define READY 0
|
||||
#define SEW868_RESET 0x01
|
||||
#define SEW868_POWON 0x02
|
||||
#define SEW868_POWOFF 0x03
|
||||
static struct wake_lock modem_wakelock;
|
||||
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
|
||||
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
|
||||
struct rk30_sew868_data *gpdata = NULL;
|
||||
static int do_wakeup_irq = 0;
|
||||
|
||||
extern void rk28_send_wakeup_key(void);
|
||||
|
||||
static void do_wakeup(struct work_struct *work)
|
||||
{
|
||||
rk28_send_wakeup_key();
|
||||
}
|
||||
|
||||
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
|
||||
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
printk("%s\n", __FUNCTION__);
|
||||
if(do_wakeup_irq)
|
||||
{
|
||||
do_wakeup_irq = 0;
|
||||
wake_lock_timeout(&modem_wakelock, 10 * HZ);
|
||||
schedule_delayed_work(&wakeup_work, HZ / 10);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
int modem_poweron_off(int on_off)
|
||||
{
|
||||
struct rk30_sew868_data *pdata = gpdata;
|
||||
if(on_off)
|
||||
{
|
||||
gpio_direction_output(pdata->bp_sys, GPIO_HIGH);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(200);//for charge
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(4000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
msleep(200);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_value(pdata->bp_power, GPIO_HIGH);
|
||||
msleep(4000);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
gpio_set_value(pdata->bp_sys, GPIO_LOW);
|
||||
msleep(50);
|
||||
gpio_set_value(pdata->bp_power, GPIO_LOW);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int sew868_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sew868_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long sew868_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rk30_sew868_data *pdata = gpdata;
|
||||
switch(cmd)
|
||||
{
|
||||
case SEW868_RESET:
|
||||
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
|
||||
mdelay(100);
|
||||
gpio_set_value(pdata->bp_reset, GPIO_LOW);
|
||||
mdelay(200);
|
||||
modem_poweron_off(1);
|
||||
break;
|
||||
case SEW868_POWON:
|
||||
modem_poweron_off(1);
|
||||
break;
|
||||
case SEW868_POWOFF:
|
||||
modem_poweron_off(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations sew868_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = sew868_open,
|
||||
.release = sew868_release,
|
||||
.unlocked_ioctl = sew868_ioctl
|
||||
};
|
||||
|
||||
static struct miscdevice sew868_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = MODEM_NAME,
|
||||
.fops = &sew868_fops
|
||||
};
|
||||
|
||||
static int sew868_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk30_sew868_data *pdata = gpdata = pdev->dev.platform_data;
|
||||
struct modem_dev *sew868_data = NULL;
|
||||
int result, irq = 0;
|
||||
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
|
||||
modem_poweron_off(1);
|
||||
sew868_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
|
||||
if(sew868_data == NULL)
|
||||
{
|
||||
printk("failed to request sew868_data\n");
|
||||
goto err1;
|
||||
}
|
||||
platform_set_drvdata(pdev, sew868_data);
|
||||
|
||||
irq = gpio_to_irq(pdata->bp_wakeup_ap);
|
||||
if(irq < 0)
|
||||
{
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
printk("failed to request bp_wakeup_ap\n");
|
||||
}
|
||||
|
||||
wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
|
||||
gpio_direction_input(pdata->bp_wakeup_ap);
|
||||
gpio_pull_updown(pdata->bp_wakeup_ap, GPIONormal);
|
||||
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, irq);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
goto err0;
|
||||
}
|
||||
enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap));
|
||||
result = misc_register(&sew868_misc);
|
||||
if(result)
|
||||
{
|
||||
MODEMDBG("misc_register err\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
err0:
|
||||
cancel_work_sync(&sew868_data->work);
|
||||
err1:
|
||||
kfree(sew868_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sew868_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
do_wakeup_irq = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sew868_resume(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sew868_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct rk30_sew868_data *pdata = pdev->dev.platform_data;
|
||||
struct modem_dev *sew868_data = platform_get_drvdata(pdev);
|
||||
modem_poweron_off(0);
|
||||
if(pdata->io_deinit)
|
||||
pdata->io_deinit();
|
||||
cancel_work_sync(&sew868_data->work);
|
||||
kfree(sew868_data);
|
||||
}
|
||||
|
||||
static struct platform_driver sew868_driver = {
|
||||
.probe = sew868_probe,
|
||||
.shutdown = sew868_shutdown,
|
||||
.suspend = sew868_suspend,
|
||||
.resume = sew868_resume,
|
||||
.driver = {
|
||||
.name = "sew868",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sew868_init(void)
|
||||
{
|
||||
return platform_driver_register(&sew868_driver);
|
||||
}
|
||||
|
||||
static void __exit sew868_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sew868_driver);
|
||||
}
|
||||
|
||||
module_init(sew868_init);
|
||||
|
||||
module_exit(sew868_exit);
|
||||
@@ -564,7 +564,6 @@ source "drivers/misc/iwmc3200top/Kconfig"
|
||||
source "drivers/misc/ti-st/Kconfig"
|
||||
source "drivers/misc/lis3lv02d/Kconfig"
|
||||
source "drivers/misc/carma/Kconfig"
|
||||
source "drivers/misc/3g_module/Kconfig"
|
||||
source "drivers/misc/bp/Kconfig"
|
||||
source "drivers/misc/rk2928_callpad_misc/Kconfig"
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ obj-$(CONFIG_SENSORS_AK8963) += akm8963.o
|
||||
obj-$(CONFIG_MTK23D) += mtk23d.o
|
||||
obj-$(CONFIG_FM580X) += fm580x.o
|
||||
obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/
|
||||
obj-$(CONFIG_3G_MODULE) += 3g_module/
|
||||
obj-$(CONFIG_BP_AUTO) += bp/
|
||||
obj-$(CONFIG_GPS_DEVICES) += gps/
|
||||
obj-y += inv_mpu/
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
# all auto modem control drivers configuration
|
||||
#
|
||||
|
||||
menuconfig BP_AUTO
|
||||
bool "auto modem control driver support"
|
||||
config BP_AUTO
|
||||
bool "voice modem support"
|
||||
default n
|
||||
|
||||
if BP_AUTO
|
||||
|
||||
source "drivers/misc/bp/chips/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
#include "../../mtd/rknand/api_flash.h"
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
@@ -34,7 +35,9 @@ struct bp_private_data *g_bp;
|
||||
static struct class *g_bp_class;
|
||||
static struct bp_operate *g_bp_ops[BP_ID_NUM];
|
||||
struct class *bp_class = NULL;
|
||||
|
||||
int get_current_bp_id(){
|
||||
return g_bp->ops->bp_id;
|
||||
}
|
||||
static void ap_wakeup_bp(struct bp_private_data *bp, int wake)
|
||||
{
|
||||
if(bp->ops->ap_wake_bp)
|
||||
@@ -91,7 +94,7 @@ static int bp_request_gpio(struct bp_private_data *bp)
|
||||
if(bp->pdata->bp_uart_en > 0)
|
||||
{
|
||||
bp->ops->bp_uart_en = bp->pdata->bp_uart_en;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -197,9 +200,10 @@ static irqreturn_t bp_wake_up_irq(int irq, void *dev_id)
|
||||
{
|
||||
|
||||
struct bp_private_data *bp = dev_id;
|
||||
if(bp->ops->bp_wake_ap)
|
||||
printk("<---%s:bp_id=%d--->\n",__FUNCTION__,bp->ops->bp_id);
|
||||
if(bp->ops->bp_wake_ap){
|
||||
bp->ops->bp_wake_ap(bp);
|
||||
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -212,7 +216,7 @@ static int bp_id_open(struct inode *inode, struct file *file)
|
||||
|
||||
static int bp_id_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -248,7 +252,8 @@ static long bp_id_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
static int bp_dev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct bp_private_data *bp = g_bp;
|
||||
device_init_wakeup(bp->dev, 1);
|
||||
printk("<---%s:bp_id=%d--->\n",__FUNCTION__,bp->ops->bp_id);
|
||||
device_init_wakeup(bp->dev, 1);
|
||||
return 0;
|
||||
}
|
||||
static ssize_t bp_dev_write(struct file *file, const char __user *buf,size_t len, loff_t *off)
|
||||
@@ -256,15 +261,15 @@ static ssize_t bp_dev_write(struct file *file, const char __user *buf,size_t len
|
||||
static char cmd[2];
|
||||
struct bp_private_data *bp = g_bp;
|
||||
|
||||
int ret = 0;
|
||||
if (len > 2)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = copy_from_user(&cmd, buf, len);
|
||||
if (ret != 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
int ret = 0;
|
||||
if (len > 2)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = copy_from_user(&cmd, buf, len);
|
||||
if (ret != 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
printk(" received cmd = %c\n",cmd[0]);
|
||||
switch(bp->ops->bp_id)
|
||||
{
|
||||
@@ -305,6 +310,9 @@ static ssize_t bp_dev_write(struct file *file, const char __user *buf,size_t len
|
||||
}
|
||||
static int bp_dev_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct bp_private_data *bp = g_bp;
|
||||
printk("<---%s:bp_id=%d--->\n",__FUNCTION__,bp->ops->bp_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -312,8 +320,9 @@ static long bp_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct bp_private_data *bp = g_bp;
|
||||
void __user *argp = (void __user *)arg;
|
||||
char SectorBuffer[512];
|
||||
int result = 0;
|
||||
|
||||
printk("<---%s:bp_id=%d,cmd=%d--->\n",__FUNCTION__,bp->ops->bp_id,cmd);
|
||||
switch(cmd)
|
||||
{
|
||||
case BP_IOCTL_RESET:
|
||||
@@ -321,22 +330,18 @@ static long bp_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
bp->ops->reset(bp);
|
||||
}
|
||||
else if(bp->ops->active)
|
||||
{
|
||||
bp->ops->active(bp, 0);
|
||||
msleep(100);
|
||||
bp->ops->active(bp, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BP_IOCTL_POWON:
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 1);
|
||||
bp->status = BP_ON;
|
||||
break;
|
||||
|
||||
case BP_IOCTL_POWOFF:
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
bp->status = BP_OFF;
|
||||
break;
|
||||
|
||||
case BP_IOCTL_WRITE_STATUS:
|
||||
@@ -359,6 +364,15 @@ static long bp_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
break;
|
||||
case BP_IOCTL_GET_IMEI:
|
||||
printk("BP_IMEI_READ\n");
|
||||
GetSNSectorInfo(SectorBuffer);
|
||||
if(copy_to_user(argp, &(SectorBuffer[451]), 16)) // IMEIo<49><6F><EFBFBD>䨮451??<3F><>??a<><61>?<3F><>?16bytes<65><73>?<3F>̨<EFBFBD><CCA8><EFBFBD>???byte?a3<61><33>?<3F><>1<EFBFBD><31>?<3F><>?a15
|
||||
{
|
||||
printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -382,23 +396,39 @@ static ssize_t bp_status_write(struct class *cls, struct class_attribute *attr,
|
||||
int status = 0;
|
||||
|
||||
status = simple_strtoul(_buf, NULL, 16);
|
||||
printk("<<<<<<<<--%s:buf:%s,status=%d\n",__func__,_buf,status);
|
||||
|
||||
if(status == bp->status)
|
||||
return _count;
|
||||
|
||||
bp->status = status;
|
||||
|
||||
if(bp->ops->write_status)
|
||||
if(bp->ops->write_status){
|
||||
result = bp->ops->write_status(bp);
|
||||
|
||||
}else{
|
||||
switch(status)
|
||||
{
|
||||
case 1://modem power on
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 1);
|
||||
break;
|
||||
|
||||
case 0: // modem power off
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static CLASS_ATTR(bp_status, 0777, bp_status_read, bp_status_write);
|
||||
//static CLASS_ATTR(bp_status, 0777, bp_status_read, bp_status_write);
|
||||
static int bp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bp_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct bp_private_data *bp = NULL;
|
||||
int i = 0, result;
|
||||
|
||||
int i = 0, result,irq = 0;
|
||||
if(!pdata)
|
||||
return -1;
|
||||
|
||||
@@ -406,7 +436,8 @@ static int bp_probe(struct platform_device *pdev)
|
||||
|
||||
if(pdata->init_platform_hw)
|
||||
pdata->init_platform_hw();
|
||||
|
||||
if(pdata->get_bp_id())
|
||||
pdata->bp_id = pdata->get_bp_id();
|
||||
bp = kzalloc(sizeof(struct bp_private_data), GFP_KERNEL);
|
||||
if(bp == NULL)
|
||||
{
|
||||
@@ -434,25 +465,26 @@ static int bp_probe(struct platform_device *pdev)
|
||||
else
|
||||
{
|
||||
printk("%s:bp_id=%d is out of range\n",__func__, pdata->bp_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bp_request_gpio(bp);
|
||||
|
||||
if(bp->ops->init)
|
||||
bp->ops->init(bp);
|
||||
bp->ops->irq = 0;
|
||||
wake_lock_init(&bp->bp_wakelock, WAKE_LOCK_SUSPEND, "bp_wakelock");
|
||||
if((bp->ops->bp_wakeup_ap) && (bp->ops->trig != BP_UNKNOW_DATA))
|
||||
{
|
||||
result = request_irq(bp->ops->bp_wakeup_ap, bp_wake_up_irq, bp->ops->trig, "bp_wakeup_ap", bp);
|
||||
irq = gpio_to_irq(bp->ops->bp_wakeup_ap);
|
||||
result = request_irq(irq, bp_wake_up_irq, bp->ops->trig, "bp_wakeup_ap", bp);
|
||||
if (result < 0) {
|
||||
printk("%s: request_irq(%d) failed\n", __func__, bp->ops->bp_wakeup_ap);
|
||||
gpio_free(pdata->bp_wakeup_ap);
|
||||
return result;
|
||||
}
|
||||
bp->ops->irq = irq;
|
||||
}
|
||||
|
||||
if(bp->ops->init)
|
||||
bp->ops->init(bp);
|
||||
|
||||
enable_irq_wake(bp->ops->bp_wakeup_ap);
|
||||
wake_lock_init(&bp->bp_wakelock, WAKE_LOCK_SUSPEND, "bp_wakelock");
|
||||
|
||||
bp->status = BP_OFF;
|
||||
|
||||
@@ -468,7 +500,7 @@ static int bp_probe(struct platform_device *pdev)
|
||||
if(bp->ops->misc_name)
|
||||
bp->miscdev.name = bp->ops->misc_name;
|
||||
else
|
||||
bp->miscdev.name = "bp-auto";
|
||||
bp->miscdev.name = BP_DEV_NAME;
|
||||
bp->miscdev.fops = &bp->fops;
|
||||
}
|
||||
else
|
||||
@@ -512,14 +544,15 @@ int bp_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
|
||||
if(bp->ops->suspend)
|
||||
bp->ops->suspend(bp);
|
||||
|
||||
enable_irq_wake(bp->ops->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bp_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct bp_private_data *bp = platform_get_drvdata(pdev);
|
||||
|
||||
|
||||
disable_irq_wake(bp->ops->irq);
|
||||
if(bp->ops->resume)
|
||||
bp->ops->resume(bp);
|
||||
|
||||
@@ -532,7 +565,9 @@ void bp_shutdown(struct platform_device *pdev)
|
||||
|
||||
if(bp->ops->shutdown)
|
||||
bp->ops->shutdown(bp);
|
||||
|
||||
if(bp->ops->irq){
|
||||
free_irq(bp->ops->irq,bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -584,19 +619,19 @@ static struct platform_driver bp_driver = {
|
||||
static int __init bp_init(void)
|
||||
{
|
||||
int ret ;
|
||||
bp_class = class_create(THIS_MODULE, "bp-auto");
|
||||
ret = class_create_file(bp_class, &class_attr_bp_status);
|
||||
if (ret)
|
||||
{
|
||||
printk("Fail to create class bp-auto\n");
|
||||
}
|
||||
//bp_class = class_create(THIS_MODULE, "bp-auto");
|
||||
//ret = class_create_file(bp_class, &class_attr_bp_status);
|
||||
//if (ret)
|
||||
//{
|
||||
// printk("Fail to create class bp-auto\n");
|
||||
//}
|
||||
return platform_driver_register(&bp_driver);
|
||||
}
|
||||
|
||||
static void __exit bp_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bp_driver);
|
||||
class_remove_file(bp_class, &class_attr_bp_status);
|
||||
//class_remove_file(bp_class, &class_attr_bp_status);
|
||||
}
|
||||
|
||||
module_init(bp_init);
|
||||
|
||||
13
drivers/misc/bp/chips/Kconfig
Normal file → Executable file
13
drivers/misc/bp/chips/Kconfig
Normal file → Executable file
@@ -4,4 +4,15 @@ bool "modem mt6229"
|
||||
|
||||
config BP_AUTO_MU509
|
||||
bool "modem mu509"
|
||||
default n
|
||||
default n
|
||||
|
||||
config BP_AUTO_MW100
|
||||
bool "modem mw100"
|
||||
default n
|
||||
config BP_AUTO_MI700
|
||||
bool "modem mi700"
|
||||
default n
|
||||
config BP_AUTO_C66A
|
||||
bool "modem c66a"
|
||||
default n
|
||||
|
||||
|
||||
10
drivers/misc/bp/chips/Makefile
Normal file → Executable file
10
drivers/misc/bp/chips/Makefile
Normal file → Executable file
@@ -1,2 +1,8 @@
|
||||
obj-$(CONFIG_BP_AUTO_MT6229) += mt6229.o
|
||||
obj-$(CONFIG_BP_AUTO_MU509) += mu509.o
|
||||
obj-$(CONFIG_BP_AUTO) += mw100.o
|
||||
obj-$(CONFIG_BP_AUTO) += mi700.o
|
||||
obj-$(CONFIG_BP_AUTO) += mt6229.o
|
||||
obj-$(CONFIG_BP_AUTO) += mu509.o
|
||||
obj-$(CONFIG_BP_AUTO) += sc6610.o
|
||||
obj-$(CONFIG_BP_AUTO) += m51.o
|
||||
obj-$(CONFIG_BP_AUTO) += mtk6250.o
|
||||
obj-$(CONFIG_BP_AUTO) += c66a.o
|
||||
|
||||
207
drivers/misc/bp/chips/c66a.c
Normal file
207
drivers/misc/bp/chips/c66a.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/* drivers/misc/bp/chips/c66a.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("<-----c66a power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("<-----c66a power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(500);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
printk("<-----c66a bp_wake_ap-------->\n");
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_direction_output(bp->ops->bp_power,GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp,GPIO_HIGH);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl c66a reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(2000);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
bp->suspend_status = 1;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
printk("<-----c66a bp_resume-------->\n");
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_c66a_ops = {
|
||||
.name = "c66a",
|
||||
.bp_id = BP_ID_C66A,
|
||||
.bp_bus = BP_BUS_TYPE_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.bp_assert = BP_UNKNOW_DATA,//RK2928_PIN3_PC5,
|
||||
.trig = IRQF_TRIGGER_RISING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_c66a_ops;
|
||||
}
|
||||
|
||||
static int __init bp_c66a_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_c66a_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_c66a_init);
|
||||
module_exit(bp_c66a_exit);
|
||||
|
||||
234
drivers/misc/bp/chips/m51.c
Executable file
234
drivers/misc/bp/chips/m51.c
Executable file
@@ -0,0 +1,234 @@
|
||||
/* drivers/misc/bp/chips/m51.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("<-----m51 power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("<-----m51 power off-------->\n");
|
||||
//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
//msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(200);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(500);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
if(bp->pdata->gpio_valid ==0){
|
||||
|
||||
}
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);
|
||||
//if(bp->ops->active)
|
||||
//bp->ops->active(bp, 1);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl m51 reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(500);
|
||||
//gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
//if(bp->ops->active)
|
||||
//bp->ops->active(bp, 0);
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
printk("m51 bp_shutdown !!! \n");
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
bp->suspend_status = 1;
|
||||
//gpio_set_value(bp->ops->ap_ready, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
bp->suspend_status = 0;
|
||||
//gpio_set_value(bp->ops->ap_ready, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_m51_ops = {
|
||||
.name = "m51",
|
||||
.bp_id = BP_ID_M50,
|
||||
.bp_bus = BP_BUS_TYPE_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA, // RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // RK2928_PIN3_PC5,//BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA, // RK2928_PIN0_PB6,
|
||||
.ap_ready = BP_UNKNOW_DATA, // RK2928_PIN0_PD6, //
|
||||
.bp_ready = BP_UNKNOW_DATA, // RK2928_PIN0_PD0,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA, // RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA, // RK2928_PIN3_PC3, //
|
||||
.bp_assert = BP_UNKNOW_DATA,
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_FALLING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_m51_ops;
|
||||
}
|
||||
|
||||
static int __init bp_m51_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_m51_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_m51_init);
|
||||
module_exit(bp_m51_exit);
|
||||
|
||||
223
drivers/misc/bp/chips/mi700.c
Executable file
223
drivers/misc/bp/chips/mi700.c
Executable file
@@ -0,0 +1,223 @@
|
||||
/* drivers/misc/bp/chips/mi700.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("mi700 power on \n");
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(700);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("mi700 power off \n");
|
||||
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(2500);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl mi700 reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(700);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(!bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 1;
|
||||
//gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
bp->suspend_status = 0;
|
||||
//gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_mi700_ops = {
|
||||
.name = "mi700",
|
||||
.bp_id = BP_ID_MI700,
|
||||
.bp_bus = BP_BUS_TYPE_USB,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_FALLING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_mi700_ops;
|
||||
}
|
||||
|
||||
static int __init bp_mi700_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_mi700_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_mi700_init);
|
||||
module_exit(bp_mi700_exit);
|
||||
|
||||
@@ -53,6 +53,8 @@ static int bp_active(struct bp_private_data *bp, int enable)
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_uart_en, GPIO_LOW);
|
||||
@@ -61,6 +63,8 @@ static int bp_active(struct bp_private_data *bp, int enable)
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(10);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_uart_en, GPIO_HIGH);
|
||||
@@ -112,11 +116,10 @@ static void ap_wake_bp_work(struct work_struct *work)
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 1);
|
||||
|
||||
//gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
//msleep(1000);
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
@@ -148,35 +151,6 @@ static int bp_shutdown(struct bp_private_data *bp)
|
||||
}
|
||||
|
||||
|
||||
static int read_status(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int write_status(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (bp->status == BP_ON)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_uart_en,GPIO_LOW);
|
||||
}
|
||||
else if(bp->status == BP_OFF)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_uart_en,GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("%s, invalid parameter \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
@@ -192,19 +166,12 @@ static int bp_suspend(struct bp_private_data *bp)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
PREPARE_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
schedule_delayed_work(&bp->wakeup_work, 0);
|
||||
}
|
||||
|
||||
bp->suspend_status = 0;
|
||||
PREPARE_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
schedule_delayed_work(&bp->wakeup_work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -215,15 +182,15 @@ struct bp_operate bp_mt6229_ops = {
|
||||
.bp_bus = BP_BUS_TYPE_USB_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = RK30_PIN6_PB2, // 3g_power
|
||||
.bp_en = RK30_PIN2_PB6, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = RK30_PIN2_PB7, //
|
||||
.bp_power = BP_UNKNOW_DATA, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA,
|
||||
.bp_wakeup_ap = RK30_PIN6_PA1, //
|
||||
.bp_uart_en = RK30_PIN2_PC1, //EINT9
|
||||
.bp_usb_en = RK30_PIN2_PC0, //W_disable
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_RISING,
|
||||
|
||||
.active = bp_active,
|
||||
@@ -231,11 +198,11 @@ struct bp_operate bp_mt6229_ops = {
|
||||
.ap_wake_bp = ap_wake_bp,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = read_status,
|
||||
.write_status = write_status,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = "mt6229",
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
|
||||
231
drivers/misc/bp/chips/mtk6250.c
Normal file
231
drivers/misc/bp/chips/mtk6250.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/* drivers/misc/bp/chips/mt6250.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("<-----mt6250 power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
|
||||
mdelay(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
mdelay(2500);
|
||||
gpio_set_value(bp->ops->bp_en,GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("<-----mt6250 power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(2500);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
if(bp->pdata->gpio_valid ==0){
|
||||
|
||||
}
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
//gpio_direction_input(bp->ops->bp_ready);
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);
|
||||
|
||||
//if(bp->ops->active)
|
||||
//bp->ops->active(bp, 1);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl mt6250 reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(2000);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
bp->suspend_status = 1;
|
||||
gpio_set_value(bp->ops->ap_ready, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_ready, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_mt6250_ops = {
|
||||
.name = "mt6250",
|
||||
.bp_id = BP_ID_MT6250,
|
||||
.bp_bus = BP_BUS_TYPE_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA, // RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // RK2928_PIN3_PC5,//BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA, // RK2928_PIN0_PB6,
|
||||
.ap_ready = BP_UNKNOW_DATA, // RK2928_PIN0_PD0, //
|
||||
.bp_ready = BP_UNKNOW_DATA, // RK2928_PIN0_PD6,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA, // RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA, // RK2928_PIN3_PC3, //
|
||||
.bp_assert = BP_UNKNOW_DATA,
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_FALLING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_mt6250_ops;
|
||||
}
|
||||
|
||||
static int __init bp_mt6250_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_mt6250_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_mt6250_init);
|
||||
module_exit(bp_mt6250_exit);
|
||||
|
||||
@@ -53,18 +53,21 @@ static int bp_active(struct bp_private_data *bp, int enable)
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);
|
||||
// gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
// msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(700);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
// gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(2500);
|
||||
@@ -78,7 +81,7 @@ static int ap_wake_bp(struct bp_private_data *bp, int wake)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, wake);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, wake);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -93,6 +96,7 @@ static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
if(bp->ops->ap_wake_bp)
|
||||
bp->ops->ap_wake_bp(bp, 0);
|
||||
bp->suspend_status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -106,19 +110,32 @@ static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 1);
|
||||
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(500);
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);
|
||||
gpio_direction_output(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
// gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
|
||||
// msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
msleep(1000);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(700);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -143,50 +160,29 @@ static int bp_shutdown(struct bp_private_data *bp)
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int read_status(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int write_status(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (bp->status == BP_ON)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_HIGH);
|
||||
gpio_direction_output(bp->ops->bp_uart_en,GPIO_LOW);
|
||||
}
|
||||
else if(bp->status == BP_OFF)
|
||||
{
|
||||
gpio_direction_output(bp->ops->bp_usb_en, GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_uart_en,GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("%s, invalid parameter \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
printk("<-----mu509 bp_suspend-------->\n");
|
||||
#if defined(CONFIG_ARCH_RK29)
|
||||
rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
|
||||
#elif defined(CONFIG_ARCH_RK30)
|
||||
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_GPIO1A7);
|
||||
#endif
|
||||
|
||||
if(!bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 1;
|
||||
//printk("<-----mu509 bp_suspend----ap_wakeup_bp, GPIO_HIGH---->\n");
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -196,12 +192,17 @@ static int bp_suspend(struct bp_private_data *bp)
|
||||
|
||||
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
{
|
||||
#if defined(CONFIG_ARCH_RK29)
|
||||
rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
|
||||
#elif defined(CONFIG_ARCH_RK30)
|
||||
rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_UART1_RTS_N);
|
||||
#endif
|
||||
|
||||
//bp->suspend_status = 0;
|
||||
//gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
schedule_delayed_work(&bp->wakeup_work, 4*HZ);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -213,13 +214,13 @@ struct bp_operate bp_mu509_ops = {
|
||||
.bp_bus = BP_BUS_TYPE_USB_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = RK30_PIN6_PB2, // 3g_power
|
||||
.bp_en = RK30_PIN2_PB6, // 3g_en
|
||||
.bp_reset = RK30_PIN2_PC1,
|
||||
.bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,//RK2928_PIN1_PA3,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = RK30_PIN2_PB7,
|
||||
.bp_wakeup_ap = RK30_PIN6_PA1, //
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_FALLING,
|
||||
@@ -230,11 +231,11 @@ struct bp_operate bp_mu509_ops = {
|
||||
.ap_wake_bp = ap_wake_bp,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = read_status,
|
||||
.write_status = write_status,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = "mu509",
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
|
||||
242
drivers/misc/bp/chips/mw100.c
Executable file
242
drivers/misc/bp/chips/mw100.c
Executable file
@@ -0,0 +1,242 @@
|
||||
/* drivers/misc/bp/chips/mw100.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("mw100 power on \n");
|
||||
/* gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(500);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
|
||||
mdelay(10);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
|
||||
mdelay(500);
|
||||
//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
*/
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
msleep(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
msleep(500);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
|
||||
msleep(1000);
|
||||
//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("mw100 power off \n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
msleep(500);
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
//if(bp->ops->active)
|
||||
// bp->ops->active(bp, 1);
|
||||
//if(!bp->pdata->gpio_valid){
|
||||
//rk30_mux_api_set(GPIO1A3_I2S_LRCKTX_NAME,GPIO1A_GPIO1A3);
|
||||
//}
|
||||
gpio_direction_output(bp->ops->bp_power,GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_en,GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->bp_reset,GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp,GPIO_HIGH);
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl mw100 reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_en, GPIO_LOW);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
//gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
//mdelay(10);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
|
||||
mdelay(100);
|
||||
gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(!bp->suspend_status)
|
||||
{
|
||||
bp->suspend_status = 1;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_mw100_ops = {
|
||||
.name = "mw100",
|
||||
.bp_id = BP_ID_MW100,
|
||||
.bp_bus = BP_BUS_TYPE_USB,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA,//RK2928_PIN3_PC5, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,//RK2928_PIN1_PA3,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.trig = IRQF_TRIGGER_FALLING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_mw100_ops;
|
||||
}
|
||||
|
||||
static int __init bp_mw100_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_mw100_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_mw100_init);
|
||||
module_exit(bp_mw100_exit);
|
||||
|
||||
207
drivers/misc/bp/chips/sc6610.c
Executable file
207
drivers/misc/bp/chips/sc6610.c
Executable file
@@ -0,0 +1,207 @@
|
||||
/* drivers/misc/bp/chips/sc6610.c
|
||||
*
|
||||
* Copyright (C) 2012-2015 ROCKCHIP.
|
||||
* Author: luowei <lw@rock-chips.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include <linux/bp-auto.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************operate according to bp chip:start************/
|
||||
static int bp_active(struct bp_private_data *bp, int enable)
|
||||
{
|
||||
int result = 0;
|
||||
if(enable)
|
||||
{
|
||||
printk("<-----sc6610 power on-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("<-----sc6610 power off-------->\n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(500);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ap_wake_bp_work(struct work_struct *work)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static int bp_wake_ap(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->suspend_status)
|
||||
{
|
||||
printk("<-----sc6610 bp_wake_ap-------->\n");
|
||||
bp->suspend_status = 0;
|
||||
wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_init(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
gpio_direction_input(bp->ops->bp_wakeup_ap);
|
||||
gpio_direction_output(bp->ops->bp_power,GPIO_LOW);
|
||||
gpio_direction_output(bp->ops->ap_wakeup_bp,GPIO_HIGH);
|
||||
INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int bp_reset(struct bp_private_data *bp)
|
||||
{
|
||||
printk("ioctrl sc6610 reset !!! \n");
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_LOW);
|
||||
msleep(2000);
|
||||
gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
|
||||
return 0;
|
||||
}
|
||||
static int bp_shutdown(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(bp->ops->active)
|
||||
bp->ops->active(bp, 0);
|
||||
|
||||
cancel_delayed_work_sync(&bp->wakeup_work);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_suspend(struct bp_private_data *bp)
|
||||
{
|
||||
int result = 0;
|
||||
bp->suspend_status = 1;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
|
||||
|
||||
return result;
|
||||
}
|
||||
static int bp_resume(struct bp_private_data *bp)
|
||||
{
|
||||
|
||||
printk("<-----sc6610 bp_resume-------->\n");
|
||||
bp->suspend_status = 0;
|
||||
gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct bp_operate bp_sc6610_ops = {
|
||||
.name = "sc6610",
|
||||
.bp_id = BP_ID_SC6610,
|
||||
.bp_bus = BP_BUS_TYPE_UART,
|
||||
.bp_pid = 0,
|
||||
.bp_vid = 0,
|
||||
.bp_power = BP_UNKNOW_DATA, // RK2928_PIN3_PC2, // 3g_power
|
||||
.bp_en = BP_UNKNOW_DATA, // 3g_en
|
||||
.bp_reset = BP_UNKNOW_DATA,
|
||||
.ap_ready = BP_UNKNOW_DATA, //
|
||||
.bp_ready = BP_UNKNOW_DATA,
|
||||
.ap_wakeup_bp = BP_UNKNOW_DATA, // RK2928_PIN3_PC4,
|
||||
.bp_wakeup_ap = BP_UNKNOW_DATA, // RK2928_PIN3_PC3, //
|
||||
.bp_uart_en = BP_UNKNOW_DATA, //EINT9
|
||||
.bp_usb_en = BP_UNKNOW_DATA, //W_disable
|
||||
.bp_assert = BP_UNKNOW_DATA, // RK2928_PIN3_PC5,
|
||||
.trig = IRQF_TRIGGER_RISING,
|
||||
|
||||
.active = bp_active,
|
||||
.init = bp_init,
|
||||
.reset = bp_reset,
|
||||
.ap_wake_bp = NULL,
|
||||
.bp_wake_ap = bp_wake_ap,
|
||||
.shutdown = bp_shutdown,
|
||||
.read_status = NULL,
|
||||
.write_status = NULL,
|
||||
.suspend = bp_suspend,
|
||||
.resume = bp_resume,
|
||||
.misc_name = NULL,
|
||||
.private_miscdev = NULL,
|
||||
};
|
||||
|
||||
/****************operate according to bp chip:end************/
|
||||
|
||||
//function name should not be changed
|
||||
static struct bp_operate *bp_get_ops(void)
|
||||
{
|
||||
return &bp_sc6610_ops;
|
||||
}
|
||||
|
||||
static int __init bp_sc6610_init(void)
|
||||
{
|
||||
struct bp_operate *ops = bp_get_ops();
|
||||
int result = 0;
|
||||
result = bp_register_slave(NULL, NULL, bp_get_ops);
|
||||
if(result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ops->private_miscdev)
|
||||
{
|
||||
result = misc_register(ops->private_miscdev);
|
||||
if (result < 0) {
|
||||
printk("%s:misc_register err\n",__func__);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s\n",__func__);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit bp_sc6610_exit(void)
|
||||
{
|
||||
//struct bp_operate *ops = bp_get_ops();
|
||||
bp_unregister_slave(NULL, NULL, bp_get_ops);
|
||||
}
|
||||
|
||||
|
||||
subsys_initcall(bp_sc6610_init);
|
||||
module_exit(bp_sc6610_exit);
|
||||
|
||||
@@ -365,4 +365,12 @@ config TWL60xx_VBAT_LOW_DETECTION
|
||||
tristate "Support for twl60xx low battery detection."
|
||||
default n
|
||||
|
||||
config CHARGER_SMB347
|
||||
tristate "Summit Microelectronics SMB347 Battery Charger"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say Y to include support for Summit Microelectronics SMB347
|
||||
Battery Charger.
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
||||
@@ -41,9 +41,11 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
|
||||
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
|
||||
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
|
||||
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
|
||||
obj-$(CONFIG_TWL6030_BCI_BATTERY) += twl6030_bci_battery.o
|
||||
obj-$(CONFIG_BATTERY_RK29_ADC) += rk29_adc_battery.o
|
||||
obj-$(CONFIG_BATTERY_RK30_ADC) += rk30_adc_battery.o
|
||||
obj-$(CONFIG_PLAT_RK) += rk29_charger_display.o
|
||||
obj-$(CONFIG_BATTERY_RK30_ADC_FAC) += rk30_factory_adc_battery.o
|
||||
obj-$(CONFIG_CW2015_BATTERY) += cw2015_battery.o
|
||||
|
||||
|
||||
515
drivers/power/smb347-charger.c
Normal file
515
drivers/power/smb347-charger.c
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
* smb347 battery driver
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <linux/power/smb347-charger.h>
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include "../usb/dwc_otg/dwc_otg_driver.h"
|
||||
|
||||
#if 1
|
||||
#define xhc_printk(format, ...) printk(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define xhc_printk(format, ...)
|
||||
#endif
|
||||
|
||||
#define SMB347_STATUS_D 0x3d
|
||||
#define SMB347_SPEED (300 * 1000)
|
||||
#define MAX_REG_INDEX 0x3f
|
||||
|
||||
struct workqueue_struct *wq;
|
||||
struct smb347_device{
|
||||
struct i2c_client *client;
|
||||
struct delayed_work work;
|
||||
struct smb347_info *info;
|
||||
struct work_struct full_power_work_struct;
|
||||
int usb_host_in;
|
||||
};
|
||||
|
||||
|
||||
/* Input current limit in mA */
|
||||
static const unsigned int icl_tbl[] = {
|
||||
300,
|
||||
500,
|
||||
700,
|
||||
900,
|
||||
1200,
|
||||
1500,
|
||||
1800,
|
||||
2000,
|
||||
2200,
|
||||
2500,
|
||||
};
|
||||
|
||||
extern dwc_otg_device_t* g_otgdev;
|
||||
struct smb347_device * g_smb347_dev;
|
||||
static void smb347_init(struct i2c_client *client);
|
||||
|
||||
static int smb347_read(struct i2c_client *client, const char reg, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, SMB347_SPEED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smb347_write(struct i2c_client *client,const char reg, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, len, SMB347_SPEED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dump_smb347_reg(struct smb347_device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
char buf = 0;
|
||||
int reg = 0;
|
||||
if(!dev)
|
||||
{
|
||||
xhc_printk("dev is null");
|
||||
return -1;
|
||||
}
|
||||
for(reg = 0; reg <= MAX_REG_INDEX; reg++)
|
||||
{
|
||||
ret = i2c_master_reg8_recv(dev->client, reg, &buf, 1, SMB347_SPEED);
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
printk("read smb137 reg error:%d\n",ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("reg 0x%x:0x%x\n",reg,buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static ssize_t smb_debug_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t _count)
|
||||
{
|
||||
int temp;
|
||||
u8 reg;
|
||||
u8 val;
|
||||
struct smb347_device *smb347_dev = dev_get_drvdata(dev);
|
||||
if (sscanf(buf, "%x", &temp) != 1)
|
||||
return -EINVAL;
|
||||
val = temp & 0x00ff;
|
||||
reg = temp >> 8;
|
||||
smb347_write(smb347_dev->client, reg, &val,1);
|
||||
|
||||
return _count;
|
||||
}
|
||||
|
||||
static ssize_t smb_debug_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct smb347_device *smb347_dev = dev_get_drvdata(dev);
|
||||
dump_smb347_reg(smb347_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_attribute smb_debug =
|
||||
__ATTR(smb_debug, S_IRUGO | S_IWUSR, smb_debug_show, smb_debug_store);
|
||||
|
||||
int smb347_is_chg_ok(void)
|
||||
{
|
||||
u8 reg = 0;
|
||||
int ret = 0;
|
||||
|
||||
smb347_read(g_smb347_dev->client, 0x37, ®, 1);
|
||||
ret = (reg & 0x03);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(smb347_is_chg_ok);
|
||||
|
||||
int smb347_is_charging(void)
|
||||
{
|
||||
int status = 0;//POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
u8 data = 0;
|
||||
|
||||
smb347_read(g_smb347_dev->client, SMB347_STATUS_D, &data, 1);
|
||||
if (data & 0x06)
|
||||
status = 1;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(smb347_is_charging);
|
||||
|
||||
void smb347_set_something(void)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
smb347_init(g_smb347_dev->client);
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(smb347_set_something);
|
||||
|
||||
void smb347_set_charging(void)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = 0x26;
|
||||
smb347_write(g_smb347_dev->client, 0x03, &val, 1);
|
||||
|
||||
smb347_read(g_smb347_dev->client, 0x04, &val, 1);
|
||||
val &= 0x7f;
|
||||
smb347_write(g_smb347_dev->client, 0x04, &val, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(smb347_set_charging);
|
||||
|
||||
void smb347_set_discharging(void)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = 0x20;
|
||||
smb347_write(g_smb347_dev->client, 0x03, &val, 1);
|
||||
|
||||
smb347_read(g_smb347_dev->client, 0x04, &val, 1);
|
||||
val |= 0x80;
|
||||
smb347_write(g_smb347_dev->client, 0x04, &val, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(smb347_set_discharging);
|
||||
|
||||
/* Convert current to register value using lookup table */
|
||||
static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < size; i++) {
|
||||
if (val < tbl[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i > 0 ? i - 1 : -EINVAL;
|
||||
}
|
||||
|
||||
static int smb347_set_current_limits(struct smb347_device *smb_dev)
|
||||
{
|
||||
char ret;
|
||||
if (smb_dev->info->max_current) {
|
||||
xhc_printk("xhc_test_smb_dev->info->max_current = %d\n", smb_dev->info->max_current);
|
||||
ret = current_to_hw (icl_tbl, ARRAY_SIZE(icl_tbl),
|
||||
smb_dev->info->max_current);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = (ret << 4) + ret;
|
||||
ret = 0x77; //Hardcode 2000mA 2012-11-06
|
||||
xhc_printk("ret = %x\n", ret);
|
||||
ret = smb347_write(smb_dev->client, 0x01, &ret, 1);
|
||||
xhc_printk("ret = %x\n", ret);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void suspend_smb347(struct smb347_device *smb347_dev)
|
||||
{
|
||||
u8 reg;
|
||||
reg = 0x80;
|
||||
smb347_write(smb347_dev->client,0x30,®,1);
|
||||
smb347_read(smb347_dev->client, 0x02, ®, 1);
|
||||
reg = (reg&0x7f);
|
||||
smb347_write(smb347_dev->client,0x02,®,1);
|
||||
xhc_printk("%s\n", __func__);
|
||||
}
|
||||
|
||||
static void active_smb347(struct smb347_device *smb347_dev)
|
||||
{
|
||||
u8 reg;
|
||||
reg = 0x80;
|
||||
smb347_write(smb347_dev->client,0x30,®,1);
|
||||
smb347_read(smb347_dev->client, 0x02, ®, 1);
|
||||
reg = (reg | 0x80);
|
||||
smb347_write(smb347_dev->client,0x02,®,1);
|
||||
xhc_printk("%s\n", __func__);
|
||||
}
|
||||
|
||||
static int smb347_set_otg_control(struct smb347_device *smb_dev)
|
||||
{
|
||||
char ret;
|
||||
char reg;
|
||||
if (smb_dev->info->otg_power_form_smb == 1) {
|
||||
ret = smb347_read(smb_dev->client, 0x09, ®, 1);
|
||||
if (ret < 0) {
|
||||
xhc_printk("error,ret = %x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
reg &= 0xef;
|
||||
reg |= 0x40;
|
||||
reg |= 0x20;
|
||||
ret = smb347_write(smb_dev->client,0x09,®,1);
|
||||
if (ret < 0) {
|
||||
xhc_printk("error,ret = %x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
reg = 0x76;
|
||||
smb347_write(smb_dev->client,0x0a,®,1);
|
||||
if (ret < 0) {
|
||||
xhc_printk("error,ret = %x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void smb347_init(struct i2c_client *client)
|
||||
{
|
||||
u8 reg;
|
||||
reg = 0x80;
|
||||
smb347_write(client, 0x30, ®, 1);
|
||||
|
||||
reg = 0xfd;
|
||||
smb347_write(client, 0x00, ®, 1);
|
||||
|
||||
reg = 0x77;
|
||||
smb347_write(client, 0x01, ®, 1);
|
||||
|
||||
reg = 0x26;
|
||||
smb347_write(client, 0x03, ®, 1);
|
||||
|
||||
smb347_read(client, 0x05, ®, 1);
|
||||
reg |= 0x80;
|
||||
smb347_write(client, 0x05, ®, 1);
|
||||
|
||||
/* close interrupt */
|
||||
smb347_read(client, 0x38, ®, 1);
|
||||
smb347_read(client, 0x3a, ®, 1);
|
||||
reg = 0x0;
|
||||
smb347_write(client, 0x0c, ®, 1);
|
||||
smb347_write(client, 0x0d, ®, 1);
|
||||
|
||||
/* set dc charge when bosh inser dc and usb */
|
||||
smb347_read(client, 0x02, ®, 1);
|
||||
reg = reg & 0xfb;
|
||||
smb347_write(client, 0x02, ®, 1);
|
||||
|
||||
|
||||
smb347_set_otg_control(g_smb347_dev);
|
||||
smb347_set_current_limits(g_smb347_dev);
|
||||
|
||||
dump_smb347_reg(g_smb347_dev);
|
||||
}
|
||||
|
||||
static void smb347_set_current_work(struct work_struct *work)
|
||||
{
|
||||
struct smb347_device *smb347_dev = container_of(to_delayed_work(work), struct smb347_device, work);
|
||||
u8 reg;
|
||||
if (g_otgdev->core_if->op_state == A_HOST && smb347_dev->usb_host_in == 0) {
|
||||
|
||||
xhc_printk("otg_dev->core_if->op_state = %d\n", g_otgdev->core_if->op_state);
|
||||
if (g_smb347_dev->info->otg_power_form_smb == 1) {
|
||||
|
||||
reg = 0x7e;
|
||||
smb347_write(smb347_dev->client,0x0a,®,1);
|
||||
} else {
|
||||
suspend_smb347(smb347_dev);
|
||||
}
|
||||
smb347_dev->usb_host_in = 1;
|
||||
} else if (g_otgdev->core_if->op_state != A_HOST && smb347_dev->usb_host_in == 1) {
|
||||
|
||||
xhc_printk("otg_dev->core_if->op_state = %d\n", g_otgdev->core_if->op_state);
|
||||
if (g_smb347_dev->info->otg_power_form_smb == 1) {
|
||||
reg = 0x76;
|
||||
smb347_write(smb347_dev->client,0x0a,®,1);
|
||||
} else {
|
||||
active_smb347(smb347_dev);
|
||||
}
|
||||
smb347_dev->usb_host_in = 0;
|
||||
}
|
||||
schedule_delayed_work(&smb347_dev->work, 100);
|
||||
}
|
||||
|
||||
static int smb347_battery_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
struct smb347_device *smb347_dev;
|
||||
struct smb347_info *info = client->dev.platform_data;;
|
||||
|
||||
xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
|
||||
smb347_dev = kzalloc(sizeof(struct smb347_device), GFP_KERNEL);
|
||||
smb347_dev->usb_host_in = 0;
|
||||
if (!smb347_dev) {
|
||||
dev_err(&client->dev, "failed to allocate device info data\n");
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
|
||||
i2c_set_clientdata(client, smb347_dev);
|
||||
dev_set_drvdata(&client->dev,smb347_dev);
|
||||
smb347_dev->client = client;
|
||||
smb347_dev->info = info;
|
||||
g_smb347_dev = smb347_dev;
|
||||
wq = create_singlethread_workqueue("smb347_det");
|
||||
|
||||
if(info->chg_susp_pin) {
|
||||
rk30_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME, 0);
|
||||
ret = gpio_request(info->chg_susp_pin, "chg susp pin");
|
||||
if (ret != 0) {
|
||||
gpio_free(info->chg_susp_pin);
|
||||
xhc_printk("smb347 gpio_request chg_susp_pin error\n");
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_output(info->chg_susp_pin, 0);
|
||||
gpio_set_value(info->chg_susp_pin, GPIO_HIGH);
|
||||
}
|
||||
//msleep(200);
|
||||
if(info->chg_ctl_pin) {
|
||||
ret = gpio_request(info->chg_ctl_pin, "chg ctl pin");
|
||||
if (ret != 0) {
|
||||
gpio_free(info->chg_ctl_pin);
|
||||
xhc_printk("smb347 gpio_request chg_ctl_pin error\n");
|
||||
return -EIO;
|
||||
}
|
||||
xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
|
||||
gpio_direction_output(info->chg_ctl_pin, 0);
|
||||
// gpio_set_value(info->chg_ctl_pin, GPIO_HIGH);
|
||||
}
|
||||
|
||||
if(info->chg_en_pin)
|
||||
{
|
||||
rk30_mux_api_set(GPIO4D5_SMCDATA13_TRACEDATA13_NAME, 0);
|
||||
ret = gpio_request(info->chg_en_pin, "chg en pin");
|
||||
if (ret != 0) {
|
||||
gpio_free(info->chg_en_pin);
|
||||
xhc_printk("smb347 gpio_request chg_en_pin error\n");
|
||||
return -EIO;
|
||||
}
|
||||
gpio_direction_output(info->chg_en_pin, 0);
|
||||
gpio_set_value(info->chg_en_pin, GPIO_LOW);
|
||||
}
|
||||
mdelay(100);
|
||||
smb347_init(client);
|
||||
|
||||
INIT_DELAYED_WORK(&smb347_dev->work,smb347_set_current_work);
|
||||
schedule_delayed_work(&smb347_dev->work, msecs_to_jiffies(3*1000));
|
||||
|
||||
ret = device_create_file(&client->dev,&smb_debug);
|
||||
if(ret) {
|
||||
dev_err(&client->dev, "failed to create sysfs file\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smb347_battery_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smb347_battery_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
xhc_printk("__xhc__%s,", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smb347_battery_resume(struct i2c_client *client)
|
||||
{
|
||||
xhc_printk("__xhc__%s,", __func__);
|
||||
return 0;
|
||||
}
|
||||
static void smb347_battery_shutdown(struct i2c_client *client)
|
||||
{
|
||||
u8 reg = 0x0e;
|
||||
smb347_write(client,0x09,®,1);
|
||||
xhc_printk("%s,----xhc----\n", __func__);
|
||||
}
|
||||
static const struct i2c_device_id smb347_id[] = {
|
||||
{ "smb347", 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct i2c_driver smb347_battery_driver = {
|
||||
.probe = smb347_battery_probe,
|
||||
.remove = smb347_battery_remove,
|
||||
.suspend = smb347_battery_suspend,
|
||||
.resume = smb347_battery_resume,
|
||||
.shutdown = smb347_battery_shutdown,
|
||||
|
||||
.id_table = smb347_id,
|
||||
.driver = {
|
||||
.name = "smb347",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init smb347_battery_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_add_driver(&smb347_battery_driver);
|
||||
if (ret)
|
||||
xhc_printk(KERN_ERR "Unable to register smb347 driver\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit smb347_battery_exit(void)
|
||||
{
|
||||
if (g_smb347_dev->info->otg_power_form_smb != 1) {
|
||||
active_smb347(g_smb347_dev);
|
||||
}
|
||||
i2c_del_driver(&smb347_battery_driver);
|
||||
}
|
||||
|
||||
//subsys_initcall_sync(smb347_battery_init);
|
||||
subsys_initcall(smb347_battery_init);
|
||||
module_exit(smb347_battery_exit);
|
||||
|
||||
/*
|
||||
delay 500ms to fix the problam
|
||||
that sometime limit 500ma when startup when insert the hc charger
|
||||
*/
|
||||
static int __init delay_for_smb347(void)
|
||||
{
|
||||
xhc_printk("function: %s\n", __func__);
|
||||
mdelay(500);
|
||||
return 0;
|
||||
}
|
||||
core_initcall(delay_for_smb347);
|
||||
|
||||
MODULE_AUTHOR("xhc@rock-chips.com");
|
||||
MODULE_DESCRIPTION("smb347 battery monitor driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -42,7 +42,9 @@
|
||||
*/
|
||||
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
|
||||
#define DRIVER_DESC "USB Serial Driver core"
|
||||
|
||||
#ifdef CONFIG_BP_AUTO
|
||||
extern int get_current_bp_id();
|
||||
#endif
|
||||
/* Driver structure we register with the USB core */
|
||||
static struct usb_driver usb_serial_driver = {
|
||||
.name = "usbserial",
|
||||
@@ -53,23 +55,12 @@ static struct usb_driver usb_serial_driver = {
|
||||
.no_dynamic_id = 1,
|
||||
.supports_autosuspend = 1,
|
||||
};
|
||||
#if defined(CONFIG_MU509) || defined(CONFIG_BP_AUTO_MU509)
|
||||
static int MU509_USB = 0;
|
||||
#define MU509_USB_PORT (SERIAL_TTY_MINORS - 10)
|
||||
#endif
|
||||
#if defined(CONFIG_MW100) || defined(CONFIG_BP_AUTO_MW100)
|
||||
static int MW100_USB = 0;
|
||||
#define MW100_USB_PORT (SERIAL_TTY_MINORS - 10)
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229) || defined(CONFIG_BP_AUTO_MT6229)
|
||||
static int MT6229_USB = 0;
|
||||
#define MT6229_USB_PORT (SERIAL_TTY_MINORS - 10)
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868) || defined(CONFIG_BP_AUTO_SEW868)
|
||||
static int SEW868_USB = 0;
|
||||
#define SEW868_USB_PORT (SERIAL_TTY_MINORS - 10)
|
||||
#ifdef CONFIG_BP_AUTO
|
||||
static int BP_USB = 0;
|
||||
#define BP_USB_PORT (SERIAL_TTY_MINORS - 10)
|
||||
#endif
|
||||
|
||||
|
||||
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
|
||||
the MODULE_DEVICE_TABLE declarations in each serial driver
|
||||
cause the "hotplug" program to pull in whatever module is necessary
|
||||
@@ -119,22 +110,11 @@ static struct usb_serial *get_free_serial(struct usb_serial *serial,
|
||||
|
||||
*minor = 0;
|
||||
mutex_lock(&table_lock);
|
||||
#if defined(CONFIG_MU509) || defined(CONFIG_BP_AUTO_MU509)
|
||||
if (MU509_USB)
|
||||
a= MU509_USB_PORT;
|
||||
#endif
|
||||
#if defined(CONFIG_MW100) || defined(CONFIG_BP_AUTO_MW100)
|
||||
if (MW100_USB)
|
||||
a= MW100_USB_PORT;
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229) || defined(CONFIG_BP_AUTO_MT6229)
|
||||
if (MT6229_USB)
|
||||
a= MT6229_USB_PORT;
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868) || defined(CONFIG_BP_AUTO_SEW868)
|
||||
if (SEW868_USB)
|
||||
a= SEW868_USB_PORT;
|
||||
#ifdef CONFIG_BP_AUTO
|
||||
if (BP_USB)
|
||||
a= BP_USB_PORT;
|
||||
#endif
|
||||
|
||||
for (i = a; i < SERIAL_TTY_MINORS; ++i) {
|
||||
if (serial_table[i])
|
||||
continue;
|
||||
@@ -1093,29 +1073,19 @@ int usb_serial_probe(struct usb_interface *interface,
|
||||
} else {
|
||||
serial->attached = 1;
|
||||
}
|
||||
#if defined(CONFIG_MU509) || defined(CONFIG_BP_AUTO_MU509)
|
||||
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x12D1 ) && (le16_to_cpu(dev->descriptor.idProduct) == 0x1001))
|
||||
MU509_USB =1;
|
||||
else
|
||||
MU509_USB = 0;
|
||||
#endif
|
||||
#if defined(CONFIG_MW100) || defined(CONFIG_BP_AUTO_MW100)
|
||||
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x19f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x9013))
|
||||
MW100_USB =1;
|
||||
else
|
||||
MW100_USB = 0;
|
||||
#endif
|
||||
#if defined(CONFIG_MT6229) || defined(CONFIG_BP_AUTO_MT6229)
|
||||
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x0E8D) && (le16_to_cpu(dev->descriptor.idProduct) == 0x00A2))
|
||||
MT6229_USB =1;
|
||||
else
|
||||
MT6229_USB = 0;
|
||||
#endif
|
||||
#if defined(CONFIG_SEW868) || defined(CONFIG_BP_AUTO_SEW868)
|
||||
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x19d2) && (le16_to_cpu(dev->descriptor.idProduct) == 0xffeb))
|
||||
SEW868_USB =1;
|
||||
else
|
||||
SEW868_USB = 0;
|
||||
#ifdef CONFIG_BP_AUTO
|
||||
int bp_id = get_current_bp_id();
|
||||
if (((le16_to_cpu(dev->descriptor.idVendor) == 0x12D1 ) && (le16_to_cpu(dev->descriptor.idProduct) == 0x1001) && (bp_id == 2))
|
||||
|| ((le16_to_cpu(dev->descriptor.idVendor) == 0x19f5) && (le16_to_cpu(dev->descriptor.idProduct) == 0x9013) && (bp_id == 4))
|
||||
|| ((le16_to_cpu(dev->descriptor.idVendor) == 0x0E8D) && (le16_to_cpu(dev->descriptor.idProduct) == 0x00A2) && (bp_id == 1))
|
||||
){
|
||||
BP_USB =1;
|
||||
|
||||
}
|
||||
else{
|
||||
BP_USB = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Avoid race with tty_open and serial_install by setting the
|
||||
|
||||
@@ -85,7 +85,16 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
|
||||
screen->standby = standby;
|
||||
}
|
||||
|
||||
|
||||
size_t get_fb_size(void)
|
||||
{
|
||||
size_t size = 0;
|
||||
#if defined(CONFIG_THREE_FB_BUFFER)
|
||||
size = ((H_VD)*(V_VD)<<2)* 3; //three buffer
|
||||
#else
|
||||
size = ((H_VD)*(V_VD)<<2)<<1; //two buffer
|
||||
#endif
|
||||
return ALIGN(size,SZ_1M);
|
||||
}
|
||||
static int standby(u8 enable)
|
||||
{
|
||||
printk(KERN_INFO "byd1024x600 lcd standby, enable=%d\n", enable);
|
||||
|
||||
@@ -4,33 +4,38 @@
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
struct bp_private_data;
|
||||
|
||||
#define BP_DEV_NAME "voice_modem"
|
||||
#define BP_UNKNOW_DATA -1
|
||||
#define BP_OFF 0
|
||||
#define BP_ON 1
|
||||
#define BP_SUSPEND 2
|
||||
#define BP_WAKE 3
|
||||
|
||||
#define BP_IOCTL_BASE 'm'
|
||||
#define BP_IOCTL_BASE 0x1a
|
||||
|
||||
#define BP_IOCTL_RESET _IOW(BP_IOCTL_BASE, 0x00, int)
|
||||
#define BP_IOCTL_POWON _IOW(BP_IOCTL_BASE, 0x01, int)
|
||||
#define BP_IOCTL_RESET _IOW(BP_IOCTL_BASE, 0x01, int)
|
||||
#define BP_IOCTL_POWOFF _IOW(BP_IOCTL_BASE, 0x02, int)
|
||||
#define BP_IOCTL_WRITE_STATUS _IOW(BP_IOCTL_BASE, 0x03, int)
|
||||
#define BP_IOCTL_GET_STATUS _IOR(BP_IOCTL_BASE, 0x04, int)
|
||||
#define BP_IOCTL_SET_PVID _IOW(BP_IOCTL_BASE, 0x05, int)
|
||||
#define BP_IOCTL_GET_BPID _IOR(BP_IOCTL_BASE, 0x06, int)
|
||||
#define BP_IOCTL_POWON _IOW(BP_IOCTL_BASE, 0x03, int)
|
||||
|
||||
#define BP_IOCTL_WRITE_STATUS _IOW(BP_IOCTL_BASE, 0x04, int)
|
||||
#define BP_IOCTL_GET_STATUS _IOR(BP_IOCTL_BASE, 0x05, int)
|
||||
#define BP_IOCTL_SET_PVID _IOW(BP_IOCTL_BASE, 0x06, int)
|
||||
#define BP_IOCTL_GET_BPID _IOR(BP_IOCTL_BASE, 0x07, int)
|
||||
#define BP_IOCTL_GET_IMEI _IOR(BP_IOCTL_BASE, 0x08, int)
|
||||
|
||||
enum bp_id{
|
||||
BP_ID_INVALID = 0,
|
||||
BP_ID_INVALID = 0,//no bp
|
||||
|
||||
BP_ID_MT6229,
|
||||
BP_ID_MU509,
|
||||
BP_ID_MI700,
|
||||
BP_ID_MW100,
|
||||
BP_ID_TD8801,
|
||||
|
||||
BP_ID_NUM,
|
||||
BP_ID_MT6229, //USI MT6229 WCDMA
|
||||
BP_ID_MU509, //huawei MU509 WCDMA
|
||||
BP_ID_MI700, //thinkwill MI700 WCDMA
|
||||
BP_ID_MW100, //thinkwill MW100 WCDMA
|
||||
BP_ID_TD8801, //spreadtrum SC8803 TD-SCDMA
|
||||
BP_ID_SC6610, //spreadtrum SC6610 GSM
|
||||
BP_ID_M50, //spreadtrum RDA GSM
|
||||
BP_ID_MT6250, //ZINN M50 EDGE
|
||||
BP_ID_C66A, //zhongben
|
||||
BP_ID_NUM,
|
||||
};
|
||||
|
||||
|
||||
@@ -54,14 +59,15 @@ struct bp_platform_data {
|
||||
int bp_id;
|
||||
int (*init_platform_hw)(void);
|
||||
int (*exit_platform_hw)(void);
|
||||
|
||||
int (*get_bp_id)(void);
|
||||
int bp_power;
|
||||
int bp_en;
|
||||
int bp_reset;
|
||||
int ap_ready;
|
||||
int bp_ready;
|
||||
int ap_wakeup_bp;
|
||||
int bp_wakeup_ap;
|
||||
int bp_wakeup_ap;
|
||||
int bp_assert;
|
||||
int bp_usb_en;
|
||||
int bp_uart_en;
|
||||
|
||||
@@ -70,23 +76,25 @@ struct bp_platform_data {
|
||||
|
||||
|
||||
struct bp_operate {
|
||||
char *name;
|
||||
int bp_id;
|
||||
int bp_bus;
|
||||
|
||||
int bp_pid;
|
||||
int bp_vid;
|
||||
int bp_power;
|
||||
int bp_en;
|
||||
int bp_reset;
|
||||
int ap_ready;
|
||||
int bp_ready;
|
||||
int ap_wakeup_bp;
|
||||
int bp_wakeup_ap;
|
||||
int bp_usb_en;
|
||||
int bp_uart_en;
|
||||
int trig;
|
||||
char *name; //bp name can be null
|
||||
int bp_id; //bp id the value must be one of enum bp_id
|
||||
int bp_bus; // bp bus the value must be one of enum bp_bus_type
|
||||
|
||||
int bp_pid; // the pid of usb device if used usb else the value is BP_UNKNOW_DATA
|
||||
int bp_vid; // the vid of usb device if used usb else the value is BP_UNKNOW_DATA
|
||||
int bp_power;//bp power if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int bp_en;//bp power key if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int bp_reset;//bo reset if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int ap_ready;//bp ready if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int bp_ready;// bp ready if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int ap_wakeup_bp; //ap wakeup bp if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int bp_wakeup_ap;// bp wakeup ap if used GPIO value else the is BP_UNKNOW_DATA
|
||||
int bp_assert;
|
||||
int bp_usb_en;//not used
|
||||
int bp_uart_en;//not used
|
||||
int trig;//if 1:used board gpio define else used bp driver
|
||||
int irq;
|
||||
|
||||
int (*active)(struct bp_private_data *bp, int enable);
|
||||
int (*init)(struct bp_private_data *bp);
|
||||
int (*reset)(struct bp_private_data *bp);
|
||||
@@ -96,8 +104,7 @@ struct bp_operate {
|
||||
int (*read_status)(struct bp_private_data *bp);
|
||||
int (*write_status)(struct bp_private_data *bp);
|
||||
int (*suspend)(struct bp_private_data *bp);
|
||||
int (*resume)(struct bp_private_data *bp);
|
||||
|
||||
int (*resume)(struct bp_private_data *bp);
|
||||
char *misc_name;
|
||||
struct miscdevice *private_miscdev;
|
||||
|
||||
@@ -116,9 +123,7 @@ struct bp_private_data {
|
||||
struct miscdevice miscdev;
|
||||
struct file_operations id_fops;
|
||||
struct miscdevice id_miscdev;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern int bp_register_slave(struct bp_private_data *bp,
|
||||
|
||||
26
include/linux/power/smb347-charger.h
Normal file
26
include/linux/power/smb347-charger.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef SMB347_CHARGER_H
|
||||
#define SMB347_CHARGER_H
|
||||
|
||||
/*
|
||||
* @chg_en_pin: charge enable pin (smb347's c4 pin)
|
||||
* @chg_ctl_pin: charge control pin (smb347's d2 pin)
|
||||
* @chg_stat_pin: charge stat pin (smb347's f5 pin)
|
||||
* @chg_susp_pin: charge usb suspend pin (smb347's d3 pin)
|
||||
* @max_current: dc and hc input current limit
|
||||
* can set 300ma/500ma/700ma/900ma/1200ma
|
||||
* or 1500ma/1800ma/2000ma/2200ma/2500ma
|
||||
* @otg_power_form_smb: if otg 5v power form smb347 set 1 otherwise set 0
|
||||
*/
|
||||
struct smb347_info{
|
||||
unsigned int chg_en_pin;
|
||||
unsigned int chg_ctl_pin;
|
||||
unsigned int chg_stat_pin;
|
||||
unsigned int chg_susp_pin;
|
||||
unsigned int max_current;
|
||||
bool otg_power_form_smb;
|
||||
};
|
||||
|
||||
extern int smb347_is_chg_ok(void);
|
||||
extern int smb347_is_charging(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user