From 2fd93fbff1efa2de6606cd37c7a5a3bcadafcaff Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=93=9D=E6=96=8C=E5=85=83?= Date: Wed, 6 Mar 2013 18:13:33 +0800 Subject: [PATCH] rk3066 add phone pad modem support --- .../configs/rk3066_z600t_phonepad_defconfig | 437 ++++ arch/arm/mach-rk30/Kconfig | 5 +- arch/arm/mach-rk30/Makefile | 8 +- .../arm/mach-rk30/board-rk30-phonepad-z600t.c | 2083 +++++++++++++++++ arch/arm/mach-rk30/board-rk30-sdk.c | 312 ++- arch/arm/plat-rk/include/plat/board.h | 7 + drivers/input/touchscreen/Kconfig | 12 + drivers/input/touchscreen/Makefile | 3 + drivers/input/touchscreen/ct36x_ts/Kconfig | 63 + drivers/input/touchscreen/ct36x_ts/Makefile | 26 + .../input/touchscreen/ct36x_ts/allwinner.c | 99 + drivers/input/touchscreen/ct36x_ts/chip.h | 13 + drivers/input/touchscreen/ct36x_ts/ct360.c | 363 +++ drivers/input/touchscreen/ct36x_ts/ct360.h | 77 + drivers/input/touchscreen/ct36x_ts/ct365.c | 439 ++++ drivers/input/touchscreen/ct36x_ts/ct365.h | 96 + drivers/input/touchscreen/ct36x_ts/generic.c | 109 + drivers/input/touchscreen/ct36x_ts/generic.h | 8 + drivers/input/touchscreen/ct36x_ts/platform.h | 22 + drivers/input/touchscreen/ct36x_ts/rockchip.c | 136 ++ drivers/input/touchscreen/ct36x_ts/rockchip.h | 15 + drivers/input/touchscreen/ct36x_ts/tscore.c | 572 +++++ drivers/input/touchscreen/ct36x_ts/tscore.h | 80 + drivers/input/touchscreen/ft5506_app.f | 1793 ++++++++++++++ drivers/input/touchscreen/ft5506_wgj.c | 1172 ++++++++++ drivers/input/touchscreen/ft5506_wgj.h | 120 + drivers/misc/3g_module/Kconfig | 31 - drivers/misc/3g_module/Makefile | 6 - drivers/misc/3g_module/mi700.c | 352 --- drivers/misc/3g_module/mt6229.c | 358 --- drivers/misc/3g_module/mu509.c | 339 --- drivers/misc/3g_module/mw100.c | 235 -- drivers/misc/3g_module/sc6610.c | 231 -- drivers/misc/3g_module/sew868.c | 228 -- drivers/misc/Kconfig | 1 - drivers/misc/Makefile | 1 - drivers/misc/bp/Kconfig | 9 +- drivers/misc/bp/bp-auto.c | 129 +- drivers/misc/bp/chips/Kconfig | 13 +- drivers/misc/bp/chips/Makefile | 10 +- drivers/misc/bp/chips/c66a.c | 207 ++ drivers/misc/bp/chips/m51.c | 234 ++ drivers/misc/bp/chips/mi700.c | 223 ++ drivers/misc/bp/chips/mt6229.c | 77 +- drivers/misc/bp/chips/mtk6250.c | 231 ++ drivers/misc/bp/chips/mu509.c | 115 +- drivers/misc/bp/chips/mw100.c | 242 ++ drivers/misc/bp/chips/sc6610.c | 207 ++ drivers/power/Kconfig | 8 + drivers/power/Makefile | 2 + drivers/power/smb347-charger.c | 515 ++++ drivers/usb/serial/usb-serial.c | 78 +- drivers/video/display/screen/lcd_hj101na.c | 11 +- include/linux/bp-auto.h | 83 +- include/linux/power/smb347-charger.h | 26 + 55 files changed, 10065 insertions(+), 2207 deletions(-) create mode 100644 arch/arm/configs/rk3066_z600t_phonepad_defconfig create mode 100644 arch/arm/mach-rk30/board-rk30-phonepad-z600t.c create mode 100644 drivers/input/touchscreen/ct36x_ts/Kconfig create mode 100644 drivers/input/touchscreen/ct36x_ts/Makefile create mode 100644 drivers/input/touchscreen/ct36x_ts/allwinner.c create mode 100644 drivers/input/touchscreen/ct36x_ts/chip.h create mode 100644 drivers/input/touchscreen/ct36x_ts/ct360.c create mode 100644 drivers/input/touchscreen/ct36x_ts/ct360.h create mode 100644 drivers/input/touchscreen/ct36x_ts/ct365.c create mode 100644 drivers/input/touchscreen/ct36x_ts/ct365.h create mode 100644 drivers/input/touchscreen/ct36x_ts/generic.c create mode 100644 drivers/input/touchscreen/ct36x_ts/generic.h create mode 100644 drivers/input/touchscreen/ct36x_ts/platform.h create mode 100644 drivers/input/touchscreen/ct36x_ts/rockchip.c create mode 100644 drivers/input/touchscreen/ct36x_ts/rockchip.h create mode 100644 drivers/input/touchscreen/ct36x_ts/tscore.c create mode 100644 drivers/input/touchscreen/ct36x_ts/tscore.h create mode 100644 drivers/input/touchscreen/ft5506_app.f create mode 100644 drivers/input/touchscreen/ft5506_wgj.c create mode 100644 drivers/input/touchscreen/ft5506_wgj.h delete mode 100755 drivers/misc/3g_module/Kconfig delete mode 100755 drivers/misc/3g_module/Makefile delete mode 100755 drivers/misc/3g_module/mi700.c delete mode 100755 drivers/misc/3g_module/mt6229.c delete mode 100755 drivers/misc/3g_module/mu509.c delete mode 100644 drivers/misc/3g_module/mw100.c delete mode 100755 drivers/misc/3g_module/sc6610.c delete mode 100755 drivers/misc/3g_module/sew868.c mode change 100644 => 100755 drivers/misc/bp/chips/Kconfig mode change 100644 => 100755 drivers/misc/bp/chips/Makefile create mode 100644 drivers/misc/bp/chips/c66a.c create mode 100755 drivers/misc/bp/chips/m51.c create mode 100755 drivers/misc/bp/chips/mi700.c create mode 100644 drivers/misc/bp/chips/mtk6250.c create mode 100755 drivers/misc/bp/chips/mw100.c create mode 100755 drivers/misc/bp/chips/sc6610.c create mode 100644 drivers/power/smb347-charger.c create mode 100644 include/linux/power/smb347-charger.h diff --git a/arch/arm/configs/rk3066_z600t_phonepad_defconfig b/arch/arm/configs/rk3066_z600t_phonepad_defconfig new file mode 100644 index 000000000000..44e0945a2458 --- /dev/null +++ b/arch/arm/configs/rk3066_z600t_phonepad_defconfig @@ -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 diff --git a/arch/arm/mach-rk30/Kconfig b/arch/arm/mach-rk30/Kconfig index 1fb192c9464f..2e9a09bd1765 100755 --- a/arch/arm/mach-rk30/Kconfig +++ b/arch/arm/mach-rk30/Kconfig @@ -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 diff --git a/arch/arm/mach-rk30/Makefile b/arch/arm/mach-rk30/Makefile index 6c1dee74bc97..00296ee26a20 100755 --- a/arch/arm/mach-rk30/Makefile +++ b/arch/arm/mach-rk30/Makefile @@ -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 diff --git a/arch/arm/mach-rk30/board-rk30-phonepad-z600t.c b/arch/arm/mach-rk30/board-rk30-phonepad-z600t.c new file mode 100644 index 000000000000..e85ec2ecd6e6 --- /dev/null +++ b/arch/arm/mach-rk30/board-rk30-phonepad-z600t.c @@ -0,0 +1,2083 @@ +/* arch/arm/mach-rk30/board-rk30-sdk.c + * + * Copyright (C) 2012 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../../drivers/headset_observe/rk_headset.h" +#if defined(CONFIG_MFD_RK610) +#include +#endif + +#if defined(CONFIG_RK_HDMI) + #include "../../../drivers/video/rockchip/hdmi/rk_hdmi.h" +#endif + +#if defined(CONFIG_SPIM_RK29) +#include "../../../drivers/spi/rk29_spim.h" +#endif + +#if defined (CONFIG_BP_AUTO) +#include +#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 +#endif + +#if defined(CONFIG_DP501) //for display port transmitter dp501 +#include +#endif + +#include "board-rk30-sdk-camera.c" + +#include +static struct rk29_keys_button key_button[] = { + { + .desc = "vol-", + .code = KEY_VOLUMEDOWN, + .gpio = RK30_PIN4_PC5, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "play", + .code = KEY_POWER, + .gpio = RK30_PIN6_PA2, + .active_low = PRESS_LEV_LOW, + //.code_long_press = EV_ENCALL, + .wakeup = 1, + }, + { + .desc = "vol+", + .code = KEY_VOLUMEUP, + .adc_value = 1, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, +#ifndef RK3000_SDK + { + .desc = "menu", + .code = EV_MENU, + .adc_value = 135, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "home", + .code = KEY_HOME, + .adc_value = 550, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "esc", + .code = KEY_BACK, + .adc_value = 334, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "camera", + .code = KEY_CAMERA, + .adc_value = 743, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, +#else + { + .desc = "menu", + .code = EV_MENU, + .adc_value = 155, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "home", + .code = KEY_HOME, + .adc_value = 630, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "esc", + .code = KEY_BACK, + .adc_value = 386, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, + { + .desc = "camera", + .code = KEY_CAMERA, + .adc_value = 827, + .gpio = INVALID_GPIO, + .active_low = PRESS_LEV_LOW, + }, +#endif +}; + +struct rk29_keys_platform_data rk29_keys_pdata = { + .buttons = key_button, + .nbuttons = ARRAY_SIZE(key_button), + .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 +int goodix_init_platform_hw(void) +{ + int ret; + + rk30_mux_api_set(GPIO4D0_SMCDATA8_TRACEDATA8_NAME, GPIO4D_GPIO4D0); + rk30_mux_api_set(GPIO4C2_SMCDATA2_TRACEDATA2_NAME, GPIO4C_GPIO4C2); + printk("%s:0x%x,0x%x\n",__func__,rk30_mux_api_get(GPIO4D0_SMCDATA8_TRACEDATA8_NAME),rk30_mux_api_get(GPIO4C2_SMCDATA2_TRACEDATA2_NAME)); + + if (TOUCH_PWR_PIN != INVALID_GPIO) { + ret = gpio_request(TOUCH_PWR_PIN, "goodix power pin"); + if (ret != 0) { + gpio_free(TOUCH_PWR_PIN); + printk("goodix power error\n"); + return -EIO; + } + gpio_direction_output(TOUCH_PWR_PIN, 0); + gpio_set_value(TOUCH_PWR_PIN, GPIO_LOW); + msleep(100); + } + + if (TOUCH_RESET_PIN != INVALID_GPIO) { + ret = gpio_request(TOUCH_RESET_PIN, "goodix reset pin"); + if (ret != 0) { + gpio_free(TOUCH_RESET_PIN); + printk("goodix gpio_request error\n"); + return -EIO; + } + gpio_direction_output(TOUCH_RESET_PIN, 1); + msleep(100); + //gpio_set_value(TOUCH_RESET_PIN, GPIO_LOW); + //msleep(100); + //gpio_set_value(TOUCH_RESET_PIN, GPIO_HIGH); + //msleep(500); + } + return 0; +} + +struct goodix_platform_data goodix_info = { + .model = 8105, + .irq_pin = RK30_PIN4_PC2, + .rest_pin = TOUCH_RESET_PIN, + .init_platform_hw = goodix_init_platform_hw, +}; +#endif + +#if defined (CONFIG_TOUCHSCREEN_FT5506) +#define TOUCH_RESET_PIN RK30_PIN4_PD0 +#define TOUCH_INT_PIN RK30_PIN4_PC2 +int ft5506_init_platform_hw(void) +{ + printk("ft5506_init_platform_hw\n"); + if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){ + gpio_free(TOUCH_RESET_PIN); + printk("ft5506_init_platform_hw gpio_request error\n"); + return -EIO; + } + + if(gpio_request(TOUCH_INT_PIN,NULL) != 0){ + gpio_free(TOUCH_INT_PIN); + printk("ift5506_init_platform_hw gpio_request error\n"); + return -EIO; + } + + gpio_direction_output(TOUCH_RESET_PIN, 0); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + mdelay(10); + gpio_direction_input(TOUCH_INT_PIN); + mdelay(10); + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + msleep(300); + return 0; +} + +void ft5506_exit_platform_hw(void) +{ + printk("ft5506_exit_platform_hw\n"); + gpio_free(TOUCH_RESET_PIN); + gpio_free(TOUCH_INT_PIN); +} + + +int ft5506_platform_sleep(void) +{ + printk("ft5506_platform_sleep\n"); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + return 0; +} +int ft5506_platform_wakeup(void) +{ + printk("ft5506_platform_wakeup\n"); + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + msleep(300); + return 0; +} + +struct ft5506_platform_data ft5506_info = { + + .init_platform_hw= ft5506_init_platform_hw, + .exit_platform_hw= ft5506_exit_platform_hw, + .platform_sleep = ft5506_platform_sleep, + .platform_wakeup = ft5506_platform_wakeup, + +}; +#endif +static struct spi_board_info board_spi_devices[] = { +}; + +/*********************************************************** +* rk30 backlight +************************************************************/ +#ifdef CONFIG_BACKLIGHT_RK29_BL +#define PWM_ID 2 +#define PWM_MUX_NAME GPIO0D6_PWM2_NAME +#define PWM_MUX_MODE GPIO0D_PWM2 +#define PWM_MUX_MODE_GPIO GPIO0A_GPIO0A3 +#define PWM_GPIO RK30_PIN0_PD6 +#define PWM_EFFECT_VALUE 1 + +#define LCD_DISP_ON_PIN + +#ifdef LCD_DISP_ON_PIN +//#define BL_EN_MUX_NAME GPIOF34_UART3_SEL_NAME +//#define BL_EN_MUX_MODE IOMUXB_GPIO1_B34 + +#define BL_EN_PIN RK30_PIN6_PB3 +#define BL_EN_VALUE GPIO_HIGH +#endif +static int rk29_backlight_io_init(void) +{ + int ret = 0; + //rk30_mux_api_set(GPIO0D6_PWM2_NAME, GPIO0D_GPIO0D6); + //gpio_request(RK30_PIN0_PD6, NULL); + //gpio_direction_output(RK30_PIN0_PD6, GPIO_HIGH); + + msleep(50); + + rk30_mux_api_set(GPIO0D6_PWM2_NAME, GPIO0D_PWM2); + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); +#ifdef LCD_DISP_ON_PIN + // rk30_mux_api_set(BL_EN_MUX_NAME, BL_EN_MUX_MODE); + + ret = gpio_request(BL_EN_PIN, NULL); + if (ret != 0) { + gpio_free(BL_EN_PIN); + } + + gpio_direction_output(BL_EN_PIN, BL_EN_VALUE); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); +#endif + return ret; +} + +static int rk29_backlight_io_deinit(void) +{ + int ret = 0; + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + if (gpio_request(PWM_GPIO, NULL)) { + printk("func %s, line %d: request gpio fail\n", __FUNCTION__, __LINE__); + return -1; + } + gpio_direction_output(PWM_GPIO, GPIO_LOW); +#ifdef LCD_DISP_ON_PIN + gpio_direction_output(BL_EN_PIN, !BL_EN_VALUE); + gpio_set_value(BL_EN_PIN, !BL_EN_VALUE); + gpio_free(BL_EN_PIN); +#endif + return ret; +} + +static int rk29_backlight_pwm_suspend(void) +{ + int ret = 0; + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + if (gpio_request(PWM_GPIO, NULL)) { + printk("func %s, line %d: request gpio fail\n", __FUNCTION__, __LINE__); + return -1; + } + gpio_direction_output(PWM_GPIO, GPIO_LOW); +#ifdef LCD_DISP_ON_PIN + gpio_direction_output(BL_EN_PIN, 0); + gpio_set_value(BL_EN_PIN, !BL_EN_VALUE); +#endif + return ret; +} + +static int rk29_backlight_pwm_resume(void) +{ + gpio_free(PWM_GPIO); + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); +#ifdef LCD_DISP_ON_PIN + msleep(30); + gpio_direction_output(BL_EN_PIN, 1); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); +#endif + return 0; +} + +static struct rk29_bl_info rk29_bl_info = { + .pwm_id = PWM_ID, + .bl_ref = PWM_EFFECT_VALUE, + .io_init = rk29_backlight_io_init, + .io_deinit = rk29_backlight_io_deinit, + .pwm_suspend = rk29_backlight_pwm_suspend, + .pwm_resume = rk29_backlight_pwm_resume, + .pre_div = 20000, + .delay_ms = 50, + .min_brightness = 150, +}; + +static struct platform_device rk29_device_backlight = { + .name = "rk29_backlight", + .id = -1, + .dev = { + .platform_data = &rk29_bl_info, + } +}; + +#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 +#define RK30_MODEM_POWER_IOMUX rk29_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME, GPIO4D_GPIO4D1) + +static int rk30_modem_io_init(void) +{ + printk("%s\n", __FUNCTION__); + RK30_MODEM_POWER_IOMUX; + + return 0; +} + +static struct rk29_io_t rk30_modem_io = { + .io_addr = RK30_MODEM_POWER, + .enable = GPIO_HIGH, + .disable = GPIO_LOW, + .io_init = rk30_modem_io_init, +}; + +static struct platform_device rk30_device_modem = { + .name = "rk30_modem", + .id = -1, + .dev = { + .platform_data = &rk30_modem_io, + } +}; +#endif + + +/*MMA8452 gsensor*/ +#if defined (CONFIG_GS_MMA8452) +#define MMA8452_INT_PIN RK30_PIN4_PC0 + +static int mma8452_init_platform_hw(void) +{ + rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME, GPIO4C_GPIO4C0); + + return 0; +} + +static struct sensor_platform_data mma8452_info = { + .type = SENSOR_TYPE_ACCEL, + .irq_enable = 1, + .poll_delay_ms = 30, + .init_platform_hw = mma8452_init_platform_hw, + .orientation = {0, 1, 0, 0, 0, -1, 1, 0, 0}, +}; +#endif +#if defined (CONFIG_GS_LIS3DH) +#define LIS3DH_INT_PIN RK30_PIN4_PC0 + +static int lis3dh_init_platform_hw(void) +{ + rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME, GPIO4C_GPIO4C0); + + return 0; +} + +static struct sensor_platform_data lis3dh_info = { + .type = SENSOR_TYPE_ACCEL, + .irq_enable = 1, + .poll_delay_ms = 30, + .init_platform_hw = lis3dh_init_platform_hw, + .orientation = {-1, 0, 0, 0, 0, 1, 0, -1, 0}, +}; +#endif +#if defined (CONFIG_GS_KXTIK) +#define KXTIK_INT_PIN RK30_PIN4_PC0 + +static int kxtik_init_platform_hw(void) +{ + rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME, GPIO4C_GPIO4C0); + + return 0; +} + +static struct sensor_platform_data kxtik_info = { + .type = SENSOR_TYPE_ACCEL, + .irq_enable = 1, + .poll_delay_ms = 30, + .init_platform_hw = kxtik_init_platform_hw, + .orientation = {0, 1, 0, 0, 0, -1, 1, 0, 0}, +}; + +#endif +#if defined(CONFIG_CHARGER_SMB347) +struct smb347_info smb347_info = { + .chg_en_pin = RK30_PIN4_PD5, // charge enable pin (smb347's c4 pin) + .chg_ctl_pin = RK30_PIN0_PC6, // charge control pin (smb347's d2 pin) + .chg_stat_pin = RK30_PIN6_PA6, // charge stat pin (smb347's f5 pin) + .chg_susp_pin = RK30_PIN4_PD1, // charge usb suspend pin (smb347's d3 pin) + .max_current = 1800, // dc and hc input current limit can set 300/500/700/900/1200/1500/1800/2000/2200/2500(ma) + .otg_power_form_smb = 0, // if otg 5v power form smb347 set 1 otherwise set 0 +}; +#endif +#if defined (CONFIG_COMPASS_AK8975) +static struct sensor_platform_data akm8975_info = +{ + .type = SENSOR_TYPE_COMPASS, + .irq_enable = 1, + .poll_delay_ms = 30, + .m_layout = + { + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + } +}; + +#endif + +#if defined(CONFIG_GYRO_L3G4200D) + +#include +#define L3G4200D_INT_PIN RK30_PIN4_PC3 + +static int l3g4200d_init_platform_hw(void) +{ + rk30_mux_api_set(GPIO4C3_SMCDATA3_TRACEDATA3_NAME, GPIO4C_GPIO4C3); + + return 0; +} + +static struct sensor_platform_data l3g4200d_info = { + .type = SENSOR_TYPE_GYROSCOPE, + .irq_enable = 1, + .poll_delay_ms = 30, + .orientation = {0, 1, 0, -1, 0, 0, 0, 0, 1}, + .init_platform_hw = l3g4200d_init_platform_hw, + .x_min = 40,//x_min,y_min,z_min = (0-100) according to hardware + .y_min = 40, + .z_min = 20, +}; + +#endif + +#ifdef CONFIG_LS_CM3217 +static struct sensor_platform_data cm3217_info = { + .type = SENSOR_TYPE_LIGHT, + .irq_enable = 0, + .poll_delay_ms = 500, +}; + +#endif + +#ifdef CONFIG_LS_CM3231 +static struct sensor_platform_data cm3231_info = { + .type = SENSOR_TYPE_LIGHT, + .irq_enable = 0, + .poll_delay_ms = 500, +}; +#endif + +#if defined(CONFIG_PS_AL3006) +static struct sensor_platform_data proximity_al3006_info = { + .type = SENSOR_TYPE_PROXIMITY, + .irq_enable = 1, + .poll_delay_ms = 200, +}; +#endif + +#if defined(CONFIG_PS_STK3171) +static struct sensor_platform_data proximity_stk3171_info = { + .type = SENSOR_TYPE_PROXIMITY, + .irq_enable = 1, + .poll_delay_ms = 200, +}; +#endif + + +#if defined(CONFIG_LS_AL3006) +static struct sensor_platform_data light_al3006_info = { + .type = SENSOR_TYPE_LIGHT, + .irq_enable = 1, + .poll_delay_ms = 200, +}; +#endif + +#if defined(CONFIG_LS_STK3171) +static struct sensor_platform_data light_stk3171_info = { + .type = SENSOR_TYPE_LIGHT, + .irq_enable = 1, + .poll_delay_ms = 200, +}; +#endif +#ifdef CONFIG_FB_ROCKCHIP + +#define LCD_CS_MUX_NAME GPIO4C7_SMCDATA7_TRACEDATA7_NAME +#define LCD_CS_PIN RK30_PIN4_PC7 +#define LCD_CS_VALUE GPIO_HIGH + +#define LCD_STANDBY_MUX_NAME GPIO4D6_SMCDATA14_TRACEDATA14_NAME +#define LCD_STANDBY_PIN RK30_PIN4_PD6 +#define LCD_STANDBY_VALUE GPIO_HIGH + + +#define LCD_EN_MUX_NAME GPIO4C7_SMCDATA7_TRACEDATA7_NAME +#define LCD_EN_PIN RK30_PIN6_PB4 +#define LCD_EN_VALUE GPIO_LOW + +#define HDMI11_MUX_NAME GPIO3A6_SDMMC0RSTNOUT_NAME +#define HDMI11_EN_PIN RK30_PIN3_PA6 +#define HDMI11_EN_VALUE GPIO_HIGH + + +static int rk_fb_io_init(struct rk29_fb_setting_info *fb_setting) +{ + int ret = 0; + + rk30_mux_api_set(LCD_STANDBY_MUX_NAME, GPIO4D_GPIO4D6); + ret = gpio_request(LCD_STANDBY_PIN, NULL); + if (ret != 0) + { + gpio_free(LCD_STANDBY_PIN); + printk(KERN_ERR "request lcd cs pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(LCD_STANDBY_PIN, LCD_STANDBY_VALUE); + } + + rk30_mux_api_set(GPIO3A6_SDMMC0RSTNOUT_NAME, GPIO3A_GPIO3A6); + ret = gpio_request(HDMI11_EN_PIN, NULL); + if (ret != 0) + { + gpio_free(HDMI11_EN_PIN); + printk(KERN_ERR "hdmi gpio fail!\n"); + return -1; + } + else + { + gpio_direction_output(HDMI11_EN_PIN, HDMI11_EN_VALUE); + } + + rk30_mux_api_set(LCD_CS_MUX_NAME, GPIO4C_GPIO4C7); + ret = gpio_request(LCD_CS_PIN, NULL); + if (ret != 0) + { + gpio_free(LCD_CS_PIN); + printk(KERN_ERR "request lcd cs pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(LCD_CS_PIN, LCD_CS_VALUE); + } + ret = gpio_request(LCD_EN_PIN, NULL); + if (ret != 0) + { + gpio_free(LCD_EN_PIN); + printk(KERN_ERR "request lcd en pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(LCD_EN_PIN, LCD_EN_VALUE); + } + return 0; +} +static int rk_fb_io_disable(void) +{ + msleep(100); //Response Time (Rising + Falling) + gpio_set_value(HDMI11_EN_PIN, HDMI11_EN_VALUE? 0:1); + gpio_set_value(LCD_CS_PIN, LCD_CS_VALUE? 0:1); + gpio_set_value(LCD_STANDBY_PIN, LCD_CS_VALUE? 0:1); + gpio_set_value(LCD_EN_PIN, LCD_EN_VALUE? 0:1); + + return 0; +} +static int rk_fb_io_enable(void) +{ + gpio_set_value(LCD_EN_PIN, LCD_EN_VALUE); + gpio_set_value(LCD_CS_PIN, LCD_CS_VALUE); + gpio_set_value(LCD_STANDBY_PIN, LCD_CS_VALUE); + gpio_set_value(HDMI11_EN_PIN, HDMI11_EN_VALUE); + msleep(150); //wait for power stable + + return 0; +} + +#if defined(CONFIG_LCDC0_RK30) +struct rk29fb_info lcdc0_screen_info = { + .prop = PRMRY, //primary display device + .io_init = rk_fb_io_init, + .io_disable = rk_fb_io_disable, + .io_enable = rk_fb_io_enable, + .set_screen_info = set_lcd_info, +}; +#endif + +#if defined(CONFIG_LCDC1_RK30) +struct rk29fb_info lcdc1_screen_info = { + #if defined(CONFIG_RK_HDMI) + .prop = EXTEND, //extend display device + .lcd_info = NULL, + .set_screen_info = hdmi_init_lcdc, + #endif +}; +#endif + +static struct resource resource_fb[] = { + [0] = { + .name = "fb0 buf", + .start = 0, + .end = 0,//RK30_FB0_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "ipp buf", //for rotate + .start = 0, + .end = 0,//RK30_FB0_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "fb2 buf", + .start = 0, + .end = 0,//RK30_FB0_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device device_fb = { + .name = "rk-fb", + .id = -1, + .num_resources = ARRAY_SIZE(resource_fb), + .resource = resource_fb, +}; +#endif + +#if defined(CONFIG_LCDC0_RK30) +static struct resource resource_lcdc0[] = { + [0] = { + .name = "lcdc0 reg", + .start = RK30_LCDC0_PHYS, + .end = RK30_LCDC0_PHYS + RK30_LCDC0_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .name = "lcdc0 irq", + .start = IRQ_LCDC0, + .end = IRQ_LCDC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device device_lcdc0 = { + .name = "rk30-lcdc", + .id = 0, + .num_resources = ARRAY_SIZE(resource_lcdc0), + .resource = resource_lcdc0, + .dev = { + .platform_data = &lcdc0_screen_info, + }, +}; +#endif +#if defined(CONFIG_LCDC1_RK30) +extern struct rk29fb_info lcdc1_screen_info; +static struct resource resource_lcdc1[] = { + [0] = { + .name = "lcdc1 reg", + .start = RK30_LCDC1_PHYS, + .end = RK30_LCDC1_PHYS + RK30_LCDC1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "lcdc1 irq", + .start = IRQ_LCDC1, + .end = IRQ_LCDC1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device device_lcdc1 = { + .name = "rk30-lcdc", + .id = 1, + .num_resources = ARRAY_SIZE(resource_lcdc1), + .resource = resource_lcdc1, + .dev = { + .platform_data = &lcdc1_screen_info, + }, +}; +#endif + +#if defined(CONFIG_DP501) + #define DVDD33_EN_PIN RK30_PIN6_PB4 + #define DVDD33_EN_VALUE GPIO_LOW + + #define DVDD12_EN_PIN RK30_PIN4_PC7 + #define DVDD12_EN_VALUE GPIO_HIGH + + #define EDP_RST_PIN RK30_PIN2_PC4 + static int rk_edp_power_ctl(void) + { + int ret; + ret = gpio_request(DVDD33_EN_PIN, "dvdd33_en_pin"); + if (ret != 0) + { + gpio_free(DVDD33_EN_PIN); + printk(KERN_ERR "request dvdd33 en pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(DVDD33_EN_PIN, DVDD33_EN_VALUE); + } + + ret = gpio_request(DVDD12_EN_PIN, "dvdd18_en_pin"); + if (ret != 0) + { + gpio_free(DVDD12_EN_PIN); + printk(KERN_ERR "request dvdd18 en pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(DVDD12_EN_PIN, DVDD12_EN_VALUE); + } + + ret = gpio_request(EDP_RST_PIN, "edp_rst_pin"); + if (ret != 0) + { + gpio_free(EDP_RST_PIN); + printk(KERN_ERR "request rst pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(EDP_RST_PIN, GPIO_LOW); + msleep(10); + gpio_direction_output(EDP_RST_PIN, GPIO_HIGH); + } + return 0; + + } + static struct dp501_platform_data dp501_platform_data = { + .power_ctl = rk_edp_power_ctl, + .dvdd33_en_pin = DVDD33_EN_PIN, + .dvdd33_en_val = DVDD33_EN_VALUE, + .dvdd18_en_pin = DVDD12_EN_PIN, + .dvdd18_en_val = DVDD12_EN_VALUE, + .edp_rst_pin = EDP_RST_PIN, + }; +#endif + +#if defined(CONFIG_MFD_RK610) +#define RK610_RST_PIN_MUX_NAME GPIO0C6_TRACECLK_SMCADDR2_NAME +#define RK610_RST_PIN_MUX_MODE GPIO0C_GPIO0C6 +#define RK610_RST_PIN RK30_PIN0_PC6 +static int rk610_power_on_init(void) +{ + int ret; + if(RK610_RST_PIN != INVALID_GPIO) + { + rk30_mux_api_set(RK610_RST_PIN_MUX_NAME,RK610_RST_PIN_MUX_MODE); + ret = gpio_request(RK610_RST_PIN, "rk610 reset"); + if (ret) + { + printk(KERN_ERR "rk610_control_probe request gpio fail\n"); + } + else + { + gpio_direction_output(RK610_RST_PIN, GPIO_HIGH); + msleep(100); + gpio_direction_output(RK610_RST_PIN, GPIO_LOW); + msleep(100); + gpio_set_value(RK610_RST_PIN, GPIO_HIGH); + } + } + + return 0; + +} + + +static struct rk610_ctl_platform_data rk610_ctl_pdata = { + .rk610_power_on_init = rk610_power_on_init, +}; +#endif +#ifdef CONFIG_SND_SOC_RK610 +static int rk610_codec_io_init(void) +{ +//if need iomux. +//Must not gpio_request + return 0; +} + +static struct rk610_codec_platform_data rk610_codec_pdata = { + .spk_ctl_io = RK30_PIN4_PC6, + .io_init = rk610_codec_io_init, +}; +#endif +#ifdef CONFIG_ANDROID_TIMED_GPIO +static struct timed_gpio timed_gpios[] = { + { + .name = "vibrator", + .gpio = RK30_PIN0_PA4, + .max_timeout = 1000, + .active_low = 0, + .adjust_time =20, //adjust for diff product + }, +}; + +static struct timed_gpio_platform_data rk29_vibrator_info = { + .num_gpios = 1, + .gpios = timed_gpios, +}; + +static struct platform_device rk29_device_vibrator = { + .name = "timed-gpio", + .id = -1, + .dev = { + .platform_data = &rk29_vibrator_info, + }, + +}; +#endif + +#ifdef CONFIG_LEDS_GPIO_PLATFORM +static struct gpio_led rk29_leds[] = { + { + .name = "button-backlight", + .gpio = RK30_PIN4_PD7, + .default_trigger = "timer", + .active_low = 0, + .retain_state_suspended = 0, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, +}; + +static struct gpio_led_platform_data rk29_leds_pdata = { + .leds = rk29_leds, + .num_leds = ARRAY_SIZE(rk29_leds), +}; + +static struct platform_device rk29_device_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &rk29_leds_pdata, + }, +}; +#endif + +#ifdef CONFIG_RK_IRDA +#define IRDA_IRQ_PIN RK30_PIN6_PA1 + +static int irda_iomux_init(void) +{ + int ret = 0; + + //irda irq pin + ret = gpio_request(IRDA_IRQ_PIN, NULL); + if (ret != 0) { + gpio_free(IRDA_IRQ_PIN); + printk(">>>>>> IRDA_IRQ_PIN gpio_request err \n "); + } + gpio_pull_updown(IRDA_IRQ_PIN, PullDisable); + gpio_direction_input(IRDA_IRQ_PIN); + + return 0; +} + +static int irda_iomux_deinit(void) +{ + gpio_free(IRDA_IRQ_PIN); + return 0; +} + +static struct irda_info rk29_irda_info = { + .intr_pin = IRDA_IRQ_PIN, + .iomux_init = irda_iomux_init, + .iomux_deinit = irda_iomux_deinit, + //.irda_pwr_ctl = bu92747guw_power_ctl, +}; + +static struct platform_device irda_device = { +#ifdef CONFIG_RK_IRDA_NET + .name = "rk_irda", +#else + .name = "bu92747_irda", +#endif + .id = -1, + .dev = { + .platform_data = &rk29_irda_info, + } +}; +#endif + +#ifdef CONFIG_ION +#define ION_RESERVE_SIZE (80 * SZ_1M) +static struct ion_platform_data rk30_ion_pdata = { + .nr = 1, + .heaps = { + { + .type = ION_HEAP_TYPE_CARVEOUT, + .id = ION_NOR_HEAP_ID, + .name = "norheap", + .size = ION_RESERVE_SIZE, + } + }, +}; + +static struct platform_device device_ion = { + .name = "ion-rockchip", + .id = 0, + .dev = { + .platform_data = &rk30_ion_pdata, + }, +}; +#endif + +/************************************************************************************************** + * SDMMC devices, include the module of SD,MMC,and SDIO.noted by xbw at 2012-03-05 +**************************************************************************************************/ +#ifdef CONFIG_SDMMC_RK29 +#include "board-rk30-sdk-sdmmc.c" +#endif + +#ifdef CONFIG_SDMMC0_RK29 +static int rk29_sdmmc0_cfg_gpio(void) +{ +#ifdef CONFIG_SDMMC_RK29_OLD + rk30_mux_api_set(GPIO3B1_SDMMC0CMD_NAME, GPIO3B_SDMMC0_CMD); + rk30_mux_api_set(GPIO3B0_SDMMC0CLKOUT_NAME, GPIO3B_SDMMC0_CLKOUT); + rk30_mux_api_set(GPIO3B2_SDMMC0DATA0_NAME, GPIO3B_SDMMC0_DATA0); + rk30_mux_api_set(GPIO3B3_SDMMC0DATA1_NAME, GPIO3B_SDMMC0_DATA1); + rk30_mux_api_set(GPIO3B4_SDMMC0DATA2_NAME, GPIO3B_SDMMC0_DATA2); + rk30_mux_api_set(GPIO3B5_SDMMC0DATA3_NAME, GPIO3B_SDMMC0_DATA3); + + rk30_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME, GPIO3B_GPIO3B6); + + rk30_mux_api_set(GPIO3A7_SDMMC0PWREN_NAME, GPIO3A_GPIO3A7); + gpio_request(RK30_PIN3_PA7, "sdmmc-power"); + gpio_direction_output(RK30_PIN3_PA7, GPIO_LOW); + +#else + rk29_sdmmc_set_iomux(0, 0xFFFF); + + #if defined(CONFIG_SDMMC0_RK29_SDCARD_DET_FROM_GPIO) + rk30_mux_api_set(RK29SDK_SD_CARD_DETECT_PIN_NAME, RK29SDK_SD_CARD_DETECT_IOMUX_FGPIO); + #else + rk30_mux_api_set(RK29SDK_SD_CARD_DETECT_PIN_NAME, RK29SDK_SD_CARD_DETECT_IOMUX_FMUX); + #endif + + #if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) + gpio_request(SDMMC0_WRITE_PROTECT_PIN, "sdmmc-wp"); + gpio_direction_input(SDMMC0_WRITE_PROTECT_PIN); + #endif + +#endif + + return 0; +} + +#define CONFIG_SDMMC0_USE_DMA +struct rk29_sdmmc_platform_data default_sdmmc0_data = { + .host_ocr_avail = + (MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 | + MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | + MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36), + .host_caps = + (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), + .io_init = rk29_sdmmc0_cfg_gpio, + +#if !defined(CONFIG_SDMMC_RK29_OLD) + .set_iomux = rk29_sdmmc_set_iomux, +#endif + + .dma_name = "sd_mmc", +#ifdef CONFIG_SDMMC0_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif + +#if defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC) && defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) + .status = rk29sdk_wifi_mmc0_status, + .register_status_notify = rk29sdk_wifi_mmc0_status_register, +#endif + +#if defined(RK29SDK_SD_CARD_PWR_EN) || (INVALID_GPIO != RK29SDK_SD_CARD_PWR_EN) + .power_en = RK29SDK_SD_CARD_PWR_EN, + .power_en_level = RK29SDK_SD_CARD_PWR_EN_LEVEL, +#else + .power_en = INVALID_GPIO, + .power_en_level = GPIO_LOW, +#endif + .enable_sd_wakeup = 0, + +#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) + .write_prt = SDMMC0_WRITE_PROTECT_PIN, + .write_prt_enalbe_level = SDMMC0_WRITE_PROTECT_ENABLE_VALUE; +#else + .write_prt = INVALID_GPIO, +#endif + + .det_pin_info = { + #if defined(RK29SDK_SD_CARD_DETECT_N) || (INVALID_GPIO != RK29SDK_SD_CARD_DETECT_N) + .io = RK29SDK_SD_CARD_DETECT_N, //INVALID_GPIO, + .enable = RK29SDK_SD_CARD_INSERT_LEVEL, + #ifdef RK29SDK_SD_CARD_DETECT_PIN_NAME + .iomux = { + .name = RK29SDK_SD_CARD_DETECT_PIN_NAME, + #ifdef RK29SDK_SD_CARD_DETECT_IOMUX_FGPIO + .fgpio = RK29SDK_SD_CARD_DETECT_IOMUX_FGPIO, + #endif + #ifdef RK29SDK_SD_CARD_DETECT_IOMUX_FMUX + .fmux = RK29SDK_SD_CARD_DETECT_IOMUX_FMUX, + #endif + }, + #endif + #else + .io = INVALID_GPIO, + .enable = GPIO_LOW, + #endif + }, + +}; +#endif // CONFIG_SDMMC0_RK29 + +#ifdef CONFIG_SDMMC1_RK29 +#define CONFIG_SDMMC1_USE_DMA +static int rk29_sdmmc1_cfg_gpio(void) +{ +#if defined(CONFIG_SDMMC_RK29_OLD) + rk30_mux_api_set(GPIO3C0_SMMC1CMD_NAME, GPIO3C_SMMC1_CMD); + rk30_mux_api_set(GPIO3C5_SDMMC1CLKOUT_NAME, GPIO3C_SDMMC1_CLKOUT); + rk30_mux_api_set(GPIO3C1_SDMMC1DATA0_NAME, GPIO3C_SDMMC1_DATA0); + rk30_mux_api_set(GPIO3C2_SDMMC1DATA1_NAME, GPIO3C_SDMMC1_DATA1); + rk30_mux_api_set(GPIO3C3_SDMMC1DATA2_NAME, GPIO3C_SDMMC1_DATA2); + rk30_mux_api_set(GPIO3C4_SDMMC1DATA3_NAME, GPIO3C_SDMMC1_DATA3); +#else + +#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT) + gpio_request(SDMMC1_WRITE_PROTECT_PIN, "sdio-wp"); + gpio_direction_input(SDMMC1_WRITE_PROTECT_PIN); +#endif + +#endif + + return 0; +} + +struct rk29_sdmmc_platform_data default_sdmmc1_data = { + .host_ocr_avail = + (MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 | + MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | + MMC_VDD_33_34), + +#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD) + .host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +#else + .host_caps = + (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +#endif + + .io_init = rk29_sdmmc1_cfg_gpio, + +#if !defined(CONFIG_SDMMC_RK29_OLD) + .set_iomux = rk29_sdmmc_set_iomux, +#endif + + .dma_name = "sdio", +#ifdef CONFIG_SDMMC1_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif + +#if defined(CONFIG_WIFI_CONTROL_FUNC) || defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC) + .status = rk29sdk_wifi_status, + .register_status_notify = rk29sdk_wifi_status_register, +#endif + + #if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT) + .write_prt = SDMMC1_WRITE_PROTECT_PIN, + .write_prt_enalbe_level = SDMMC1_WRITE_PROTECT_ENABLE_VALUE; + #else + .write_prt = INVALID_GPIO, + #endif + + #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO) + .sdio_INT_gpio = RK29SDK_WIFI_SDIO_CARD_INT, + #endif + + .det_pin_info = { +#if defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD) + #if defined(RK29SDK_SD_CARD_DETECT_N) || (INVALID_GPIO != RK29SDK_SD_CARD_DETECT_N) + .io = RK29SDK_SD_CARD_DETECT_N, + #else + .io = INVALID_GPIO, + #endif + + .enable = RK29SDK_SD_CARD_INSERT_LEVEL, + #ifdef RK29SDK_SD_CARD_DETECT_PIN_NAME + .iomux = { + .name = RK29SDK_SD_CARD_DETECT_PIN_NAME, + #ifdef RK29SDK_SD_CARD_DETECT_IOMUX_FGPIO + .fgpio = RK29SDK_SD_CARD_DETECT_IOMUX_FGPIO, + #endif + #ifdef RK29SDK_SD_CARD_DETECT_IOMUX_FMUX + .fmux = RK29SDK_SD_CARD_DETECT_IOMUX_FMUX, + #endif + }, + #endif + #else + .io = INVALID_GPIO, + .enable = GPIO_LOW, +#endif + }, + + .enable_sd_wakeup = 0, +}; +#endif //endif--#ifdef CONFIG_SDMMC1_RK29 + +/************************************************************************************************** + * the end of setting for SDMMC devices +**************************************************************************************************/ + + +#ifdef CONFIG_BATTERY_RK30_ADC_FAC +static struct rk30_adc_battery_platform_data rk30_adc_battery_platdata = { + .dc_det_pin = RK30_PIN6_PA5,//INVALID_GPIO, + .batt_low_pin = RK30_PIN6_PA0, + .charge_set_pin = INVALID_GPIO, + .charge_ok_pin = INVALID_GPIO, + .dc_det_level = GPIO_LOW, + .charge_ok_level = GPIO_HIGH, + .usb_det_pin = RK30_PIN6_PA3, + .usb_det_level = GPIO_LOW, + + .charging_sleep = 0 , + .save_capacity = 1 , + .adc_channel =0 , + .spport_usb_charging = 1, +}; + +static struct platform_device rk30_device_adc_battery = { + .name = "rk30-battery", + .id = -1, + .dev = { + .platform_data = &rk30_adc_battery_platdata, + }, +}; +#endif + +#if defined(CONFIG_BATTERY_RK30_ADC) +static struct rk30_adc_battery_platform_data rk30_adc_battery_platdata = { + .dc_det_pin = RK30_PIN6_PA5, + .batt_low_pin = RK30_PIN6_PA0, + .charge_set_pin = INVALID_GPIO, + .charge_ok_pin = RK30_PIN6_PA6, + .dc_det_level = GPIO_LOW, + .charge_ok_level = GPIO_HIGH, +}; + +static struct platform_device rk30_device_adc_battery = { + .name = "rk30-battery", + .id = -1, + .dev = { + .platform_data = &rk30_adc_battery_platdata, + }, +}; +#endif + +#ifdef CONFIG_RK30_PWM_REGULATOR +const static int pwm_voltage_map[] = { + 950000,975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000 +}; + +static struct regulator_consumer_supply pwm_dcdc1_consumers[] = { + { + .supply = "vdd_core", + } +}; + +struct regulator_init_data pwm_regulator_init_dcdc[1] = +{ + { + .constraints = { + .name = "PWM_DCDC1", + .min_uV = 600000, + .max_uV = 1800000, //0.6-1.8V + .apply_uV = true, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(pwm_dcdc1_consumers), + .consumer_supplies = pwm_dcdc1_consumers, + }, +}; + +static struct pwm_platform_data pwm_regulator_info[1] = { + { + .pwm_id = 3, + .pwm_gpio = RK30_PIN0_PD7, + .pwm_iomux_name = GPIO0D7_PWM3_NAME, + .pwm_iomux_pwm = GPIO0D_PWM3, + .pwm_iomux_gpio = GPIO0D_GPIO0D6, + .pwm_voltage = 1100000, + .suspend_voltage = 1050000, + .min_uV = 950000, + .max_uV = 1400000, + .coefficient = 455, //45.5% + .pwm_voltage_map = pwm_voltage_map, + .init_data = &pwm_regulator_init_dcdc[0], + }, +}; + +struct platform_device pwm_regulator_device[1] = { + { + .name = "pwm-voltage-regulator", + .id = 0, + .dev = { + .platform_data = &pwm_regulator_info[0], + } + }, +}; +#endif + +#ifdef CONFIG_RK29_VMAC +#define PHY_PWR_EN_GPIO RK30_PIN1_PD6 +#include "board-rk30-sdk-vmac.c" +#endif + +#ifdef CONFIG_RFKILL_RK +// bluetooth rfkill device, its driver in net/rfkill/rfkill-rk.c +static struct rfkill_rk_platform_data rfkill_rk_platdata = { + .type = RFKILL_TYPE_BLUETOOTH, + + .poweron_gpio = { // BT_REG_ON + .io = RK30_PIN3_PC7, + .enable = GPIO_HIGH, + .iomux = { + .name = GPIO3C7_SDMMC1WRITEPRT_NAME, + .fgpio = GPIO3C_GPIO3C7, + }, + }, + + .reset_gpio = { // BT_RST + .io = RK30_PIN3_PD1, // set io to INVALID_GPIO for disable it + .enable = GPIO_LOW, + .iomux = { + .name = GPIO3D1_SDMMC1BACKENDPWR_NAME, + .fgpio = GPIO3D_GPIO3D1, + }, + }, + + .wake_gpio = { // BT_WAKE, use to control bt's sleep and wakeup + .io = RK30_PIN3_PC6, // set io to INVALID_GPIO for disable it + .enable = GPIO_HIGH, + .iomux = { + .name = GPIO3C6_SDMMC1DETECTN_NAME, + .fgpio = GPIO3C_GPIO3C6, + }, + }, + + .wake_host_irq = { // BT_HOST_WAKE, for bt wakeup host when it is in deep sleep + .gpio = { + .io = RK30_PIN6_PA7, // set io to INVALID_GPIO for disable it + .enable = GPIO_LOW, // set GPIO_LOW for falling, set 0 for rising + .iomux = { + .name = NULL, + }, + }, + }, + + .rts_gpio = { // UART_RTS, enable or disable BT's data coming + .io = RK30_PIN1_PA3, // set io to INVALID_GPIO for disable it + .enable = GPIO_LOW, + .iomux = { + .name = GPIO1A3_UART0RTSN_NAME, + .fgpio = GPIO1A_GPIO1A3, + .fmux = GPIO1A_UART0_RTS_N, + }, + }, +}; + +static struct platform_device device_rfkill_rk = { + .name = "rfkill_rk", + .id = -1, + .dev = { + .platform_data = &rfkill_rk_platdata, + }, +}; +#endif + +#if defined(CONFIG_MT5931_MT6622) +static struct mt6622_platform_data mt6622_platdata = { + .power_gpio = { // BT_REG_ON + .io = RK30_PIN3_PC7, // set io to INVALID_GPIO for disable it + .enable = GPIO_HIGH, + .iomux = { + .name = NULL, + }, + }, + + .reset_gpio = { // BT_RST + .io = RK30_PIN3_PD1, + .enable = GPIO_LOW, + .iomux = { + .name = NULL, + }, + }, + + .irq_gpio = { + .io = RK30_PIN6_PA7, + .enable = GPIO_HIGH, + .iomux = { + .name = NULL, + }, + } +}; + +static struct platform_device device_mt6622 = { + .name = "mt6622", + .id = -1, + .dev = { + .platform_data = &mt6622_platdata, + }, +}; +#endif + +static struct platform_device *devices[] __initdata = { +#ifdef CONFIG_ION + &device_ion, +#endif +#ifdef CONFIG_ANDROID_TIMED_GPIO + &rk29_device_vibrator, +#endif +#ifdef CONFIG_LEDS_GPIO_PLATFORM + &rk29_device_gpio_leds, +#endif +#ifdef CONFIG_RK_IRDA + &irda_device, +#endif +#if defined(CONFIG_WIFI_CONTROL_FUNC)||defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC) + &rk29sdk_wifi_device, +#endif + +#if defined(CONFIG_MT6620) + &mt3326_device_gps, +#endif + +#ifdef CONFIG_RK29_SUPPORT_MODEM + &rk30_device_modem, +#endif +#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 +#ifdef CONFIG_RFKILL_RK + &device_rfkill_rk, +#endif +#ifdef CONFIG_MT5931_MT6622 + &device_mt6622, +#endif +#if defined(CONFIG_BP_AUTO) + &device_bp_auto, +#endif +}; + + +static int rk_platform_add_display_devices(void) +{ + struct platform_device *fb = NULL; //fb + struct platform_device *lcdc0 = NULL; //lcdc0 + struct platform_device *lcdc1 = NULL; //lcdc1 + struct platform_device *bl = NULL; //backlight +#ifdef CONFIG_FB_ROCKCHIP + fb = &device_fb; +#endif + +#if defined(CONFIG_LCDC0_RK30) + lcdc0 = &device_lcdc0, +#endif + +#if defined(CONFIG_LCDC1_RK30) + lcdc1 = &device_lcdc1, +#endif + +#ifdef CONFIG_BACKLIGHT_RK29_BL + bl = &rk29_device_backlight, +#endif + __rk_platform_add_display_devices(fb,lcdc0,lcdc1,bl); + + return 0; + +} +// i2c +#ifdef CONFIG_I2C0_RK30 +static struct i2c_board_info __initdata i2c0_info[] = { +#if defined (CONFIG_GS_MMA8452) + { + .type = "gs_mma8452", + .addr = 0x1d, + .flags = 0, + .irq = MMA8452_INT_PIN, + .platform_data = &mma8452_info, + }, +#endif +#if defined (CONFIG_GS_LIS3DH) + { + .type = "gs_lis3dh", + .addr = 0x19, //0x19(SA0-->VCC), 0x18(SA0-->GND) + .flags = 0, + .irq = LIS3DH_INT_PIN, + .platform_data = &lis3dh_info, + }, +#endif +#if defined (CONFIG_GS_KXTIK) + { + .type = "gs_kxtik", + .addr = 0x0F, + .flags = 0, + .irq = KXTIK_INT_PIN, + .platform_data = &kxtik_info, + }, +#endif +#if defined (CONFIG_COMPASS_AK8975) + { + .type = "ak8975", + .addr = 0x0d, + .flags = 0, + .irq = RK30_PIN4_PC1, + .platform_data = &akm8975_info, + }, +#endif +#if defined (CONFIG_GYRO_L3G4200D) + { + .type = "l3g4200d_gryo", + .addr = 0x69, + .flags = 0, + .irq = L3G4200D_INT_PIN, + .platform_data = &l3g4200d_info, + }, +#endif +#if defined (CONFIG_LS_AL3006) + { + .type = "light_al3006", + .addr = 0x1c, //sel = 0; if sel =1, then addr = 0x1D + .flags = 0, + .irq = RK30_PIN6_PA2, + .platform_data = &light_al3006_info, + }, +#endif +#if defined (CONFIG_LS_STK3171) + { + .type = "ls_stk3171", + .addr = 0x48, + .flags = 0, + .irq = RK30_PIN6_PA2, + .platform_data = &light_stk3171_info, + }, +#endif + + +#if defined (CONFIG_PS_AL3006) + { + .type = "proximity_al3006", + .addr = 0x1c, //sel = 0; if sel =1, then addr = 0x1D + .flags = 0, + .irq = RK30_PIN6_PA2, + .platform_data = &proximity_al3006_info, + }, +#endif + +#if defined (CONFIG_PS_STK3171) + { + .type = "ps_stk3171", + .addr = 0x48, + .flags = 0, + .irq = RK30_PIN6_PA2, + .platform_data = &proximity_stk3171_info, + }, +#endif +#if defined (CONFIG_SND_SOC_RK1000) + { + .type = "rk1000_i2c_codec", + .addr = 0x60, + .flags = 0, + }, + { + .type = "rk1000_control", + .addr = 0x40, + .flags = 0, + }, +#endif +#if defined (CONFIG_SND_SOC_RT5631) + { + .type = "rt5631", + .addr = 0x1a, + .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 + { + .type = "rk610_ctl", + .addr = 0x40, + .flags = 0, + .platform_data = &rk610_ctl_pdata, + }, +#ifdef CONFIG_RK610_TVOUT + { + .type = "rk610_tvout", + .addr = 0x42, + .flags = 0, + }, +#endif +#ifdef CONFIG_HDMI_RK610 + { + .type = "rk610_hdmi", + .addr = 0x46, + .flags = 0, + .irq = INVALID_GPIO, + }, +#endif +#ifdef CONFIG_SND_SOC_RK610 + {//RK610_CODEC addr from 0x60 to 0x80 (0x60~0x80) + .type = "rk610_i2c_codec", + .addr = 0x60, + .flags = 0, + .platform_data = &rk610_codec_pdata, + }, +#endif +#endif + +}; +#endif +int __sramdata g_pmic_type = 0; +#ifdef CONFIG_I2C1_RK30 +#ifdef CONFIG_MFD_WM831X_I2C +#include "board-rk30-sdk-wm8326.c" +#endif +#ifdef CONFIG_MFD_TPS65910 +#define TPS65910_HOST_IRQ RK30_PIN6_PA4 +#include "board-rk30-sdk-tps65910.c" +#endif + +static struct i2c_board_info __initdata i2c1_info[] = { +#if defined (CONFIG_MFD_WM831X_I2C) + { + .type = "wm8326", + .addr = 0x34, + .flags = 0, + .irq = RK30_PIN6_PA4, + .platform_data = &wm831x_platdata, + }, +#endif +#if defined (CONFIG_CHARGER_SMB347) + { + .type = "smb347", + .addr = 0x06, + .flags = 0, + .platform_data = &smb347_info, + }, +#endif +#if defined (CONFIG_MFD_TPS65910) + { + .type = "tps65910", + .addr = TPS65910_I2C_ID0, + .flags = 0, + .irq = TPS65910_HOST_IRQ, + .platform_data = &tps65910_data, + }, +#endif +}; +#endif + +void __sramfunc board_pmu_suspend(void) +{ + #if defined (CONFIG_MFD_WM831X_I2C) + if(pmic_is_wm8326()) + board_pmu_wm8326_suspend(); + #endif + #if defined (CONFIG_MFD_TPS65910) + if(pmic_is_tps65910()) + board_pmu_tps65910_suspend(); + #endif +} + +void __sramfunc board_pmu_resume(void) +{ + #if defined (CONFIG_MFD_WM831X_I2C) + if(pmic_is_wm8326()) + board_pmu_wm8326_resume(); + #endif + #if defined (CONFIG_MFD_TPS65910) + if(pmic_is_tps65910()) + board_pmu_tps65910_resume(); + #endif +} + +#ifdef CONFIG_I2C2_RK30 +static struct i2c_board_info __initdata i2c2_info[] = { +#if defined (CONFIG_TOUCHSCREEN_GT8XX) + { + .type = "Goodix-TS", + .addr = 0x55, + .flags = 0, + .irq = RK30_PIN4_PC2, + .platform_data = &goodix_info, + }, +#endif +#if defined (CONFIG_LS_CM3217) + { + .type = "light_cm3217", + .addr = 0x10, + .flags = 0, + .platform_data = &cm3217_info, + }, +#endif +#if defined (CONFIG_LS_CM3231) + { + .type = "cm3217", + .addr = 0x10, + .flags = 0, + .platform_data = &cm3231_info, + }, +#endif + +#if defined(CONFIG_DP501) + { + .type = "dp501", + .addr = 0x30, + .flags = 0, + .platform_data = &dp501_platform_data, + }, +#endif +#if defined (CONFIG_TOUCHSCREEN_FT5506) +{ + .type = "laibao_touch", + .addr = 0x38, + .flags = 0, + .irq = RK30_PIN4_PC2, + .platform_data = &ft5506_info, +}, +#endif +}; +#endif + +#ifdef CONFIG_I2C3_RK30 +static struct i2c_board_info __initdata i2c3_info[] = { +}; +#endif + +#ifdef CONFIG_I2C4_RK30 +static struct i2c_board_info __initdata i2c4_info[] = { +}; +#endif + +#ifdef CONFIG_I2C_GPIO_RK30 +#define I2C_SDA_PIN INVALID_GPIO// RK30_PIN2_PD6 //set sda_pin here +#define I2C_SCL_PIN INVALID_GPIO//RK30_PIN2_PD7 //set scl_pin here +static int rk30_i2c_io_init(void) +{ + //set iomux (gpio) here + //rk30_mux_api_set(GPIO2D7_I2C1SCL_NAME, GPIO2D_GPIO2D7); + //rk30_mux_api_set(GPIO2D6_I2C1SDA_NAME, GPIO2D_GPIO2D6); + + return 0; +} +struct i2c_gpio_platform_data default_i2c_gpio_data = { + .sda_pin = I2C_SDA_PIN, + .scl_pin = I2C_SCL_PIN, + .udelay = 5, // clk = 500/udelay = 100Khz + .timeout = 100,//msecs_to_jiffies(100), + .bus_num = 5, + .io_init = rk30_i2c_io_init, +}; +static struct i2c_board_info __initdata i2c_gpio_info[] = { +}; +#endif + +static void __init rk30_i2c_register_board_info(void) +{ +#ifdef CONFIG_I2C0_RK30 + i2c_register_board_info(0, i2c0_info, ARRAY_SIZE(i2c0_info)); +#endif +#ifdef CONFIG_I2C1_RK30 + i2c_register_board_info(1, i2c1_info, ARRAY_SIZE(i2c1_info)); +#endif +#ifdef CONFIG_I2C2_RK30 + i2c_register_board_info(2, i2c2_info, ARRAY_SIZE(i2c2_info)); +#endif +#ifdef CONFIG_I2C3_RK30 + i2c_register_board_info(3, i2c3_info, ARRAY_SIZE(i2c3_info)); +#endif +#ifdef CONFIG_I2C4_RK30 + i2c_register_board_info(4, i2c4_info, ARRAY_SIZE(i2c4_info)); +#endif +#ifdef CONFIG_I2C_GPIO_RK30 + i2c_register_board_info(5, i2c_gpio_info, ARRAY_SIZE(i2c_gpio_info)); +#endif +} +//end of i2c + +#define POWER_ON_PIN RK30_PIN6_PB0 //power_hold +static void rk30_pm_power_off(void) +{ + printk(KERN_ERR "rk30_pm_power_off start...\n"); + gpio_direction_output(POWER_ON_PIN, GPIO_LOW); + #if defined(CONFIG_MFD_WM831X) + if(pmic_is_wm8326()) + { + wm831x_set_bits(Wm831x,WM831X_GPIO_LEVEL,0x0001,0x0000); //set sys_pwr 0 + wm831x_device_shutdown(Wm831x);//wm8326 shutdown + } + #endif + #if defined(CONFIG_MFD_TPS65910) + if(pmic_is_tps65910()) + { + tps65910_device_shutdown();//tps65910 shutdown + } + #endif + + while (1); +} + +static void __init machine_rk30_board_init(void) +{ + avs_init(); + gpio_request(POWER_ON_PIN, "poweronpin"); + gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); + + pm_power_off = rk30_pm_power_off; + + rk30_i2c_register_board_info(); + spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices)); + platform_add_devices(devices, ARRAY_SIZE(devices)); + rk_platform_add_display_devices(); + board_usb_detect_init(RK30_PIN6_PA3); + +#if defined(CONFIG_WIFI_CONTROL_FUNC) + rk29sdk_wifi_bt_gpio_control_init(); +#elif defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC) + rk29sdk_wifi_combo_module_gpio_init(); +#endif + +#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) +{ +#ifdef CONFIG_ION + rk30_ion_pdata.heaps[0].base = board_mem_reserve_add("ion", ION_RESERVE_SIZE); +#endif +#ifdef CONFIG_FB_ROCKCHIP + resource_fb[0].start = board_mem_reserve_add("fb0 buf", get_fb_size()); + resource_fb[0].end = resource_fb[0].start + get_fb_size()- 1; +#if 0 + resource_fb[1].start = board_mem_reserve_add("ipp buf", RK30_FB0_MEM_SIZE); + resource_fb[1].end = resource_fb[1].start + RK30_FB0_MEM_SIZE - 1; +#endif + +#if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER) + resource_fb[2].start = board_mem_reserve_add("fb2 buf",get_fb_size()); + resource_fb[2].end = resource_fb[2].start + get_fb_size() - 1; +#endif +#endif +#ifdef CONFIG_VIDEO_RK29 + rk30_camera_request_reserve_mem(); +#endif + board_mem_reserved(); +} + +/** + * dvfs_cpu_logic_table: table for arm and logic dvfs + * @frequency : arm frequency + * @cpu_volt : arm voltage depend on frequency + * @logic_volt : logic voltage arm requests depend on frequency + * comments : min arm/logic voltage + */ +static struct dvfs_arm_table dvfs_cpu_logic_table[] = { + {.frequency = 252 * 1000, .cpu_volt = 1075 * 1000, .logic_volt = 1125 * 1000},//0.975V/1.000V + {.frequency = 504 * 1000, .cpu_volt = 1100 * 1000, .logic_volt = 1125 * 1000},//0.975V/1.000V + {.frequency = 816 * 1000, .cpu_volt = 1125 * 1000, .logic_volt = 1150 * 1000},//1.000V/1.025V + {.frequency = 1008 * 1000, .cpu_volt = 1125 * 1000, .logic_volt = 1150 * 1000},//1.025V/1.050V + {.frequency = 1200 * 1000, .cpu_volt = 1175 * 1000, .logic_volt = 1200 * 1000},//1.100V/1.050V + {.frequency = 1272 * 1000, .cpu_volt = 1225 * 1000, .logic_volt = 1200 * 1000},//1.150V/1.100V + {.frequency = 1416 * 1000, .cpu_volt = 1300 * 1000, .logic_volt = 1200 * 1000},//1.225V/1.100V + {.frequency = 1512 * 1000, .cpu_volt = 1350 * 1000, .logic_volt = 1250 * 1000},//1.300V/1.150V + {.frequency = 1608 * 1000, .cpu_volt = 1425 * 1000, .logic_volt = 1300 * 1000},//1.325V/1.175V + {.frequency = CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table dvfs_gpu_table[] = { + {.frequency = 266 * 1000, .index = 1050 * 1000}, + {.frequency = 400 * 1000, .index = 1275 * 1000}, + {.frequency = CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table dvfs_ddr_table[] = { + {.frequency = 200 * 1000 + DDR_FREQ_SUSPEND, .index = 1050 * 1000}, + {.frequency = 300 * 1000 + DDR_FREQ_VIDEO, .index = 1050 * 1000}, + {.frequency = 400 * 1000 + DDR_FREQ_NORMAL, .index = 1125 * 1000}, + {.frequency = CPUFREQ_TABLE_END}, +}; + +#define DVFS_CPU_TABLE_SIZE (ARRAY_SIZE(dvfs_cpu_logic_table)) +static struct cpufreq_frequency_table cpu_dvfs_table[DVFS_CPU_TABLE_SIZE]; +static struct cpufreq_frequency_table dep_cpu2core_table[DVFS_CPU_TABLE_SIZE]; + +void __init board_clock_init(void) +{ + rk30_clock_data_init(periph_pll_default, codec_pll_default, RK30_CLOCKS_DEFAULT_FLAGS); + dvfs_set_arm_logic_volt(dvfs_cpu_logic_table, cpu_dvfs_table, dep_cpu2core_table); + dvfs_set_freq_volt_table(clk_get(NULL, "gpu"), dvfs_gpu_table); + dvfs_set_freq_volt_table(clk_get(NULL, "ddr"), dvfs_ddr_table); +} + +MACHINE_START(RK30, "RK30board") + .boot_params = PLAT_PHYS_OFFSET + 0x800, + .fixup = rk30_fixup, + .reserve = &rk30_reserve, + .map_io = rk30_map_io, + .init_irq = rk30_init_irq, + .timer = &rk30_timer, + .init_machine = machine_rk30_board_init, +MACHINE_END diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c index 4e220462ff47..367a118ca5e8 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -45,6 +45,7 @@ #include #include +#include "../../../drivers/headset_observe/rk_headset.h" #if defined(CONFIG_MFD_RK610) #include #endif @@ -56,22 +57,24 @@ #if defined(CONFIG_SPIM_RK29) #include "../../../drivers/spi/rk29_spim.h" #endif -#if defined(CONFIG_MU509) -#include -#endif -#if defined(CONFIG_MW100) -#include -#endif -#if defined(CONFIG_MT6229) -#include -#endif -#if defined(CONFIG_SEW868) -#include + +#if defined (CONFIG_BP_AUTO) +#include #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 #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,173 +354,124 @@ static struct platform_device rk29_device_backlight = { #endif -#ifdef CONFIG_RK29_SUPPORT_MODEM - -#define RK30_MODEM_POWER RK30_PIN4_PD1 -#define RK30_MODEM_POWER_IOMUX rk29_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME, GPIO4D_GPIO4D1) - -static int rk30_modem_io_init(void) -{ - printk("%s\n", __FUNCTION__); - RK30_MODEM_POWER_IOMUX; +#if defined (CONFIG_SND_SOC_RT3224) || defined (CONFIG_SND_SOC_RT3261) - return 0; -} +#define DIFFERENTIAL 1 +#define SINGLE_END 0 +#define TWO_SPK 2 +#define ONE_SPK 1 -static struct rk29_io_t rk30_modem_io = { - .io_addr = RK30_MODEM_POWER, - .enable = GPIO_HIGH, - .disable = GPIO_LOW, - .io_init = rk30_modem_io_init, +enum { + SPK_AMPLIFY_ZERO_POINT_FIVE_WATT=1, + SPK_AMPLIFY_ZERO_POINT_SIX_WATT, + SPK_AMPLIFY_ZERO_POINT_EIGHT_WATT, + SPK_AMPLIFY_ONE_WATT, }; -static struct platform_device rk30_device_modem = { - .name = "rk30_modem", - .id = -1, - .dev = { - .platform_data = &rk30_modem_io, - } +enum { + LR_NORMAL, + LR_SWAP, + LEFT_COPY_TO_RIGHT, + RIGHT_COPY_LEFT, }; -#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) +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); - 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, - } - }; +}; + +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_MW100) -static int mw100_io_init(void) + +#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(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME, GPIO2B_GPIO2B7); - rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME, GPIO2C_GPIO2C0); + 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 mw100_io_deinit(void) +static int bp_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 bp_id_get(void) +{ + return ap_mdm; //internally 3G modem ID, defined in include\linux\Bp-auto.h } -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", +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 = &rk29_mt6229_info, + .platform_data = &bp_auto_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) +#ifdef CONFIG_RK29_SUPPORT_MODEM + +#define RK30_MODEM_POWER RK30_PIN4_PD1 +#define RK30_MODEM_POWER_IOMUX rk29_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME, GPIO4D_GPIO4D1) + +static int rk30_modem_io_init(void) { + printk("%s\n", __FUNCTION__); + RK30_MODEM_POWER_IOMUX; + 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, - } - }; + +static struct rk29_io_t rk30_modem_io = { + .io_addr = RK30_MODEM_POWER, + .enable = GPIO_HIGH, + .disable = GPIO_LOW, + .io_init = rk30_modem_io_init, +}; + +static struct platform_device rk30_device_modem = { + .name = "rk30_modem", + .id = -1, + .dev = { + .platform_data = &rk30_modem_io, + } +}; #endif + /*MMA8452 gsensor*/ #if defined (CONFIG_GS_MMA8452) #define MMA8452_INT_PIN RK30_PIN4_PC0 @@ -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) diff --git a/arch/arm/plat-rk/include/plat/board.h b/arch/arm/plat-rk/include/plat/board.h index 8c04bd7f4391..781964b007e4 100755 --- a/arch/arm/plat-rk/include/plat/board.h +++ b/arch/arm/plat-rk/include/plat/board.h @@ -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; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index af7436547213..75325d878862 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -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" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 77751eb6f94f..10dacabbfc4a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -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/ diff --git a/drivers/input/touchscreen/ct36x_ts/Kconfig b/drivers/input/touchscreen/ct36x_ts/Kconfig new file mode 100644 index 000000000000..220d300a4ac2 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/Kconfig @@ -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 diff --git a/drivers/input/touchscreen/ct36x_ts/Makefile b/drivers/input/touchscreen/ct36x_ts/Makefile new file mode 100644 index 000000000000..447628a18ea3 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/Makefile @@ -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 + diff --git a/drivers/input/touchscreen/ct36x_ts/allwinner.c b/drivers/input/touchscreen/ct36x_ts/allwinner.c new file mode 100644 index 000000000000..bdf4b7af7376 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/allwinner.c @@ -0,0 +1,99 @@ + +#include + +#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); +} diff --git a/drivers/input/touchscreen/ct36x_ts/chip.h b/drivers/input/touchscreen/ct36x_ts/chip.h new file mode 100644 index 000000000000..495ef13c298d --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/chip.h @@ -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 + diff --git a/drivers/input/touchscreen/ct36x_ts/ct360.c b/drivers/input/touchscreen/ct36x_ts/ct360.c new file mode 100644 index 000000000000..13e18b05e3e5 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/ct360.c @@ -0,0 +1,363 @@ + +#include +#include + +#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); +} + diff --git a/drivers/input/touchscreen/ct36x_ts/ct360.h b/drivers/input/touchscreen/ct36x_ts/ct360.h new file mode 100644 index 000000000000..24b6117acd58 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/ct360.h @@ -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 diff --git a/drivers/input/touchscreen/ct36x_ts/ct365.c b/drivers/input/touchscreen/ct36x_ts/ct365.c new file mode 100644 index 000000000000..46ef83ba5aff --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/ct365.c @@ -0,0 +1,439 @@ + +#include +#include + +#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); +} + diff --git a/drivers/input/touchscreen/ct36x_ts/ct365.h b/drivers/input/touchscreen/ct36x_ts/ct365.h new file mode 100644 index 000000000000..a0a42be67dc9 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/ct365.h @@ -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 diff --git a/drivers/input/touchscreen/ct36x_ts/generic.c b/drivers/input/touchscreen/ct36x_ts/generic.c new file mode 100644 index 000000000000..8180ffe835e9 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/generic.c @@ -0,0 +1,109 @@ + +#include +#include +#include + +#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); +} diff --git a/drivers/input/touchscreen/ct36x_ts/generic.h b/drivers/input/touchscreen/ct36x_ts/generic.h new file mode 100644 index 000000000000..9d6e1d7adc51 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/generic.h @@ -0,0 +1,8 @@ + +#ifndef GENERIC_H +#define GENERIC_H + +#define CT36X_TS_I2C_SPEED 400000 + +#endif + diff --git a/drivers/input/touchscreen/ct36x_ts/platform.h b/drivers/input/touchscreen/ct36x_ts/platform.h new file mode 100644 index 000000000000..d7af54820555 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/platform.h @@ -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 diff --git a/drivers/input/touchscreen/ct36x_ts/rockchip.c b/drivers/input/touchscreen/ct36x_ts/rockchip.c new file mode 100644 index 000000000000..f0760af9740e --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/rockchip.c @@ -0,0 +1,136 @@ + +#include +#include + +#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); +} diff --git a/drivers/input/touchscreen/ct36x_ts/rockchip.h b/drivers/input/touchscreen/ct36x_ts/rockchip.h new file mode 100644 index 000000000000..feafe6c7e177 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/rockchip.h @@ -0,0 +1,15 @@ + +#ifndef ROCKCHIP_H +#define ROCKCHIP_H + +#include + +#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 + diff --git a/drivers/input/touchscreen/ct36x_ts/tscore.c b/drivers/input/touchscreen/ct36x_ts/tscore.c new file mode 100644 index 000000000000..f08670e1cb77 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/tscore.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + + +#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<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, .\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(""); +MODULE_DESCRIPTION("VTL ct36x TouchScreen driver"); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/input/touchscreen/ct36x_ts/tscore.h b/drivers/input/touchscreen/ct36x_ts/tscore.h new file mode 100644 index 000000000000..275806c20dc9 --- /dev/null +++ b/drivers/input/touchscreen/ct36x_ts/tscore.h @@ -0,0 +1,80 @@ +#ifndef TSCORE_H +#define TSCORE_H + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#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 + + diff --git a/drivers/input/touchscreen/ft5506_app.f b/drivers/input/touchscreen/ft5506_app.f new file mode 100644 index 000000000000..0a0d74b282bb --- /dev/null +++ b/drivers/input/touchscreen/ft5506_app.f @@ -0,0 +1,1793 @@ +0x2, 0x55,0x16,0x2, 0x59,0x84,0xca,0x79,0x7d,0x73,0x74,0x1, 0x12,0x5c,0x73,0x7d, +0x37,0x12,0x58,0x4f,0xe4,0x12,0x5c,0x73,0xda,0x79,0x22,0x2, 0x39,0x97,0x5, 0x8, +0xe5,0x8, 0xbe,0xb0,0x5, 0x28,0x3, 0x75,0x8, 0x0, 0x22,0x2, 0x58,0x8f,0x74,0x3, +0x7a,0xb3,0x29,0x68,0xe4,0x7a,0xb3,0x29,0x6f,0x74,0xff,0x7a,0xb3,0x29,0x67,0x22, +0x2, 0x5d,0x6a,0x2, 0x5d,0x5a,0x7e,0x24,0xff,0xff,0x1b,0x38,0x20,0x59,0x23,0x0, +0x2, 0x74,0xff,0x19,0xb3,0x0, 0x4, 0x22,0x2, 0x5e,0x51,0x2, 0x5e,0x1, 0x2, 0x5d, +0xf6,0x22,0xff,0x2, 0x5e,0x67,0xca,0x3b,0x7d,0xf0,0x7d,0xe1,0x7d,0x42,0x7d,0xc3, +0x6c,0xee,0x6c,0xdd,0x6d,0x55,0x7a,0x57,0x22,0xba,0x7a,0x57,0x22,0xbc,0x75,0x23, +0x0, 0x75,0x26,0x0, 0x6c,0xcc,0x49,0x5e,0x0, 0x13,0x7a,0x57,0x23,0x64,0x9, 0xbe, +0x0, 0x15,0xf5,0x29,0x7e,0xb4,0x0, 0x1, 0x6d,0x55,0x7a,0x57,0x23,0x66,0x7a,0x55, +0x2a,0x7d,0xdc,0x2e,0xd4,0xd, 0x80,0x7d,0x5c,0x2e,0x54,0x1d,0x40,0x7a,0x57,0x23, +0x62,0x6c,0xff,0x6c,0xaa,0x7e,0x70,0x7, 0xac,0x7f,0x7d,0x23,0x2d,0x2f,0x19,0xa2, +0x0, 0x55,0xe4,0x7d,0xa3,0x2d,0xaf,0x19,0xba,0x0, 0x56,0xb, 0xf0,0xbe,0xf0,0xa, +0x78,0xe1,0x9, 0xbf,0x0, 0x96,0x70,0x3, 0x2, 0x7, 0x7c,0x6c,0xff,0x2, 0x5, 0xdd, +0x75,0xc6,0x0, 0x75,0x28,0x2, 0x74,0x2, 0xac,0xbf,0x7d,0xa5,0x2d,0xaf,0x7e,0xa9, +0x60,0x1e,0x60,0xa, 0x56,0x7a,0x57,0x23,0x5e,0x4d,0x55,0x68,0xd, 0x7e,0x49,0x70, +0xa, 0x57,0x1b,0x54,0x9e,0x57,0x23,0x5e,0x78,0xb, 0x9, 0xbe,0x0, 0x10,0x1e,0xb0, +0xf5,0x28,0x43,0xc6,0x10,0x9, 0xaa,0x0, 0x1, 0x1e,0xa0,0xa, 0xaa,0x7a,0xa7,0x23, +0x5e,0x4d,0xaa,0x68,0xe, 0x9, 0x74,0x0, 0x1, 0xa, 0x27,0x1b,0x24,0x9e,0x27,0x23, +0x5e,0x78,0xb, 0x9, 0xbe,0x0, 0x10,0x1e,0xb0,0xf5,0x28,0x43,0xc6,0x8, 0xe5,0xc6, +0x60,0x8, 0x9, 0x7e,0x0, 0xf, 0x7c,0xb7,0x42,0xc6,0x7e,0x70,0x24,0xac,0x67,0x2d, +0xa3,0x7a,0xa5,0x24,0x75,0x27,0x0, 0x3e,0xa4,0x2d,0xad,0xb, 0xa8,0x30,0xb, 0xe8, +0xa0,0xbd,0x3a,0x40,0x3, 0x75,0x27,0x1, 0x7d,0xbc,0x2e,0xb4,0xd, 0x80,0x7d,0x3b, +0xa, 0x36,0x7c,0xb7,0xf5,0xba,0x7d,0x3b,0x7c,0xb7,0xf5,0xb9,0xa, 0x2a,0xe5,0x28, +0xa, 0x3b,0xbd,0x23,0x40,0x15,0x7e,0x50,0x2, 0xac,0x5f,0x2d,0x2f,0x9, 0x52,0x0, +0x1, 0x1e,0x50,0xa, 0x25,0x9d,0x23,0x7c,0xd5,0x80,0x2, 0x6c,0xdd,0x7a,0xd1,0xbb, +0x7e,0x50,0x2, 0xac,0x5f,0x2d,0x2f,0x7e,0x29,0x50,0x1e,0x50,0xa, 0x25,0xbd,0x23, +0x40,0x14,0x7e,0x50,0x2, 0xac,0x5f,0x2d,0x2f,0x7e,0x29,0x50,0x1e,0x50,0xa, 0x25, +0x9d,0x23,0x7c,0xe5,0x80,0x2, 0x6c,0xee,0x7c,0xbe,0x54,0x3, 0x1a,0x2b,0x3e,0x24, +0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7c,0xb5,0x42,0xbb,0x7c,0xbe, +0xe, 0xb0,0xe, 0xb0,0xf5,0xbc,0x9, 0x5f,0x0, 0x96,0xbe,0x50,0x1, 0x28,0x3, 0x75, +0x29,0x0, 0xe5,0x29,0xa, 0x2b,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x5e,0x24, +0x0, 0xf0,0x7c,0xb5,0x42,0xbc,0x7e,0x50,0x2, 0xac,0x5f,0x2d,0x2f,0x9, 0x52,0x0, +0x1, 0x1e,0x50,0xa, 0x25,0x2d,0x23,0x9, 0xa4,0x0, 0x1, 0xa, 0xaa,0xbd,0x2a,0x50, +0x6, 0x7c,0xb5,0xf5,0x22,0x80,0x6, 0xa, 0x5a,0x1b,0x54,0xf5,0x22,0x1a,0x2d,0xe5, +0x22,0x1a,0x5b,0x9d,0x52,0xb, 0x54,0xf5,0xc3,0x7e,0x50,0x2, 0xac,0x5f,0x2d,0x2f, +0x7e,0x29,0x50,0x1e,0x50,0xa, 0xa5,0x2d,0xa3,0x7e,0x49,0xa0,0xa, 0x3a,0xbd,0xa3, +0x50,0x8, 0x7d,0x3a,0x7c,0xb7,0xf5,0x21,0x80,0x6, 0xa, 0x5a,0x1b,0x54,0xf5,0x21, +0x1a,0x3e,0xe5,0x21,0x1a,0x5b,0x9d,0x53,0xb, 0x54,0xf5,0xc4,0x7e,0xb4,0x22,0xaa, +0x7d,0x5b,0xa, 0x5a,0xf5,0xc1,0x7d,0x3b,0x7c,0xb7,0xf5,0xbd,0x75,0xc2,0x7, 0x80, +0x3, 0x43,0xc2,0x1, 0x0, 0x0, 0x0, 0x0, 0xe5,0xc2,0x30,0xe7,0xf4,0x75,0xc2,0x0, +0x7e,0x1f,0x22,0xb2,0x74,0x4, 0xac,0xbf,0x59,0x35,0x23,0x10,0x59,0x25,0x23,0xe, +0x7e,0x1f,0x22,0xb6,0x59,0x35,0x22,0xc0,0x59,0x25,0x22,0xbe,0x7e,0x1f,0x22,0xae, +0x59,0x35,0x22,0xe8,0x59,0x25,0x22,0xe6,0x7e,0x1f,0x22,0xaa,0x59,0x35,0x23,0x38, +0x59,0x25,0x23,0x36,0x74,0x2, 0xac,0xbf,0x2d,0x5f,0x7e,0x59,0xe0,0x1e,0xe0,0x9e, +0xe1,0x28,0x2, 0x5, 0xc3,0x74,0x2, 0xac,0xbf,0x2d,0x5f,0x9, 0xd5,0x0, 0x1, 0x1e, +0xd0,0x9e,0xd1,0x28,0x2, 0x5, 0xa8,0xbe,0xe0,0x0, 0x58,0x3, 0x2, 0x5, 0xa6,0x7e, +0x49,0x70,0xbc,0x7e,0x18,0x3, 0x2, 0x5, 0xa6,0xbe,0xd0,0x0, 0x58,0x3, 0x2, 0x5, +0xa6,0x9, 0x74,0x0, 0x1, 0xbc,0x7d,0x18,0x3, 0x2, 0x5, 0xa6,0x1a,0x2e,0x7e,0x34, +0x0, 0x24,0xad,0x32,0x1a,0x5d,0x2d,0x53,0x7a,0x57,0x23,0x5e,0x3e,0x54,0x2d,0x5d, +0xb, 0x58,0xa0,0xe5,0x29,0xa, 0x5b,0xbd,0xa5,0x18,0x3, 0x2, 0x5, 0xa6,0xbe,0xa7, +0x23,0x64,0x40,0x13,0x74,0x7, 0xac,0xbf,0x7d,0xa5,0x2d,0xaf,0x2e,0xa4,0x0, 0x56, +0x7e,0xa9,0xb0,0x4, 0x7a,0xa9,0xb0,0xe5,0x27,0xb4,0x1, 0x2f,0x7e,0x57,0x23,0x5e, +0x5e,0x54,0x0, 0x7, 0x2e,0x54,0x5e,0x3b,0x7a,0xb1,0x82,0x7a,0xa1,0x83,0xe4,0x93, +0x7c,0x6b,0x6e,0x60,0xff,0x7e,0x57,0x23,0x5e,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x2e, +0x57,0x23,0x62,0x7e,0x59,0x70,0x5c,0x76,0x7a,0x59,0x70,0x7c,0xbe,0x3e,0xb0,0xf5, +0x26,0x7c,0xcd,0x3e,0xc0,0x7e,0x70,0x2, 0xac,0x7f,0x7d,0xa3,0x2d,0xaf,0x7e,0xa9, +0x70,0x7e,0x60,0x2, 0x12,0x5d,0x32,0x60,0x1a,0x7c,0xbc,0x7e,0x70,0x2, 0xac,0x7f, +0x7d,0xa3,0x2d,0xaf,0x9, 0x7a,0x0, 0x1, 0x7e,0x60,0x2, 0x12,0x5d,0x32,0x60,0x3, +0x2, 0x5, 0xa6,0x6d,0x55,0x2, 0x4, 0x2a,0xa, 0x5f,0xbe,0x57,0x23,0x60,0x68,0x64, +0xe5,0x26,0x7e,0xa7,0x23,0x60,0x3e,0xa4,0x2d,0xaf,0x7e,0xa9,0x70,0x7e,0x60,0x2, +0x12,0x5d,0x32,0x60,0x1c,0x7c,0xbc,0x7e,0xa7,0x23,0x60,0x3e,0xa4,0x2d,0xaf,0x9, +0x7a,0x0, 0x1, 0x7e,0x60,0x2, 0x12,0x5d,0x32,0x60,0x6, 0x7e,0x54,0xff,0xff,0x80, +0x2d,0xe5,0x26,0x7e,0xa7,0x23,0x60,0x3e,0xa4,0x2d,0xaf,0x7e,0xa9,0x70,0x7e,0x60, +0x4, 0x12,0x5d,0x32,0x60,0x1e,0x7c,0xbc,0x7e,0xa7,0x23,0x60,0x3e,0xa4,0x2d,0xaf, +0x9, 0x7a,0x0, 0x1, 0x7e,0x60,0x4, 0x12,0x5d,0x32,0x60,0x8, 0x6d,0x55,0x7a,0x57, +0x23,0x60,0x80,0x19,0x7e,0x57,0x23,0x60,0xb, 0x54,0x7a,0x57,0x23,0x60,0x9, 0x7f, +0x0, 0x96,0xa, 0x57,0xbe,0x57,0x23,0x60,0x8, 0x3, 0x2, 0x3, 0xb8,0x7e,0x57,0x23, +0x60,0x4d,0x55,0x68,0x3, 0x2, 0x4, 0xf3,0x7e,0xa7,0x23,0x5e,0x3e,0xa4,0x2d,0xad, +0xb, 0xa8,0x30,0x1a,0x26,0x1a,0x24,0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80, +0x1a,0x1e,0x1a,0x2, 0x12,0x4b,0xf8,0x7f,0x1, 0x74,0x4, 0xac,0xbf,0x2e,0x54,0x22, +0xe6,0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, 0x1b,0x58, +0x20,0xb, 0xa8,0x30,0x1a,0x26,0x1a,0x24,0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60, +0x80,0x1a,0x1d,0x1a,0x2, 0x12,0x4b,0xf8,0x7f,0x1, 0x74,0x4, 0xac,0xbf,0x2e,0x54, +0x22,0xbe,0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, 0x1b, +0x58,0x20,0x7e,0x57,0x23,0x5e,0x3e,0x54,0x2d,0x5d,0xb, 0x58,0x10,0xe, 0x14,0x1a, +0x2, 0x1a,0x0, 0x74,0x4, 0xac,0xbf,0x2e,0x54,0x23,0x36,0x49,0x35,0x0, 0x2, 0xb, +0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, 0x1b,0x58,0x20,0x74,0x4, 0xac,0xbf,0x2e, +0x54,0x23,0xe, 0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, +0x1b,0x58,0x20,0x7e,0x57,0x23,0x60,0xbe,0x54,0xff,0xff,0x68,0x3, 0x2, 0x5, 0xa6, +0x7e,0xa7,0x23,0x5e,0x3e,0xa4,0x2d,0xad,0xb, 0xa8,0x30,0x1a,0x26,0x1a,0x24,0x1a, +0x1e,0x1a,0x2, 0x12,0x4b,0xf8,0x7f,0x1, 0x74,0x4, 0xac,0xbf,0x2e,0x54,0x22,0xe6, +0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, 0x1b,0x58,0x20, +0xb, 0xa8,0x30,0x1a,0x26,0x1a,0x24,0x1a,0x1d,0x1a,0x2, 0x12,0x4b,0xf8,0x7f,0x1, +0x74,0x4, 0xac,0xbf,0x2e,0x54,0x22,0xbe,0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f, +0x10,0x59,0x35,0x0, 0x2, 0x1b,0x58,0x20,0x7e,0x57,0x23,0x5e,0x3e,0x54,0x2d,0x5d, +0xb, 0x58,0x10,0x1a,0x2, 0x1a,0x0, 0x74,0x4, 0xac,0xbf,0x2e,0x54,0x23,0x36,0x49, +0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59,0x35,0x0, 0x2, 0x1b,0x58,0x20,0x7e, +0x57,0x23,0x5e,0x3e,0x54,0x2d,0x5d,0xb, 0x58,0x10,0x1a,0x2, 0x1a,0x0, 0x74,0x4, +0xac,0xbf,0x2e,0x54,0x23,0xe, 0x49,0x35,0x0, 0x2, 0xb, 0x58,0x20,0x9f,0x10,0x59, +0x35,0x0, 0x2, 0x1b,0x58,0x20,0xb, 0xd0,0x74,0x2, 0xac,0xbf,0x2d,0x5f,0x9, 0xb5, +0x0, 0x1, 0x1e,0xb0,0x25,0x28,0x1a,0xab,0x1a,0x5d,0xbd,0x5a,0x18,0x3, 0x2, 0x2, +0xe7,0xb, 0xe0,0x74,0x2, 0xac,0xbf,0x2d,0x5f,0x7e,0x59,0xb0,0x1e,0xb0,0x25,0x28, +0x1a,0xab,0x1a,0x5e,0xbd,0x5a,0x18,0x3, 0x2, 0x2, 0xd5,0xb, 0xf0,0x9, 0x7f,0x0, +0x96,0xbc,0x7f,0x28,0x3, 0x2, 0x0, 0xe0,0x6c,0xff,0x2, 0x7, 0x6b,0x7e,0x90,0x2, +0xac,0x9f,0x2d,0x4f,0x7e,0x49,0xa0,0x1e,0xa0,0x74,0x24,0xa4,0x9, 0x74,0x0, 0x1, +0x1e,0x70,0xa, 0xc7,0x2d,0xc5,0x3e,0xc4,0x2d,0xcd,0xb, 0xc8,0xc0,0x7a,0xc5,0x2a, +0xb, 0xe8,0xc0,0xbe,0xc5,0x2a,0x28,0x3, 0x2, 0x7, 0x69,0x7e,0xa0,0x6, 0x7e,0x90, +0x4, 0xac,0x9f,0x7d,0xc4,0x2e,0xc4,0x22,0xbe,0x49,0x3c,0x0, 0x2, 0xb, 0xc8,0x20, +0x7c,0xba,0x2f,0x11,0x14,0x78,0xfb,0x59,0x3c,0x0, 0x2, 0x1b,0xc8,0x20,0x49,0x14, +0x23,0x10,0x49,0x4, 0x23,0xe, 0x49,0x34,0x22,0xc0,0x49,0x24,0x22,0xbe,0x12,0x4c, +0x14,0x7d,0x93,0x2e,0x94,0x0, 0x20,0x7a,0x97,0x22,0xba,0x7e,0xa0,0x6, 0x7e,0x70, +0x4, 0xac,0x7f,0x7d,0xc3,0x2e,0xc4,0x22,0xe6,0x49,0x3c,0x0, 0x2, 0xb, 0xc8,0x20, +0x7c,0xba,0x2f,0x11,0x14,0x78,0xfb,0x59,0x3c,0x0, 0x2, 0x1b,0xc8,0x20,0x74,0x4, +0xac,0xbf,0x49,0xb5,0x23,0x38,0x49,0xa5,0x23,0x36,0x74,0x4, 0xac,0xbf,0x49,0x35, +0x22,0xe8,0x49,0x25,0x22,0xe6,0x7f,0x5, 0x12,0x4c,0x14,0x7d,0xc3,0x2e,0xc4,0x0, +0x20,0x7a,0xc7,0x22,0xbc,0x7e,0xd1,0x23,0x74,0x7, 0xac,0xdb,0x7d,0x86,0x2d,0x8f, +0x59,0x98,0x0, 0x50,0x7d,0x36,0x2d,0x3f,0x59,0xc3,0x0, 0x52,0x7e,0x45,0x2a,0xbe, +0x44,0x0, 0x0, 0x28,0x18,0x9, 0x7e,0x0, 0x12,0xa, 0x17,0x6d,0x0, 0x7f,0x15,0x12, +0x4b,0xf8,0x7d,0x14,0x12,0x4c,0x12,0x7d,0xc3,0x7a,0xc7,0x23,0x66,0x7e,0xc7,0x23, +0x66,0xbe,0xc4,0x0, 0xff,0x28,0x8, 0x7e,0xc4,0x0, 0xff,0x7a,0xc7,0x23,0x66,0x9, +0xae,0x0, 0x12,0x7e,0x70,0x4, 0xac,0x7f,0x7d,0xc3,0x2e,0xc4,0x23,0x36,0x49,0x3c, +0x0, 0x2, 0xb, 0xc8,0x20,0x7c,0xba,0x60,0xc, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e, +0x60,0x80,0x14,0x78,0xf4,0x59,0x3c,0x0, 0x2, 0x1b,0xc8,0x20,0x74,0x4, 0xac,0xbf, +0x49,0x35,0x23,0x38,0x49,0x25,0x23,0x36,0xbe,0x18,0x0, 0x7f,0x28,0x10,0x7e,0x18, +0x0, 0x7f,0x74,0x4, 0xac,0xbf,0x59,0x35,0x23,0x38,0x59,0x25,0x23,0x36,0x74,0x4, +0xac,0xbf,0x49,0x35,0x23,0x38,0x49,0x25,0x23,0x36,0x7d,0xc6,0x2d,0xcf,0x19,0x7c, +0x0, 0x55,0x7e,0x57,0x23,0x66,0x7c,0xab,0x7e,0x71,0x23,0x74,0x7, 0xac,0x7b,0x7d, +0xc3,0x2d,0xcf,0x19,0xac,0x0, 0x56,0x5, 0x23,0xb, 0xf0,0x9, 0x7f,0x0, 0x96,0xbc, +0x7f,0x28,0x3, 0x2, 0x5, 0xed,0xe5,0x23,0x19,0xbf,0x0, 0x96,0xda,0x3b,0x22,0x2, +0x5e,0xc, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xca,0x3b,0x7a,0x5, 0x21,0x7d,0x71,0x7d,0x62,0x75,0x24,0x0, 0x6d,0x22,0x7a,0x27, +0x22,0xaa,0x7a,0x27,0x22,0xac,0x7a,0x27,0x22,0xae,0x7a,0x27,0x22,0xb0,0x75,0x25, +0x0, 0x75,0x26,0xff,0x75,0x2b,0x0, 0x75,0x2c,0x0, 0x49,0x27,0x0, 0x3, 0x7a,0x27, +0x23,0x54,0x7e,0x24,0x2a,0x10,0x7a,0x27,0x23,0x56,0x6d,0x22,0x7a,0x27,0x2a,0x1a, +0x7e,0x17,0x23,0x56,0x59,0x21,0x0, 0xc, 0x7e,0x17,0x23,0x56,0x59,0x21,0x0, 0x18, +0x7e,0x17,0x23,0x56,0x59,0x21,0x0, 0x1a,0x2e,0x34,0xd, 0x80,0x7a,0x37,0x23,0x52, +0x75,0x23,0x0, 0x2, 0xc, 0xe9,0x7e,0xa1,0x23,0x74,0x24,0xa4,0x7a,0x55,0x29,0x75, +0x24,0x0, 0x2, 0xc, 0xdb,0x7e,0x35,0x29,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38, +0x30,0x12,0x5d,0x8a,0x7e,0x27,0x23,0x56,0x49,0x12,0x0, 0xe, 0xbd,0x31,0x38,0x3, +0x2, 0x8, 0x9f,0x2e,0x24,0x0, 0xa, 0xb, 0x28,0x30,0xb, 0x34,0x1b,0x28,0x30,0x7e, +0x35,0x29,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38,0x10,0x7e,0x27,0x23,0x56,0x49, +0x32,0x0, 0x10,0xbd,0x13,0x48,0x3, 0x2, 0x8, 0xc6,0x2e,0x24,0x0, 0xc, 0xb, 0x28, +0x30,0xb, 0x34,0x1b,0x28,0x30,0x7e,0x35,0x29,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, +0x38,0x30,0x12,0x5d,0x8a,0x7e,0x27,0x23,0x56,0x9, 0x32,0x0, 0x9, 0xa, 0x13,0xbd, +0x31,0x18,0x3, 0x2, 0x8, 0xf2,0x2e,0x24,0x0, 0x18,0xb, 0x28,0x30,0xb, 0x34,0x1b, +0x28,0x30,0x7e,0x35,0x29,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38,0x30,0x12,0x5d, +0x8a,0x7e,0x27,0x23,0x56,0x9, 0x32,0x0, 0x8, 0xa, 0x13,0xbd,0x31,0x18,0x3, 0x2, +0x9, 0x1e,0x2e,0x24,0x0, 0x1a,0xb, 0x28,0x30,0xb, 0x34,0x1b,0x28,0x30,0x7e,0x37, +0x23,0x56,0x9, 0xb3,0x0, 0x6, 0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x9, 0x61,0x9, 0x53, +0x0, 0x3, 0xbe,0x51,0x23,0x28,0x3, 0x2, 0x9, 0x61,0x9, 0x53,0x0, 0x2, 0xbe,0x51, +0x23,0x50,0x3, 0x2, 0x9, 0x61,0x9, 0x53,0x0, 0x5, 0xbe,0x51,0x24,0x28,0x3, 0x2, +0x9, 0x61,0x9, 0x73,0x0, 0x4, 0xbe,0x71,0x24,0x50,0x3, 0x2, 0x9, 0x61,0x2, 0xc, +0xd1,0x7e,0x15,0x29,0x7d,0x21,0x3e,0x24,0x2e,0x27,0x23,0x52,0xb, 0x28,0x30,0xbe, +0x37,0x23,0x54,0x18,0x3, 0x2, 0xc, 0xd1,0xe5,0x23,0x60,0x3, 0x2, 0x9, 0x84,0x6d, +0x0, 0x2, 0x9, 0x93,0x7d,0x1, 0x9e,0x4, 0x0, 0x24,0x3e,0x4, 0x2e,0x7, 0x23,0x52, +0xb, 0x8, 0x0, 0x7a,0x7, 0x22,0xaa,0x7e,0x69,0xb0,0x14,0xbe,0xb1,0x23,0x68,0x3, +0x2, 0x9, 0xa8,0x6d,0x0, 0x2, 0x9, 0xac,0x49,0x2, 0x0, 0x48,0x7a,0x7, 0x22,0xac, +0xe5,0x24,0x60,0x3, 0x2, 0x9, 0xc0,0x6d,0x0, 0x7a,0x7, 0x22,0xb0,0x2, 0x9, 0xcf, +0x1b,0x14,0x3e,0x14,0x2e,0x17,0x23,0x52,0xb, 0x18,0x10,0x7a,0x17,0x22,0xb0,0x9, +0xb6,0x0, 0x1, 0x14,0xbe,0xb1,0x24,0x68,0x3, 0x2, 0x9, 0xe5,0x6d,0x11,0x7a,0x17, +0x22,0xae,0x2, 0x9, 0xed,0x49,0x22,0x0, 0x2, 0x7a,0x27,0x22,0xae,0x7e,0x27,0x22, +0xac,0xbe,0x27,0x22,0xaa,0x18,0x3, 0x2, 0x9, 0xfe,0x7a,0x27,0x22,0xaa,0x7e,0x27, +0x22,0xae,0xbe,0x27,0x22,0xaa,0x18,0x3, 0x2, 0xa, 0xf, 0x7a,0x27,0x22,0xaa,0x7e, +0x27,0x22,0xb0,0xbe,0x27,0x22,0xaa,0x18,0x3, 0x2, 0xa, 0x20,0x7a,0x27,0x22,0xaa, +0xbe,0x37,0x22,0xaa,0x58,0x3, 0x2, 0xc, 0xd1,0xbe,0x37,0x23,0x54,0x58,0x3, 0x2, +0xc, 0xd1,0xe5,0x23,0x3e,0xb0,0xf5,0x2b,0xe5,0x24,0x3e,0xb0,0xf5,0x2c,0xe5,0x25, +0x60,0x3, 0x2, 0xa, 0x56,0xe5,0x2b,0x7a,0xb3,0x22,0xb2,0xe5,0x2c,0x7a,0xb3,0x22, +0xb3,0x5, 0x25,0x2, 0xc, 0xd1,0xe5,0x25,0xbe,0xb0,0x28,0x50,0x3, 0x2, 0xa, 0x66, +0x75,0x25,0x28,0x2, 0xc, 0xd1,0x75,0x26,0x0, 0x2, 0xc, 0xa7,0xe5,0x2b,0x7e,0xa1, +0x26,0x1a,0x3a,0x3e,0x34,0x9, 0x73,0x22,0xb2,0x7e,0x60,0x2, 0x12,0x5d,0x32,0x70, +0x3, 0x2, 0xa, 0xe2,0xe5,0x2c,0x7e,0xa1,0x26,0x1a,0x3a,0x3e,0x34,0x9, 0x73,0x22, +0xb3,0x7e,0x60,0x2, 0x12,0x5d,0x32,0x70,0x3, 0x2, 0xa, 0xe2,0xe5,0x26,0x1a,0x3b, +0x3e,0x34,0x9, 0x43,0x22,0xb2,0x1e,0x40,0x7e,0x50,0x24,0xac,0x45,0x9, 0x33,0x22, +0xb3,0x1e,0x30,0xa, 0x13,0x2d,0x21,0x3e,0x24,0x2e,0x27,0x23,0x52,0xb, 0x28,0x10, +0x7e,0x25,0x29,0x3e,0x24,0x2e,0x27,0x23,0x52,0xb, 0x28,0x20,0xbd,0x12,0x48,0x3, +0x2, 0xc, 0x9f,0xe5,0x2b,0x19,0xb3,0x22,0xb2,0xe5,0x2c,0x19,0xb3,0x22,0xb3,0x2, +0xc, 0x9f,0xe5,0x2b,0x7e,0xa1,0x26,0x1a,0x3a,0x3e,0x34,0x9, 0x73,0x22,0xb2,0x7e, +0x60,0x6, 0x12,0x5d,0x32,0x70,0x3, 0x2, 0xc, 0xa5,0xe5,0x2c,0x7e,0xa1,0x26,0x1a, +0x3a,0x3e,0x34,0x9, 0x73,0x22,0xb3,0x7e,0x60,0x6, 0x12,0x5d,0x32,0x70,0x3, 0x2, +0xc, 0xa5,0xe5,0x26,0x1a,0x3b,0x3e,0x34,0x9, 0x53,0x22,0xb2,0x1e,0x50,0xa, 0x25, +0xe5,0x23,0xa, 0x5b,0x2d,0x52,0xf5,0x27,0x9, 0x73,0x22,0xb3,0x1e,0x70,0xa, 0x47, +0xe5,0x24,0xa, 0x5b,0x2d,0x54,0xf5,0x28,0x6d,0x33,0x2, 0xb, 0x84,0xe5,0x26,0x1a, +0x3b,0xbe,0x37,0x22,0xaa,0x78,0x3, 0x2, 0xb, 0x7e,0xe5,0x27,0x7e,0x37,0x22,0xaa, +0x3e,0x34,0x9, 0x73,0x22,0xb2,0x7e,0x60,0x2, 0x12,0x5d,0x32,0x70,0x3, 0x2, 0xb, +0x7e,0xe5,0x28,0x7e,0x37,0x22,0xaa,0x3e,0x34,0x9, 0x73,0x22,0xb3,0x7e,0x60,0x2, +0x12,0x5d,0x32,0x70,0x3, 0x2, 0xb, 0x7e,0x75,0x27,0xff,0x2, 0xb, 0x92,0x7e,0x37, +0x22,0xaa,0xb, 0x34,0x7a,0x37,0x22,0xaa,0xe5,0x25,0xa, 0x3b,0xbe,0x37,0x22,0xaa, +0x18,0xab,0xe5,0x27,0xbe,0xb0,0xff,0x78,0x3, 0x2, 0xc, 0xa5,0xe5,0x26,0x1a,0x1b, +0x3e,0x14,0x9, 0x1, 0x22,0xb2,0x1e,0x0, 0x7e,0x10,0x24,0xac,0x1, 0x9, 0x71,0x22, +0xb3,0x1e,0x70,0xa, 0x37,0x2d,0x3, 0x3e,0x4, 0x2e,0x7, 0x23,0x52,0xb, 0x8, 0x20, +0x7e,0x35,0x29,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38,0x30,0xbd,0x23,0x18,0x3, +0x2, 0xb, 0xda,0x7a,0x27,0x22,0xac,0x2, 0xb, 0xde,0x7a,0x37,0x22,0xac,0x7e,0x37, +0x22,0xac,0x7d,0x23,0xe, 0x24,0xe, 0x24,0xe, 0x34,0x2d,0x32,0x7a,0x37,0x22,0xac, +0xb, 0x78,0x30,0xbe,0x37,0x22,0xac,0x38,0x3, 0x2, 0xc, 0x0, 0x7a,0x37,0x22,0xac, +0xe5,0x27,0x1a,0x1b,0xb, 0x14,0xe, 0x14,0x7e,0x44,0x0, 0x24,0xad,0x14,0x7e,0x71, +0x28,0x1e,0x70,0xa, 0x37,0x7d,0x21,0x2d,0x23,0x3e,0x24,0x2e,0x27,0x23,0x52,0xb, +0x28,0x20,0x7e,0x11,0x27,0xe, 0x10,0x1a,0x1, 0x7d,0x50,0xad,0x54,0x2d,0x35,0x3e, +0x34,0x2e,0x37,0x23,0x52,0xb, 0x38,0x30,0x2d,0x32,0x7a,0x37,0x22,0xae,0xe, 0x34, +0x7a,0x37,0x22,0xae,0xe5,0x28,0xa, 0x3b,0xb, 0x34,0xe, 0x34,0x7d,0x21,0x2d,0x23, +0x3e,0x24,0x2e,0x27,0x23,0x52,0xb, 0x28,0x20,0x7e,0x14,0x0, 0x24,0xad,0x10,0x2d, +0x31,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38,0x30,0x2d,0x32,0x7a,0x37,0x22,0xb0, +0xe, 0x34,0x7a,0x37,0x22,0xb0,0x2e,0x37,0x22,0xae,0xe, 0x34,0xbe,0x37,0x22,0xac, +0x58,0x3, 0x2, 0xc, 0xa5,0x7e,0xa1,0x27,0xe5,0x26,0x1a,0x3b,0x3e,0x34,0x19,0xa3, +0x22,0xb2,0x7e,0xa1,0x28,0xe5,0x26,0x1a,0x3b,0x3e,0x34,0x19,0xa3,0x22,0xb3,0x75, +0x26,0xff,0x2, 0xc, 0xb1,0x5, 0x26,0xe5,0x25,0xbe,0xb1,0x26,0x8, 0x3, 0x2, 0xa, +0x6c,0xe5,0x25,0xbe,0xb1,0x26,0x68,0x3, 0x2, 0xc, 0xd1,0x7e,0xa1,0x2b,0x7e,0x71, +0x25,0x74,0x2, 0xac,0x7b,0x19,0xa3,0x22,0xb2,0xe5,0x2c,0x19,0xb3,0x22,0xb3,0x5, +0x25,0x7e,0x35,0x29,0xb, 0x34,0x7a,0x35,0x29,0x5, 0x24,0x9, 0x76,0x0, 0x1, 0xbe, +0x71,0x24,0x28,0x3, 0x2, 0x8, 0x75,0x5, 0x23,0x7e,0x69,0x70,0xbe,0x71,0x23,0x28, +0x3, 0x2, 0x8, 0x66,0xe5,0x25,0xbe,0xb0,0xa, 0x38,0x3, 0x2, 0xd, 0xb1,0x75,0x23, +0x0, 0x6d,0x33,0x7a,0x37,0x22,0xaa,0x75,0x28,0x0, 0x75,0x24,0x0, 0x2, 0xd, 0x59, +0x7e,0x91,0x24,0x74,0x2, 0xac,0x9b,0x9, 0x54,0x22,0xb2,0xbe,0x50,0xff,0x78,0x3, +0x2, 0xd, 0x57,0x7c,0x65,0x1e,0x60,0x7e,0x70,0x24,0xac,0x67,0x9, 0xa4,0x22,0xb3, +0x7c,0x4a,0x1e,0x40,0xa, 0x14,0x2d,0x31,0x3e,0x34,0x2e,0x37,0x23,0x52,0xb, 0x38, +0x30,0xbe,0x37,0x22,0xaa,0x18,0x3, 0x2, 0xd, 0x57,0x7a,0x51,0x2b,0x7a,0xa1,0x2c, +0x7a,0x37,0x22,0xaa,0x85,0x24,0x28,0x5, 0x24,0xe5,0x25,0xbe,0xb1,0x24,0x38,0xb0, +0x7e,0xa1,0x2b,0x7e,0x71,0x23,0x74,0x2, 0xac,0x7b,0x19,0xa3,0x23,0x2, 0xe5,0x2c, +0x19,0xb3,0x23,0x3, 0x7e,0xa0,0xff,0x7e,0x71,0x28,0x74,0x2, 0xac,0x7b,0x19,0xa3, +0x22,0xb2,0x5, 0x23,0xe5,0x23,0xb4,0xa, 0x2, 0x80,0x3, 0x2, 0xd, 0x1, 0x75,0x23, +0x0, 0x7e,0xa1,0x23,0x74,0x2, 0xa4,0x9, 0x75,0x23,0x2, 0x19,0x75,0x22,0xb2,0x9, +0x75,0x23,0x3, 0x19,0x75,0x22,0xb3,0x5, 0x23,0xe5,0x23,0xb4,0xa, 0xe3,0x75,0x25, +0xa, 0xe5,0x25,0xbe,0xb0,0x0, 0x38,0x3, 0x2, 0xd, 0xed,0x75,0x23,0x0, 0x2, 0xd, +0xe6,0x7e,0x71,0x23,0x74,0x2, 0xac,0x7b,0x9, 0x53,0x22,0xb2,0x2e,0x35,0x21,0x7a, +0x39,0x50,0x7e,0x51,0x23,0x74,0x2, 0xac,0x5b,0x9, 0x72,0x22,0xb3,0x2e,0x25,0x21, +0x19,0x72,0x0, 0x1, 0x5, 0x23,0xe5,0x25,0xbe,0xb1,0x23,0x38,0xd4,0xe5,0x25,0x7e, +0x35,0x21,0x19,0xb3,0x0, 0x96,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x71,0x7a,0x25,0x27, +0x7a,0x35,0x25,0x9, 0xb7,0x0, 0x8e,0xf5,0x30,0x9, 0xd7,0x0, 0x8f,0x75,0x2d,0x0, +0x7e,0xa0,0xff,0x7e,0x71,0x2d,0x74,0x7, 0xac,0x7b,0x19,0xa3,0x22,0xae,0x7e,0x34, +0x7f,0xff,0x7e,0xa1,0x2d,0x74,0x7, 0xa4,0x59,0x35,0x22,0xaa,0x7e,0x34,0x7f,0xff, +0x7e,0xa1,0x2d,0x74,0x7, 0xa4,0x59,0x35,0x22,0xac,0x5, 0x2d,0xe5,0x2d,0xb4,0xa, +0xcf,0xe5,0x30,0x70,0x4e,0xbe,0xd0,0x0, 0x38,0x3, 0x2, 0x13,0x58,0xf5,0x2e,0x7e, +0xa0,0xff,0x7e,0x71,0x2e,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x19,0xa3,0x0, 0x4a,0x5, +0x2e,0xe5,0x2e,0xb4,0xa, 0xe9,0x7d,0x37,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x44, +0x4, 0x7a,0x39,0xb0,0x7d,0x37,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xf7,0x7a, +0x39,0xb0,0x7d,0x37,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xdf,0x7a,0x39,0xb0, +0x2, 0x13,0x58,0x75,0x2e,0x0, 0x80,0x3a,0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2e, +0x25,0x25,0x2e,0x24,0x0, 0x50,0xb, 0x28,0x30,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e, +0x34,0x1b,0x28,0x30,0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2e,0x25,0x25,0x2e,0x24, +0x0, 0x52,0xb, 0x28,0x30,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x1b,0x28,0x30, +0x5, 0x2e,0xe5,0x30,0xbe,0xb1,0x2e,0x38,0xbf,0x4c,0xdd,0x78,0xe, 0x7d,0x37,0x2e, +0x34,0x0, 0x92,0x7e,0x39,0xb0,0x44,0x10,0x7a,0x39,0xb0,0x75,0x2d,0x0, 0x75,0x2e, +0x0, 0x75,0x2f,0x0, 0x80,0x63,0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25, +0x9, 0x53,0x0, 0x54,0x7e,0x71,0x2e,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x9, 0xa3,0x0, +0x4a,0xbc,0xa5,0x78,0x42,0xbe,0xa0,0xff,0x68,0x3d,0x7e,0x71,0x2d,0x74,0x7, 0xac, +0x7b,0x19,0xa3,0x22,0xae,0x7e,0x71,0x2e,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33, +0x0, 0x46,0x7e,0xa1,0x2d,0x74,0x7, 0xa4,0x59,0x35,0x22,0xaa,0x7e,0x71,0x2e,0x74, +0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33,0x0, 0x48,0x7e,0xa1,0x2d,0x74,0x7, 0xa4,0x59, +0x35,0x22,0xac,0x5, 0x2d,0x80,0x9, 0x5, 0x2f,0xe5,0x30,0xbe,0xb1,0x2f,0x38,0x96, +0x5, 0x2e,0xe5,0x2e,0xb4,0xa, 0x8a,0x75,0x2e,0x0, 0x85,0x30,0x2f,0x80,0x63,0x7e, +0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25,0x9, 0x53,0x0, 0x54,0x7e,0x71,0x2e, +0x74,0x7, 0xac,0x7b,0x2d,0x37,0x9, 0xa3,0x0, 0x4a,0xbc,0xa5,0x78,0x42,0xbe,0xa0, +0xff,0x68,0x3d,0x7e,0x71,0x2d,0x74,0x7, 0xac,0x7b,0x19,0xa3,0x22,0xae,0x7e,0x71, +0x2e,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33,0x0, 0x46,0x7e,0xa1,0x2d,0x74,0x7, +0xa4,0x59,0x35,0x22,0xaa,0x7e,0x71,0x2e,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33, +0x0, 0x48,0x7e,0xa1,0x2d,0x74,0x7, 0xa4,0x59,0x35,0x22,0xac,0x5, 0x2d,0x80,0x9, +0x5, 0x2f,0xe5,0x2f,0xbe,0xb0,0xa, 0x40,0x96,0x5, 0x2e,0xe5,0x2e,0xb4,0xa, 0x8a, +0x75,0x2f,0x0, 0x75,0x2e,0x0, 0x80,0x1e,0x7e,0xa1,0x2e,0x74,0x7, 0xa4,0x9, 0x65, +0x22,0xae,0x7e,0x51,0x2f,0x74,0x7, 0xac,0x5b,0x2e,0x25,0x25,0x9, 0x72,0x0, 0x54, +0xbc,0x76,0x68,0x9, 0x5, 0x2e,0xe5,0x2d,0xbe,0xb1,0x2e,0x38,0xdb,0xe5,0x2d,0xbe, +0xb1,0x2e,0x78,0x20,0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25,0x2e,0x34, +0x0, 0x50,0x7e,0x31,0x2d,0x74,0x7, 0xac,0x3b,0x2e,0x14,0x22,0xaa,0x74,0x7, 0x12, +0x4c,0x65,0x5, 0x2d,0x5, 0x2f,0xe5,0x2f,0xb4,0xa, 0xa8,0x7e,0x24,0x22,0xaa,0x7d, +0x37,0x2e,0x34,0x0, 0x46,0x7e,0x14,0x0, 0x46,0x12,0x5d,0x1b,0x4c,0xdd,0x78,0x17, +0x7e,0x25,0x25,0x2e,0x24,0x0, 0x50,0x7d,0x37,0x2e,0x34,0x0, 0x46,0x7e,0x14,0x0, +0x46,0x12,0x5d,0x1b,0x2, 0x12,0x94,0x9, 0xb7,0x0, 0x92,0x30,0xe3,0x3, 0x2, 0x12, +0x94,0x75,0x2f,0x0, 0x2, 0x12,0x8a,0x75,0x2e,0x0, 0x7e,0x71,0x2f,0x74,0x7, 0xac, +0x7b,0x2e,0x35,0x25,0x9, 0x43,0x0, 0x54,0x7e,0x31,0x2e,0x74,0x7, 0xac,0x3b,0x2d, +0x17,0x9, 0x51,0x0, 0x4a,0xbc,0x54,0x68,0x9, 0x5, 0x2e,0xe5,0x2e,0xbe,0xb0,0xa, +0x40,0xd8,0x49,0x33,0x0, 0x52,0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49, +0x22,0x0, 0x48,0x12,0x5d,0x7a,0x7d,0x63,0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e, +0x35,0x25,0x49,0x33,0x0, 0x50,0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49, +0x22,0x0, 0x46,0x12,0x5d,0x7a,0x2d,0x36,0x7a,0x35,0x29,0x7a,0x35,0x2b,0x7e,0x35, +0x27,0x49,0x33,0x0, 0x1, 0xbe,0x35,0x29,0x28,0x3, 0x2, 0x11,0x86,0x7e,0x71,0x2f, +0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25,0x49,0x33,0x0, 0x50,0x7e,0x51,0x2e,0x74,0x7, +0xac,0x5b,0x2d,0x27,0x49,0x22,0x0, 0x46,0x12,0x5d,0x7a,0x7a,0x35,0x29,0x7e,0x31, +0x2e,0x74,0x7, 0xac,0x3b,0x2d,0x17,0x49,0x21,0x0, 0x46,0x7e,0x71,0x2f,0x74,0x7, +0xac,0x7b,0x2e,0x35,0x25,0x49,0x3, 0x0, 0x50,0xbd,0x2, 0x28,0x10,0x7d,0x51,0x2e, +0x54,0x0, 0x46,0x7d,0x2, 0x2e,0x5, 0x29,0x1b,0x58,0x0, 0x80,0xa, 0x2e,0x14,0x0, +0x46,0x9e,0x25,0x29,0x1b,0x18,0x20,0x49,0x33,0x0, 0x52,0x7e,0x51,0x2e,0x74,0x7, +0xac,0x5b,0x2d,0x27,0x49,0x22,0x0, 0x48,0x12,0x5d,0x7a,0x7a,0x35,0x29,0x7e,0x51, +0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49,0x32,0x0, 0x48,0x7e,0x31,0x2f,0x74,0x7, +0xac,0x3b,0x2e,0x15,0x25,0x49,0x11,0x0, 0x52,0xbd,0x13,0x38,0x3, 0x2, 0x12,0x7e, +0x2, 0x12,0x6e,0x2, 0x12,0x7e,0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25, +0x49,0x33,0x0, 0x50,0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49,0x22,0x0, +0x46,0x12,0x5d,0x7a,0x7d,0xf3,0x7a,0xf5,0x29,0x7e,0x35,0x2b,0x6d,0x22,0x7c,0x56, +0x7c,0x67,0x6c,0x77,0x7e,0xe5,0x27,0x49,0x1e,0x0, 0x1, 0x12,0x4c,0x12,0x7a,0x71, +0x2d,0xa, 0x37,0x6d,0x22,0x7d,0x1f,0x12,0x4c,0x9, 0x7c,0x76,0x7c,0x65,0xa, 0x24, +0x7a,0x35,0x29,0x7e,0x31,0x2e,0x74,0x7, 0xac,0x3b,0x2d,0x17,0x49,0x21,0x0, 0x46, +0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e,0x35,0x25,0x49,0x3, 0x0, 0x50,0xbd,0x2, +0x28,0x10,0x7d,0x51,0x2e,0x54,0x0, 0x46,0x7d,0x2, 0x2e,0x5, 0x29,0x1b,0x58,0x0, +0x80,0xa, 0x2e,0x14,0x0, 0x46,0x9e,0x25,0x29,0x1b,0x18,0x20,0x49,0x33,0x0, 0x52, +0x7e,0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49,0x22,0x0, 0x48,0x12,0x5d,0x7a, +0x7d,0xf3,0x7a,0xf5,0x29,0x7e,0x35,0x2b,0x6d,0x22,0x7c,0x56,0x7c,0x67,0x6c,0x77, +0x7e,0xe5,0x27,0x49,0x1e,0x0, 0x1, 0x12,0x4c,0x12,0x7a,0x71,0x2d,0xa, 0x37,0x6d, +0x22,0x7d,0x1f,0x12,0x4c,0x9, 0x7c,0x76,0x7c,0x65,0xa, 0x24,0x7a,0x35,0x29,0x7e, +0x51,0x2e,0x74,0x7, 0xac,0x5b,0x2d,0x27,0x49,0x32,0x0, 0x48,0x7e,0x31,0x2f,0x74, +0x7, 0xac,0x3b,0x2e,0x15,0x25,0x49,0x11,0x0, 0x52,0xbd,0x13,0x28,0x10,0x7d,0x2, +0x2e,0x4, 0x0, 0x48,0x7d,0x13,0x2e,0x15,0x29,0x1b,0x8, 0x10,0x80,0xa, 0x2e,0x24, +0x0, 0x48,0x9e,0x35,0x29,0x1b,0x28,0x30,0x5, 0x2f,0xe5,0x30,0xbe,0xb1,0x2f,0x28, +0x3, 0x2, 0x10,0x77,0x75,0x2f,0x0, 0x7e,0x51,0x2f,0x74,0x7, 0xac,0x5b,0x7d,0x32, +0x2d,0x37,0x49,0x33,0x0, 0x46,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x2e,0x25, +0x25,0x59,0x32,0x0, 0x50,0x7e,0x51,0x2f,0x74,0x7, 0xac,0x5b,0x7d,0x32,0x2d,0x37, +0x49,0x33,0x0, 0x48,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x2e,0x25,0x25,0x59, +0x32,0x0, 0x52,0x7e,0x51,0x2f,0x74,0x7, 0xac,0x5b,0x7d,0x32,0x2d,0x37,0x9, 0x73, +0x0, 0x4a,0x2e,0x25,0x25,0x19,0x72,0x0, 0x54,0x5, 0x2f,0xe5,0x2f,0xb4,0xa, 0xa7, +0x7d,0x37,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x44,0x1, 0x7a,0x39,0xb0,0xe5,0x30, +0xbe,0xb0,0x0, 0x28,0x53,0x75,0x2f,0x0, 0x7e,0x71,0x2f,0x74,0x7, 0xac,0x7b,0x2e, +0x35,0x25,0x49,0x33,0x0, 0x50,0x12,0x5b,0x5c,0x7d,0x13,0x7e,0x71,0x2f,0x74,0x7, +0xac,0x7b,0x7d,0x23,0x2d,0x27,0x1b,0x28,0x10,0x2e,0x35,0x25,0x49,0x33,0x0, 0x52, +0x12,0x5a,0xb3,0x7e,0x51,0x2f,0x74,0x7, 0xac,0x5b,0x7d,0x12,0x2d,0x17,0x59,0x31, +0x0, 0x2, 0x7d,0x32,0x2e,0x35,0x25,0x9, 0x73,0x0, 0x54,0x2d,0x27,0x19,0x72,0x0, +0x4, 0x5, 0x2f,0xe5,0x2f,0xb4,0xa, 0xb0,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x73,0x75, +0x27,0x0, 0x75,0x2a,0x1, 0x75,0x25,0x0, 0x7e,0xa0,0xff,0x7e,0x71,0x25,0x74,0x7, +0xac,0x7b,0x2d,0x37,0x19,0xa3,0x0, 0x4, 0x7e,0xa0,0xff,0xe5,0x25,0xa, 0x3b,0x19, +0xa3,0x22,0xc0,0x7e,0x24,0xff,0xff,0x7e,0xa1,0x25,0x74,0x2, 0xa4,0x59,0x25,0x22, +0xac,0xe4,0x19,0xb3,0x22,0xca,0x5, 0x25,0xe5,0x25,0xb4,0xa, 0xcb,0x9, 0xa7,0x0, +0x82,0x4c,0xaa,0x68,0x3, 0x2, 0x13,0xd7,0x9, 0xb7,0x0, 0x83,0x70,0x3, 0x2, 0x17, +0xe6,0x75,0x25,0x0, 0x7e,0x44,0x7f,0xff,0x7e,0x71,0x25,0x74,0x2, 0xac,0x7b,0x7d, +0x23,0x2d,0x27,0x59,0x42,0x0, 0x5a,0x2d,0x37,0x59,0x43,0x0, 0x6e,0x5, 0x25,0xe5, +0x25,0xb4,0xa, 0xe0,0x2, 0x17,0xe6,0x9, 0xb7,0x0, 0x83,0x60,0x3, 0x2, 0x14,0x31, +0xf5,0x25,0x2, 0x14,0x25,0x7e,0x91,0x25,0x74,0x7, 0xac,0x9b,0x7d,0x34,0x2d,0x37, +0xb, 0x38,0x30,0x7e,0x51,0x25,0x74,0x2, 0xac,0x5b,0x7d,0x12,0x2d,0x17,0x59,0x31, +0x0, 0x5a,0x7d,0x34,0x2d,0x37,0x49,0x33,0x0, 0x2, 0x2d,0x27,0x59,0x32,0x0, 0x6e, +0xe5,0x25,0x2d,0x47,0x19,0xb4,0x0, 0x4, 0x7e,0x70,0x1, 0xe5,0x25,0xa, 0x2b,0x19, +0x72,0x22,0xca,0x5, 0x25,0x9, 0xb7,0x0, 0x82,0xbe,0xb1,0x25,0x38,0xb7,0x2, 0x17, +0xe6,0x75,0x29,0x0, 0xbe,0xa0,0x1, 0x68,0x3, 0x2, 0x14,0x48,0x75,0x2c,0x0, 0x75, +0x2b,0x1, 0x75,0x2a,0x5, 0x2, 0x15,0x2, 0xbe,0xa0,0x2, 0x68,0x3, 0x2, 0x14,0x5c, +0x75,0x2c,0x5, 0x75,0x2b,0x2, 0x75,0x2a,0x14,0x2, 0x15,0x2, 0xbe,0xa0,0x3, 0x68, +0x3, 0x2, 0x14,0x70,0x75,0x2c,0x2d,0x75,0x2b,0x3, 0x75,0x2a,0x3c,0x2, 0x15,0x2, +0xbe,0xa0,0x3, 0x38,0x3, 0x2, 0x15,0x2, 0x75,0x25,0x0, 0x2, 0x14,0xf6,0x75,0x26, +0x0, 0x7e,0x71,0x26,0x74,0x2, 0xac,0x7b,0x2d,0x37,0x49,0x23,0x0, 0x6e,0x7e,0x71, +0x25,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33,0x0, 0x2, 0x9d,0x32,0x12,0x5d,0x8a, +0x7d,0x63,0x7e,0x71,0x26,0x74,0x2, 0xac,0x7b,0x2d,0x37,0x49,0x23,0x0, 0x5a,0x7e, +0x71,0x25,0x74,0x7, 0xac,0x7b,0x2d,0x37,0xb, 0x38,0x30,0x9d,0x32,0x12,0x5d,0x8a, +0x2d,0x36,0x7a,0x37,0x22,0xaa,0x7e,0x51,0x25,0x74,0x2, 0xac,0x5b,0x49,0x32,0x22, +0xac,0xbe,0x37,0x22,0xaa,0x38,0x3, 0x2, 0x14,0xed,0x7e,0xa1,0x26,0xe5,0x25,0xa, +0x3b,0x19,0xa3,0x22,0xc0,0x7e,0x37,0x22,0xaa,0x59,0x32,0x22,0xac,0x5, 0x26,0xe5, +0x26,0xb4,0xa, 0x8d,0x5, 0x25,0x9, 0x77,0x0, 0x82,0xbe,0x71,0x25,0x28,0x3, 0x2, +0x14,0x7e,0x7e,0x1c,0xff,0xff,0x7a,0x1f,0x22,0xe0,0x75,0x28,0xff,0x9, 0x77,0x0, +0x82,0xbe,0x70,0x0, 0x38,0x3, 0x2, 0x16,0xd, 0xbe,0x70,0x4, 0x40,0x3, 0x2, 0x16, +0xd, 0x2, 0x16,0x3, 0x9f,0x11,0x7a,0x1d,0x2d,0xe5,0x29,0x7e,0x51,0x2b,0xac,0x5b, +0xe5,0x2c,0xa, 0x3b,0x2d,0x23,0x2e,0x24,0x27,0xa8,0x7e,0x34,0x22,0xd6,0xe5,0x2b, +0xa, 0x1b,0x12,0x5d,0x1b,0x75,0x25,0x0, 0x2, 0x15,0xe0,0xe5,0x25,0xa, 0x3b,0x9, +0x23,0x22,0xd6,0x7e,0x30,0x2, 0xac,0x23,0x2d,0x17,0x49,0x21,0x0, 0x5a,0xbe,0x24, +0x7f,0xff,0x68,0x3, 0x2, 0x15,0x78,0x7e,0x2d,0x2d,0x2e,0x44,0x3, 0xff,0x2e,0x28, +0xff,0xff,0x7a,0x2d,0x2d,0x2, 0x15,0xde,0x7e,0x71,0x25,0x74,0x7, 0xac,0x7b,0x2d, +0x37,0xb, 0x38,0x30,0x9d,0x32,0x12,0x5d,0x8a,0x7a,0x37,0x22,0xd4,0xe5,0x25,0xa, +0x3b,0x9, 0x63,0x22,0xd6,0x7e,0x70,0x2, 0xac,0x67,0x2d,0x37,0x49,0x23,0x0, 0x6e, +0x7e,0x71,0x25,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x49,0x33,0x0, 0x2, 0x9d,0x32,0x12, +0x5d,0x8a,0x7d,0x63,0x7e,0x37,0x22,0xd4,0x1e,0x34,0x1e,0x34,0x7a,0x37,0x22,0xd4, +0x1e,0x64,0x1e,0x64,0x7e,0x17,0x22,0xd4,0xad,0x11,0x7e,0x1d,0x2d,0x2f,0x10,0x7a, +0x1d,0x2d,0x7d,0x16,0xad,0x16,0x7e,0x1d,0x2d,0x2f,0x10,0x7a,0x1d,0x2d,0x5, 0x25, +0x9, 0x77,0x0, 0x82,0xbe,0x71,0x25,0x28,0x3, 0x2, 0x15,0x4b,0x7e,0x1d,0x2d,0x7e, +0xf, 0x22,0xe0,0xbf,0x1, 0x38,0x3, 0x2, 0x16,0x1, 0x7a,0x1f,0x22,0xe0,0x85,0x29, +0x28,0x5, 0x29,0xe5,0x2a,0xbe,0xb1,0x29,0x28,0x3, 0x2, 0x15,0x24,0xe5,0x28,0xbe, +0xb0,0xff,0x78,0x3, 0x2, 0x16,0x87,0xe5,0x28,0x7e,0x51,0x2b,0xac,0x5b,0xe5,0x2c, +0xa, 0x3b,0x2d,0x23,0x2e,0x24,0x27,0xa8,0x7e,0x34,0x22,0xd6,0x7e,0x14,0x0, 0xa, +0x12,0x5d,0x1b,0x7e,0xa0,0x1, 0x75,0x25,0x0, 0x2, 0x16,0x7b,0xe5,0x25,0xa, 0xfb, +0x9, 0x7f,0x22,0xd6,0xa, 0x27,0x19,0xa2,0x22,0xca,0x7e,0x51,0x25,0x74,0x7, 0xac, +0x5b,0x7d,0x12,0x2d,0x17,0xb, 0x18,0x10,0x7e,0x10,0x2, 0xac,0x17,0x7d,0x40,0x2d, +0x47,0x59,0x14,0x0, 0x5a,0x7d,0x12,0x2d,0x17,0x49,0x11,0x0, 0x2, 0x2d,0x7, 0x59, +0x10,0x0, 0x6e,0x2d,0x27,0x19,0x72,0x0, 0x4, 0x5, 0x25,0x9, 0xb7,0x0, 0x82,0xbe, +0xb1,0x25,0x38,0xb8,0x2, 0x17,0xb6,0x75,0x25,0x0, 0x2, 0x17,0x2f,0x75,0x27,0x1, +0x75,0x26,0x0, 0x2, 0x16,0xda,0xe5,0x26,0xbe,0xb1,0x25,0x78,0x3, 0x2, 0x16,0xd8, +0xe5,0x26,0xa, 0x3b,0x9, 0x63,0x22,0xc0,0xe5,0x25,0xa, 0x2b,0x9, 0x72,0x22,0xc0, +0xbc,0x76,0x68,0x3, 0x2, 0x16,0xd8,0x7e,0xa1,0x26,0x74,0x2, 0xa4,0x49,0x25,0x22, +0xac,0x7e,0xa1,0x25,0x74,0x2, 0xa4,0x49,0x35,0x22,0xac,0xbd,0x32,0x50,0x3, 0x2, +0x16,0xd8,0x75,0x27,0x0, 0x2, 0x16,0xe3,0x5, 0x26,0x9, 0x77,0x0, 0x82,0xbe,0x71, +0x26,0x38,0xb3,0xe5,0x27,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x17,0x2d,0x7e,0x50,0x1, +0xe5,0x25,0xa, 0x4b,0x9, 0x44,0x22,0xc0,0xa, 0x34,0x19,0x53,0x22,0xca,0x7e,0x71, +0x25,0x74,0x7, 0xac,0x7b,0x7d,0x13,0x2d,0x17,0x19,0x41,0x0, 0x4, 0x7d,0x13,0x2d, +0x17,0xb, 0x18,0x10,0x7e,0x50,0x2, 0xac,0x45,0x7d,0x2, 0x2d,0x7, 0x59,0x10,0x0, +0x5a,0x2d,0x37,0x49,0x33,0x0, 0x2, 0x2d,0x27,0x59,0x32,0x0, 0x6e,0x5, 0x25,0x9, +0x77,0x0, 0x82,0xbe,0x71,0x25,0x28,0x3, 0x2, 0x16,0x8d,0x75,0x25,0x0, 0x2, 0x17, +0xad,0x7e,0x71,0x25,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x9, 0xb3,0x0, 0x4, 0xb4,0xff, +0x2, 0x80,0x3, 0x2, 0x17,0xab,0x75,0x26,0x0, 0xe5,0x26,0xa, 0x3b,0x9, 0xb3,0x22, +0xca,0x60,0x3, 0x2, 0x17,0xa2,0x74,0x1, 0x19,0xb3,0x22,0xca,0x7e,0x71,0x25,0x74, +0x7, 0xac,0x7b,0x7d,0x23,0x2d,0x27,0xb, 0x28,0x20,0x7e,0x31,0x26,0x74,0x2, 0xac, +0x3b,0x7d,0x1, 0x2d,0x7, 0x59,0x20,0x0, 0x5a,0x7d,0x23,0x2d,0x27,0x49,0x22,0x0, +0x2, 0x2d,0x17,0x59,0x21,0x0, 0x6e,0xe5,0x26,0x2d,0x37,0x19,0xb3,0x0, 0x4, 0x2, +0x17,0xab,0x5, 0x26,0xe5,0x26,0xbe,0xb0,0xa, 0x40,0xae,0x5, 0x25,0x9, 0x77,0x0, +0x82,0xbe,0x71,0x25,0x38,0x8b,0x75,0x25,0x0, 0xe5,0x25,0xa, 0x3b,0x9, 0xb3,0x22, +0xca,0x60,0x3, 0x2, 0x17,0xdf,0x7e,0x34,0x7f,0xff,0x7e,0x51,0x25,0x74,0x2, 0xac, +0x5b,0x7d,0x12,0x2d,0x17,0x59,0x31,0x0, 0x5a,0x2d,0x27,0x59,0x32,0x0, 0x6e,0x5, +0x25,0xe5,0x25,0xb4,0xa, 0xd3,0x9, 0xb7,0x0, 0x82,0xf5,0x26,0x75,0x25,0x0, 0xe5, +0x25,0xa, 0x1b,0x9, 0xb1,0x22,0xca,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x18,0x3d,0x7d, +0x1, 0x2d,0x7, 0x9, 0xb0,0x0, 0x50,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x18,0x15,0x74, +0x3, 0x19,0xb0,0x0, 0x50,0x7d,0x1, 0x2d,0x7, 0x9, 0xa0,0x0, 0x50,0xbe,0xa0,0x3, +0x68,0x3, 0x2, 0x18,0x2d,0xe4,0x19,0xb0,0x0, 0x46,0x2, 0x18,0x76,0x4c,0xaa,0x68, +0x3, 0x2, 0x18,0x76,0x74,0x2, 0x19,0xb0,0x0, 0x46,0x2, 0x18,0x76,0x7d,0x1, 0x2d, +0x7, 0x9, 0xb0,0x0, 0x50,0xbe,0xb0,0x2, 0x78,0x3, 0x2, 0x18,0x52,0x60,0x3, 0x2, +0x18,0x70,0x74,0x1, 0x19,0xb0,0x0, 0x46,0x7e,0xa1,0x25,0x7e,0x71,0x26,0x7c,0xb7, +0x4, 0xf5,0x26,0x74,0x7, 0xac,0x7b,0x2d,0x37,0x19,0xa3,0x0, 0x4, 0x2, 0x18,0x76, +0x74,0x3, 0x19,0xb0,0x0, 0x46,0x7d,0x21,0x2d,0x27,0x9, 0x72,0x0, 0x46,0x19,0x72, +0x0, 0x50,0x5, 0x25,0xe5,0x25,0xbe,0xb0,0xa, 0x50,0x3, 0x2, 0x17,0xef,0xda,0x3b, +0x22,0xca,0x3b,0x7d,0x72,0x7d,0x63,0x6d,0x33,0x7a,0x35,0x34,0x9, 0xb7,0x0, 0x96, +0xf5,0x2a,0x75,0x32,0x0, 0x6c,0xaa,0x7e,0x71,0x32,0x74,0x2, 0xac,0x7b,0x19,0xa3, +0x22,0xd2,0xe4,0x19,0xb3,0x22,0xd3,0x6c,0xaa,0xe5,0x32,0xa, 0x3b,0x19,0xa3,0x22, +0xaa,0x5, 0x32,0xe5,0x32,0xb4,0x28,0xdd,0xe5,0x2a,0xbe,0xb0,0x2, 0x50,0x3, 0x2, +0x1c,0xbb,0x75,0x31,0x0, 0x2, 0x1b,0x8e,0xe5,0x31,0x60,0xa, 0xe5,0x31,0xa, 0x3b, +0x9, 0xb3,0x22,0xaa,0x70,0x10,0xe5,0x31,0xa, 0x5b,0xb, 0x54,0x7c,0xab,0xe5,0x31, +0xa, 0x3b,0x19,0xa3,0x22,0xaa,0xe5,0x2a,0x14,0xbe,0xb1,0x31,0x78,0x3, 0x2, 0x1b, +0x98,0x7e,0x71,0x31,0x74,0x2, 0xac,0x7b,0x2d,0x37,0x7e,0x39,0x50,0x1e,0x50,0xa, +0x25,0x7a,0x25,0x24,0x9, 0x73,0x0, 0x1, 0x1e,0x70,0xa, 0x37,0x7a,0x35,0x22,0xe5, +0x31,0xa, 0x5b,0xb, 0x54,0xf5,0x32,0x2, 0x1b,0x82,0x75,0x37,0x0, 0x7e,0x51,0x32, +0x74,0x2, 0xac,0x5b,0x2d,0x27,0x7e,0x29,0x70,0x1e,0x70,0xa, 0x37,0x7a,0x35,0x28, +0x9, 0x52,0x0, 0x1, 0x1e,0x50,0xa, 0x55,0x7a,0x55,0x26,0x3e,0x54,0x7e,0x44,0x0, +0x48,0xad,0x34,0x7d,0x23,0x2d,0x25,0x2d,0x26,0x49,0x2, 0xd, 0x80,0x7e,0x35,0x22, +0x3e,0x34,0x7e,0x55,0x24,0xad,0x54,0x2d,0x35,0x2d,0x36,0x49,0x13,0xd, 0x80,0xbd, +0x10,0x48,0x15,0x7e,0x14,0x0, 0xc, 0xad,0x10,0x7d,0x21,0xe, 0x24,0xe, 0x24,0xe, +0x24,0xe, 0x24,0x7a,0x25,0x38,0x80,0x15,0x49,0x23,0xd, 0x80,0x7e,0x34,0x0, 0xc, +0xad,0x32,0xe, 0x34,0xe, 0x34,0xe, 0x34,0xe, 0x34,0x7a,0x35,0x38,0x7e,0x35,0x22, +0x9e,0x35,0x26,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x1, 0x18,0x12,0x7e,0x35,0x24,0x9e, +0x35,0x28,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x1, 0x18,0x3, 0x2, 0x1b,0xa, 0x7e,0x35, +0x22,0x9e,0x35,0x26,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x4, 0x8, 0x3, 0x2, 0x1b,0xd, +0x7e,0x35,0x24,0x9e,0x35,0x28,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x4, 0x8, 0x3, 0x2, +0x1b,0xd, 0x7e,0x35,0x26,0xbe,0x35,0x22,0x8, 0xb, 0x7e,0x55,0x22,0xf5,0x2b,0x7c, +0xb7,0xf5,0x2d,0x80,0x9, 0x7c,0xb7,0xf5,0x2b,0x7e,0x55,0x22,0xf5,0x2d,0x7e,0x35, +0x28,0xbe,0x35,0x24,0x8, 0xb, 0x7e,0x55,0x24,0xf5,0x2c,0x7c,0xb7,0xf5,0x2e,0x80, +0x9, 0x7c,0xb7,0xf5,0x2c,0x7e,0x55,0x24,0xf5,0x2e,0x7e,0xa1,0x2e,0x9e,0xa1,0x2c, +0xe5,0x2d,0x9e,0xb1,0x2b,0xbc,0xba,0x78,0x6, 0x5, 0x2c,0x15,0x2e,0x80,0x1e,0xe5, +0x2c,0xa, 0x3b,0xe5,0x2e,0xa, 0x2b,0x9d,0x23,0xe5,0x2b,0xa, 0x1b,0xe5,0x2d,0xa, +0x3b,0x9d,0x31,0xbd,0x32,0x50,0x6, 0x5, 0x2c,0x15,0x2e,0x80,0x4, 0x5, 0x2b,0x15, +0x2d,0x75,0x21,0x0, 0x75,0x3a,0x0, 0x75,0x3b,0x0, 0x85,0x2c,0x2f,0x80,0x50,0x85, +0x2b,0x30,0x80,0x42,0x7e,0x51,0x2f,0x74,0x48,0xac,0x5b,0x7e,0x71,0x30,0x74,0x2, +0xac,0x7b,0x2d,0x32,0x2d,0x36,0x49,0x33,0xd, 0x80,0xbe,0x35,0x38,0x58,0x25,0x75, +0x21,0x1, 0x5, 0x3b,0x7e,0x35,0x22,0x9e,0x35,0x26,0x12,0x5d,0x8a,0xbe,0x34,0x0, +0x4, 0x78,0x11,0x7e,0x35,0x24,0x9e,0x35,0x28,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x4, +0x78,0x2, 0x5, 0x3a,0x5, 0x30,0xe5,0x2d,0xbe,0xb1,0x30,0x50,0xb7,0x5, 0x2f,0xe5, +0x2e,0xbe,0xb1,0x2f,0x50,0xa9,0xe5,0x3a,0xbe,0xb0,0x4, 0x40,0x3, 0x75,0x21,0x1, +0x7e,0x35,0x22,0x9e,0x35,0x26,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x2, 0x78,0xf, 0x7e, +0x35,0x24,0x9e,0x35,0x28,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x3, 0x68,0x1e,0x7e,0x35, +0x22,0x9e,0x35,0x26,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x3, 0x78,0x19,0x7e,0x35,0x24, +0x9e,0x35,0x28,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x2, 0x78,0xa, 0xe5,0x3b,0xbe,0xb0, +0x2, 0x50,0x3, 0x75,0x21,0x0, 0xe5,0x21,0x70,0x3, 0x75,0x37,0x1, 0xe5,0x37,0xb4, +0x1, 0x2, 0x80,0x3, 0x2, 0x1b,0x80,0xe5,0x32,0xa, 0x3b,0x9, 0xa3,0x22,0xaa,0x4c, +0xaa,0x78,0xe, 0xe5,0x31,0xa, 0x2b,0x9, 0xb2,0x22,0xaa,0x19,0xb3,0x22,0xaa,0x80, +0x4f,0xe5,0x31,0xa, 0x2b,0x9, 0xb2,0x22,0xaa,0xf5,0x21,0xbc,0xba,0x38,0x3, 0x7a, +0xa1,0x21,0x75,0x33,0x0, 0x80,0x32,0x9, 0x33,0x22,0xaa,0x9, 0xa2,0x22,0xaa,0xbc, +0xa3,0x28,0x13,0xe5,0x33,0xa, 0xb, 0x9, 0x20,0x22,0xaa,0xbe,0x21,0x21,0x78,0x17, +0x19,0x30,0x22,0xaa,0x80,0x11,0xe5,0x33,0xa, 0x1b,0x9, 0xb1,0x22,0xaa,0xbe,0xb1, +0x21,0x78,0x4, 0x19,0xa1,0x22,0xaa,0x5, 0x33,0xe5,0x2a,0xbe,0xb1,0x33,0x38,0xc7, +0x5, 0x32,0xe5,0x2a,0xbe,0xb1,0x32,0x28,0x3, 0x2, 0x19,0x2a,0x5, 0x31,0xe5,0x2a, +0xbe,0xb1,0x31,0x28,0x3, 0x2, 0x18,0xd8,0x75,0x21,0x0, 0x75,0x33,0x1, 0x80,0x19, +0xe5,0x21,0xa, 0x3b,0x9, 0x63,0x22,0xaa,0xe5,0x33,0xa, 0x2b,0x9, 0x72,0x22,0xaa, +0xbc,0x76,0x40,0x3, 0x85,0x33,0x21,0x5, 0x33,0xe5,0x2a,0xbe,0xb1,0x33,0x38,0xe0, +0xe5,0x21,0xa, 0x3b,0x9, 0xb3,0x22,0xaa,0xf5,0x21,0x75,0x36,0x0, 0x6d,0x33,0x7a, +0x35,0x34,0x7a,0x35,0x38,0x7a,0x35,0x26,0x7a,0x35,0x28,0x75,0x33,0x1, 0x2, 0x1c, +0x7e,0x75,0x31,0x0, 0x80,0x5d,0x7e,0x71,0x31,0x74,0x2, 0xac,0x7b,0x2d,0x37,0x7e, +0x39,0x50,0x1e,0x50,0xa, 0x25,0x7a,0x25,0x24,0x9, 0x73,0x0, 0x1, 0x1e,0x70,0xa, +0x37,0x7a,0x35,0x22,0xe5,0x31,0xa, 0x3b,0x9, 0x73,0x22,0xaa,0xbe,0x71,0x33,0x78, +0x30,0x7e,0x35,0x34,0xb, 0x34,0x7a,0x35,0x34,0x7e,0x25,0x22,0x7d,0x52,0x3e,0x54, +0x7e,0x35,0x24,0x7e,0x14,0x0, 0x48,0xad,0x13,0x7d,0x1, 0x2d,0x5, 0x2d,0x6, 0x49, +0x10,0xd, 0x80,0xbe,0x15,0x38,0x48,0x9, 0x7a,0x15,0x38,0x7a,0x25,0x26,0x7a,0x35, +0x28,0x5, 0x31,0xe5,0x2a,0xbe,0xb1,0x31,0x38,0x9c,0x7e,0x35,0x34,0xbe,0x34,0x0, +0x1, 0x40,0x29,0x7e,0x35,0x28,0x3e,0x34,0x7e,0x61,0x36,0x74,0x2, 0xac,0xb6,0x19, +0x75,0x22,0xd2,0x7e,0x35,0x26,0x3e,0x34,0x19,0x75,0x22,0xd3,0x5, 0x36,0x6d,0x33, +0x7a,0x35,0x34,0x7a,0x35,0x38,0x7a,0x35,0x26,0x7a,0x35,0x28,0x5, 0x33,0xe5,0x21, +0xbe,0xb1,0x33,0x40,0x3, 0x2, 0x1b,0xe1,0x75,0x32,0x0, 0x80,0x1e,0x7e,0x51,0x32, +0x74,0x2, 0xac,0x5b,0x9, 0x32,0x22,0xd2,0x7d,0x32,0x2d,0x37,0x7a,0x39,0x30,0x9, +0x72,0x22,0xd3,0x2d,0x27,0x19,0x72,0x0, 0x1, 0x5, 0x32,0xe5,0x36,0xbe,0xb1,0x32, +0x38,0xdb,0x85,0x36,0x2a,0xe5,0x2a,0x19,0xb7,0x0, 0x96,0xda,0x3b,0x22,0xca,0x3b, +0x7c,0xcb,0xbe,0xb0,0x50,0x40,0x3, 0x2, 0x1e,0xca,0x7e,0xa0,0x3, 0xa4,0x90,0x1c, +0xd2,0x73,0x2, 0x1d,0xc2,0x2, 0x1e,0x1e,0x2, 0x1e,0x31,0x2, 0x1e,0x54,0x2, 0x1e, +0x5b,0x2, 0x1e,0x62,0x2, 0x1e,0x69,0x2, 0x1e,0x70,0x2, 0x1e,0x77,0x2, 0x1e,0x7e, +0x2, 0x1e,0x85,0x2, 0x1e,0x8c,0x2, 0x1e,0x93,0x2, 0x1e,0x9a,0x2, 0x1e,0xa1,0x2, +0x1e,0xab,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e, +0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca, +0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, +0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e, +0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca, +0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, +0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e, +0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca, +0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, +0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e, +0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xca, +0x2, 0x1e,0xca,0x2, 0x1e,0xca,0x2, 0x1e,0xb6,0x2, 0x1e,0xca,0x2, 0x1e,0xbd,0x2, +0x1e,0xc4,0x7e,0x74,0x29,0x15,0x7a,0x79,0x70,0x5e,0x70,0x70,0x7c,0xb7,0xc4,0x54, +0xf, 0x7c,0x7b,0x4c,0x77,0x78,0x3, 0x2, 0x1d,0xe3,0xa5,0xbf,0x1, 0x2, 0x80,0x3, +0x2, 0x1d,0xff,0x7e,0xb3,0x29,0xef,0xb4,0x3, 0x2, 0x80,0x3, 0x2, 0x1d,0xf7,0x74, +0x1, 0x7e,0x70,0x1, 0x2, 0x1e,0x4e,0x74,0x27,0x7e,0x70,0x1, 0x2, 0x1e,0x18,0x7e, +0xb3,0x29,0xef,0xb4,0x3, 0x2, 0x80,0x3, 0x2, 0x1e,0x13,0x74,0x1, 0x7e,0x70,0x3, +0x2, 0x1e,0x4e,0x74,0x27,0x7e,0x70,0x3, 0x12,0x59,0xba,0x2, 0x1f,0xa2,0x7a,0x73, +0x29,0x12,0x74,0x48,0xac,0x7b,0x2e,0x37,0x29,0x1b,0x7a,0x37,0x29,0x10,0x2, 0x1f, +0xa2,0xa5,0xbf,0x4, 0x2, 0x80,0x3, 0x2, 0x1e,0x42,0x74,0x1, 0x7e,0x70,0x4, 0x2, +0x1e,0x4e,0xa5,0xbf,0x5, 0x2, 0x80,0x3, 0x2, 0x1f,0xa2,0xe4,0x6c,0x77,0x12,0x56, +0xf9,0x2, 0x1f,0xa2,0x7a,0x73,0x23,0x83,0x2, 0x1f,0xa2,0x7a,0x73,0x23,0x84,0x2, +0x1f,0xa2,0x7a,0x73,0x23,0x85,0x2, 0x1f,0xa2,0x7a,0x73,0x23,0x86,0x2, 0x1f,0xa2, +0x7a,0x73,0x23,0x87,0x2, 0x1f,0xa2,0x7e,0x74,0x23,0x88,0x2, 0x1e,0xa5,0x7e,0x74, +0x23,0x88,0x2, 0x1e,0xaf,0x7e,0x74,0x23,0x8a,0x2, 0x1e,0xa5,0x7e,0x74,0x23,0x8a, +0x2, 0x1e,0xaf,0x7e,0x74,0x23,0x8c,0x2, 0x1e,0xa5,0x7e,0x74,0x23,0x8c,0x2, 0x1e, +0xaf,0x7e,0x74,0x23,0x8e,0x7a,0x79,0x70,0x2, 0x1f,0xa2,0x7e,0x74,0x23,0x8e,0x19, +0x77,0x0, 0x1, 0x2, 0x1f,0xa2,0x7a,0x73,0x23,0x90,0x2, 0x1f,0xa2,0x7a,0x73,0x24, +0x6f,0x2, 0x1f,0xa2,0x12,0x5c,0x8d,0x2, 0x1f,0xa2,0x7e,0xb3,0x29,0x15,0xc4,0x54, +0xf, 0x7c,0x6b,0x5e,0x60,0x7, 0xa5,0xbe,0x4, 0x2, 0x80,0x3, 0x2, 0x1e,0xe4,0x6c, +0xdd,0x2, 0x1e,0xff,0xa5,0xbe,0x6, 0x2, 0x80,0x3, 0x2, 0x1e,0xf3,0x7e,0xd0,0x1, +0x2, 0x1e,0xff,0xa5,0xbe,0x7, 0x2, 0x80,0x3, 0x2, 0x1e,0xff,0x7e,0xd0,0x2, 0xbe, +0xc0,0x50,0x50,0x3, 0x2, 0x1f,0x29,0xbe,0xc0,0x63,0x28,0x3, 0x2, 0x1f,0x29,0x7c, +0xb7,0x7e,0x70,0x8a,0x12,0x57,0x87,0x7c,0xab,0x7e,0x50,0x14,0xac,0x5d,0xa, 0x3c, +0x2d,0x32,0x19,0xa3,0x23,0x43,0x2, 0x1f,0xa2,0xbe,0xc0,0x78,0x50,0x3, 0x2, 0x1f, +0x48,0xbe,0xc0,0x8b,0x28,0x3, 0x2, 0x1f,0x48,0x74,0x14,0xac,0xbd,0xa, 0x2c,0x2d, +0x25,0x19,0x72,0x23,0x4b,0x2, 0x1f,0xa2,0xbe,0xc0,0xa0,0x50,0x3, 0x2, 0x1f,0x67, +0xbe,0xc0,0xb3,0x28,0x3, 0x2, 0x1f,0x67,0x74,0x14,0xac,0xbd,0xa, 0x2c,0x2d,0x25, +0x19,0x72,0x23,0x53,0x2, 0x1f,0xa2,0xbe,0xc0,0xbf,0x50,0x3, 0x2, 0x1f,0x86,0xbe, +0xc0,0xd2,0x28,0x3, 0x2, 0x1f,0x86,0x74,0x14,0xac,0xbd,0xa, 0x2c,0x2d,0x25,0x19, +0x72,0x23,0x58,0x2, 0x1f,0xa2,0xbe,0xc0,0xd3,0x50,0x3, 0x2, 0x1f,0xa2,0xbe,0xc0, +0xe6,0x28,0x3, 0x2, 0x1f,0xa2,0x74,0x14,0xac,0xbd,0xa, 0x2c,0x2d,0x25,0x19,0x72, +0x23,0x74,0xda,0x3b,0x22,0x7e,0x34,0x2, 0x21,0x7e,0x24,0x20,0xbe,0x7e,0x14,0x22, +0x9d,0x12,0x41,0x33,0x7e,0x34,0x0, 0x3c,0x12,0x45,0xa2,0x7e,0x34,0x0, 0xf2,0x7e, +0x24,0x1, 0x8b,0x12,0x52,0x33,0x7e,0x34,0x22,0x17,0x12,0x58,0xce,0xe4,0x7a,0xb3, +0x0, 0x1b,0x53,0xdb,0xf0,0x7e,0x34,0x2, 0x37,0x12,0x43,0x79,0x74,0x21,0x7a,0xb3, +0x0, 0xcc,0x7e,0x34,0x20,0xc9,0x12,0x3a,0xe8,0x7e,0x34,0x20,0xc9,0x12,0x2b,0xb3, +0x12,0x5e,0x4a,0x12,0x5d,0xdf,0x7e,0x34,0x5, 0xdc,0x7a,0x37,0x24,0x70,0x7e,0x34, +0x23,0x83,0x7e,0x24,0x0, 0x3c,0x7e,0x14,0x2, 0x9f,0x7e,0x4, 0x2, 0x37,0x12,0x29, +0x89,0x7e,0x34,0x2, 0x9f,0x12,0x5a,0xd6,0x7e,0x34,0x2, 0x9f,0x12,0x56,0xb0,0x53, +0xea,0xf8,0x43,0xea,0x5, 0x7e,0x34,0x2, 0x21,0x12,0x49,0x62,0x7e,0x34,0x22,0xa3, +0x12,0x5a,0xf8,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x0, 0x64,0x7a,0x37,0x23, +0x68,0x7e,0x34,0x0, 0x3c,0x7e,0x24,0x2, 0x9f,0x12,0x50,0x26,0x74,0x1, 0x7a,0xb3, +0x0, 0xca,0x7e,0x73,0x24,0x6f,0x7a,0x73,0x0, 0xcb,0x74,0x1, 0x7a,0xb3,0x29,0xef, +0x7e,0xb3,0x29,0xef,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x22,0x50,0x53,0xdb,0x7f,0x6d, +0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x0, 0x64,0x7a,0x37,0x23,0x68,0x7e,0x34,0x2, +0x21,0x7e,0x24,0x20,0xbe,0x7e,0x14,0x22,0x9d,0x12,0x46,0xa8,0x75,0xb, 0x0, 0x75, +0xa, 0x0, 0x7e,0xb3,0x29,0xed,0x60,0x3, 0x2, 0x20,0xa4,0x7e,0xb3,0x20,0xc2,0xf5, +0xc, 0x2, 0x20,0xaa,0x7e,0xb3,0x20,0xc4,0xf5,0xc, 0x7e,0xb3,0x29,0xe8,0xbe,0xb0, +0xff,0x78,0x3, 0x2, 0x20,0xcf,0x7e,0x34,0x0, 0x3c,0x7e,0x24,0x2, 0x37,0x7e,0x14, +0x2, 0x9f,0x7e,0x4, 0x20,0xc9,0x12,0x55,0xc5,0x74,0xff,0x7a,0xb3,0x29,0xe8,0x12, +0x5e,0x16,0x60,0xfb,0x12,0x5d,0xdf,0x7e,0x34,0x0, 0x3c,0x7e,0x24,0x2, 0x9f,0x12, +0x4d,0x35,0x7e,0xb3,0x20,0xc8,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x20,0xf2,0xe4,0x12, +0x5e,0x33,0x12,0x0, 0x1e,0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x0, 0x3c,0x7e,0x14,0x2, +0x21,0x7e,0x4, 0x0, 0xf2,0x12,0x8, 0x0, 0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x0, 0xf2, +0x7e,0x14,0x22,0xa3,0x12,0x51,0x32,0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x0, 0x3c,0x7e, +0x14,0x0, 0xf2,0x7e,0x4, 0x22,0xa3,0x12,0x24,0xe1,0x7e,0x34,0x2, 0x9f,0x7e,0x24, +0x0, 0xf2,0x12,0x18,0x91,0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x0, 0xf2,0x12,0x27,0x53, +0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x0, 0xf2,0x12,0x33,0xa3,0x7a,0xb3,0x2, 0x20,0x7e, +0x34,0x2, 0x9f,0x7e,0x24,0x0, 0x3c,0x7e,0x14,0x2, 0x21,0x7e,0x4, 0x0, 0xf2,0x12, +0x0, 0x66,0x7e,0x34,0x0, 0xf2,0x7e,0x24,0x1, 0x8b,0x7e,0x14,0x22,0x9d,0x7e,0x4, +0x22,0x17,0x12,0x55,0x6e,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x0, 0x64,0x7a, +0x37,0x23,0x68,0x7e,0x34,0x2, 0x9f,0x12,0x44,0x98,0x7e,0x73,0x2, 0x19,0xbe,0x70, +0x0, 0x38,0x3, 0x2, 0x21,0xa5,0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x24,0x72,0x7e,0x14, +0x0, 0xf2,0x12,0x3c,0x31,0x7e,0x34,0x2, 0x9f,0x7e,0x24,0x24,0x72,0x7e,0x14,0x26, +0xf2,0x12,0x3e,0xbb,0x7e,0x34,0x2, 0x9f,0x12,0x57,0x40,0x7e,0x34,0x0, 0xf2,0x7e, +0x24,0x0, 0x3c,0x7e,0x14,0x2, 0x9f,0x12,0x56,0x18,0x7e,0x34,0x26,0xf2,0x12,0x59, +0xc, 0xbe,0x34,0x0, 0x1, 0x68,0x3, 0x2, 0x21,0xe9,0x7e,0x34,0x0, 0x3c,0x7e,0x24, +0x2, 0x9f,0x7e,0xb3,0x2, 0x19,0x12,0x53,0xee,0x7e,0x34,0x0, 0xf2,0x12,0x5b,0xfe, +0xe5,0x8, 0xb4,0x5, 0x2, 0x80,0x3, 0x2, 0x22,0x16,0x7e,0x37,0x2a,0xe, 0xbe,0x34, +0x0, 0x1, 0x68,0x3, 0x2, 0x22,0x16,0x7e,0x34,0x0, 0xf2,0x7e,0x24,0x0, 0x3c,0x7e, +0x14,0x2, 0x9f,0x12,0x42,0x57,0x7e,0x34,0x1, 0x8b,0x7e,0x24,0x22,0x9d,0x12,0x31, +0xc4,0x7e,0xb3,0x2, 0x1d,0x54,0xef,0x7a,0xb3,0x2, 0x1d,0x7e,0x73,0x2, 0x19,0x7a, +0x73,0x2, 0x1a,0x7e,0x34,0x0, 0xf2,0x7a,0x35,0x25,0x7e,0x34,0x1, 0x8b,0x7e,0x24, +0x20,0xbe,0x7e,0x14,0x0, 0x3c,0x7e,0x4, 0x2, 0x9f,0x12,0x35,0x4b,0x2, 0x20,0x60, +0x12,0x5e,0x16,0x60,0xfb,0x2, 0x0, 0x61,0xca,0xd8,0xca,0x79,0x7c,0x7b,0xbe,0xb0, +0x4f,0x40,0x3, 0x2, 0x23,0xde,0x7e,0xa0,0x3, 0xa4,0x90,0x22,0x6e,0x73,0x2, 0x23, +0x5b,0x2, 0x23,0x62,0x2, 0x23,0x69,0x2, 0x23,0x6e,0x2, 0x23,0x75,0x2, 0x23,0x7c, +0x2, 0x23,0x83,0x2, 0x23,0x8a,0x2, 0x23,0x91,0x2, 0x23,0x98,0x2, 0x23,0x9f,0x2, +0x23,0xa6,0x2, 0x23,0xad,0x2, 0x23,0xb4,0x2, 0x23,0xbb,0x2, 0x23,0xc5,0x2, 0x23, +0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde, +0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, +0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23, +0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde, +0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, +0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23, +0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde, +0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, +0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23, +0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde, +0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, 0x23,0xde,0x2, +0x23,0xde,0x2, 0x23,0xd0,0x2, 0x23,0xde,0x2, 0x23,0xd7,0x7e,0xb3,0x29,0x15,0x2, +0x24,0xdc,0x7e,0xb3,0x29,0x12,0x2, 0x24,0xdc,0x74,0xff,0x2, 0x24,0xdc,0x7e,0xb3, +0x23,0x83,0x2, 0x24,0xdc,0x7e,0xb3,0x23,0x84,0x2, 0x24,0xdc,0x7e,0xb3,0x23,0x85, +0x2, 0x24,0xdc,0x7e,0xb3,0x23,0x86,0x2, 0x24,0xdc,0x7e,0xb3,0x23,0x87,0x2, 0x24, +0xdc,0x7e,0x74,0x23,0x88,0x2, 0x23,0xbf,0x7e,0x74,0x23,0x88,0x2, 0x23,0xc9,0x7e, +0x74,0x23,0x8a,0x2, 0x23,0xbf,0x7e,0x74,0x23,0x8a,0x2, 0x23,0xc9,0x7e,0x74,0x23, +0x8c,0x2, 0x23,0xbf,0x7e,0x74,0x23,0x8c,0x2, 0x23,0xc9,0x7e,0x74,0x23,0x8e,0x7e, +0x79,0xb0,0x2, 0x24,0xdc,0x7e,0x74,0x23,0x8e,0x9, 0xb7,0x0, 0x1, 0x2, 0x24,0xdc, +0x7e,0xb3,0x23,0x90,0x2, 0x24,0xdc,0x7e,0xb3,0x24,0x6f,0x2, 0x24,0xdc,0x7e,0xb3, +0x29,0x15,0xc4,0x54,0xf, 0x7c,0x6b,0x5e,0x60,0x7, 0xa5,0xbe,0x4, 0x2, 0x80,0x3, +0x2, 0x23,0xf8,0x6c,0xdd,0x2, 0x24,0x13,0xa5,0xbe,0x6, 0x2, 0x80,0x3, 0x2, 0x24, +0x7, 0x7e,0xd0,0x1, 0x2, 0x24,0x13,0xa5,0xbe,0x7, 0x2, 0x80,0x3, 0x2, 0x24,0x13, +0x7e,0xd0,0x2, 0xbe,0x70,0x10,0x50,0x3, 0x2, 0x24,0x39,0xbe,0x70,0x38,0x28,0x3, +0x2, 0x24,0x39,0x74,0x28,0xac,0xbd,0xa, 0x37,0x2e,0x37,0x29,0x10,0x9e,0x34,0x0, +0x10,0x2d,0x35,0x7e,0x39,0xb0,0x2, 0x24,0xdc,0xbe,0x70,0x50,0x50,0x3, 0x2, 0x24, +0x5e,0xbe,0x70,0x63,0x28,0x3, 0x2, 0x24,0x5e,0x74,0x14,0xac,0xbd,0xa, 0x37,0x2d, +0x35,0x9, 0xb3,0x23,0x43,0x7e,0x70,0x8a,0x12,0x57,0xca,0x2, 0x24,0xdc,0xbe,0x70, +0x78,0x50,0x3, 0x2, 0x24,0x7d,0xbe,0x70,0x8b,0x28,0x3, 0x2, 0x24,0x7d,0x74,0x14, +0xac,0xbd,0xa, 0x37,0x2d,0x35,0x9, 0xb3,0x23,0x4b,0x2, 0x24,0xdc,0xbe,0x70,0xa0, +0x50,0x3, 0x2, 0x24,0x9c,0xbe,0x70,0xb3,0x28,0x3, 0x2, 0x24,0x9c,0x74,0x14,0xac, +0xbd,0xa, 0x37,0x2d,0x35,0x9, 0xb3,0x23,0x53,0x2, 0x24,0xdc,0xbe,0x70,0xbf,0x50, +0x3, 0x2, 0x24,0xbb,0xbe,0x70,0xd2,0x28,0x3, 0x2, 0x24,0xbb,0x74,0x14,0xac,0xbd, +0xa, 0x37,0x2d,0x35,0x9, 0xb3,0x23,0x58,0x2, 0x24,0xdc,0xbe,0x70,0xd3,0x50,0x3, +0x2, 0x24,0xda,0xbe,0x70,0xe6,0x28,0x3, 0x2, 0x24,0xda,0x74,0x14,0xac,0xbd,0xa, +0x37,0x2d,0x35,0x9, 0xb3,0x23,0x74,0x2, 0x24,0xdc,0x74,0xff,0xda,0x79,0xda,0xd8, +0x22,0xca,0x79,0x7d,0xf0,0x7d,0x41,0x7d,0x2, 0x7d,0xe3,0x75,0x25,0x0, 0x7e,0x9, +0xb0,0xf5,0x21,0x9, 0xb0,0x0, 0x1, 0xf5,0x22,0x7d,0xe, 0x2e,0x4, 0xd, 0x80,0x9, +0x44,0x0, 0x96,0x7a,0x41,0x24,0xbe,0x40,0x1, 0x38,0x9, 0x6d,0x0, 0x7a,0x7, 0x0, +0x17,0x2, 0x27,0x50,0x7e,0xd7,0x0, 0x17,0xbe,0xd4,0x0, 0x0, 0x28,0x3, 0x75,0x25, +0x1, 0x6d,0xdd,0x7e,0xf1,0x24,0x74,0x8, 0xac,0xfb,0x7c,0xbf,0xf5,0x23,0x9, 0x4f, +0x0, 0x6, 0xbe,0x41,0x24,0x28,0x6, 0x74,0x8, 0xac,0xb4,0xf5,0x23,0x6c,0xaa,0x80, +0x53,0x7e,0xf0,0x24,0xac,0xfa,0x7d,0xc7,0x6c,0x66,0x80,0x40,0xa, 0xb6,0x2d,0xbc, +0x3e,0xb4,0x2d,0xb0,0xb, 0xb8,0xb0,0xbe,0xb4,0x0, 0x0, 0x48,0x2d,0x90,0x48,0xb8, +0xe4,0x93,0xa, 0xab,0xbd,0xab,0x50,0x22,0x90,0x48,0xb9,0xe4,0x93,0xa, 0xab,0xbd, +0xab,0x28,0x17,0xb, 0xd4,0xe5,0x23,0xa, 0xab,0xbd,0xad,0x50,0xd, 0x7e,0xa4,0x2, +0x58,0x7a,0xa7,0x0, 0x17,0x75,0x25,0x1, 0x80,0x8, 0xb, 0x60,0xe5,0x22,0xbc,0xb6, +0x38,0xba,0xb, 0xa0,0xe5,0x21,0xbc,0xba,0x38,0xa7,0xe5,0x24,0xbe,0xb0,0x1, 0x38, +0x3, 0x2, 0x27,0x50,0xe5,0x25,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x27,0x50,0x6c,0x77, +0x6c,0xaa,0x2, 0x26,0xb7,0x7e,0x10,0x2, 0xac,0x1a,0x2d,0x4, 0x7e,0x9, 0x40,0x1e, +0x40,0x7a,0x41,0x3a,0x9, 0x50,0x0, 0x1, 0x1e,0x50,0x7e,0xf0,0x48,0xac,0xf4,0x7e, +0x10,0x2, 0xac,0x15,0x7d,0xd0,0x2d,0xd7,0x2d,0xde,0x49,0xd, 0xd, 0x80,0xbe,0x4, +0x0, 0x0, 0x8, 0x4, 0x7d,0x10,0x80,0x2, 0x6d,0x11,0x6d,0xdd,0xe5,0x3a,0xbe,0xb0, +0x0, 0x38,0x3, 0x2, 0x26,0x8a,0xe5,0x21,0xa, 0xb, 0x1b,0x4, 0xe5,0x3a,0xa, 0xcb, +0xbd,0xc0,0x48,0x3, 0x2, 0x26,0x8a,0xbe,0x50,0x0, 0x38,0x3, 0x2, 0x26,0x8a,0xe5, +0x22,0xa, 0xb, 0x1b,0x4, 0xa, 0xb5,0xbd,0xb0,0x48,0x3, 0x2, 0x26,0x8a,0xe5,0x3a, +0xa, 0xb, 0x1b,0x4, 0x7c,0x61,0x80,0x3c,0xa, 0x5, 0x1b,0x4, 0x7c,0x41,0x80,0x28, +0xe5,0x3a,0xbc,0xb6,0x78,0x4, 0xbc,0x54,0x68,0x1c,0x7e,0xf0,0x48,0xac,0xf6,0x7e, +0x10,0x2, 0xac,0x14,0x7d,0xa0,0x2d,0xa7,0x2d,0xae,0x49,0xa, 0xd, 0x80,0xbe,0x4, +0x0, 0x0, 0x8, 0x2, 0x2d,0xd0,0xb, 0x40,0x7d,0xab,0xb, 0xa4,0xa, 0x4, 0xbd,0xa, +0x8, 0xce,0xb, 0x60,0x7d,0xac,0xb, 0xa4,0xa, 0x6, 0xbd,0xa, 0x8, 0xba,0x9, 0x4f, +0x0, 0x3, 0xa, 0x94,0xad,0x91,0xbd,0x9d,0x28,0x3b,0x7e,0x7, 0x0, 0x15,0xbe,0x4, +0x0, 0x0, 0x28,0x31,0xbd,0x1, 0x38,0x2d,0x80,0x0, 0x7e,0x10,0x2, 0xac,0x1a,0x2d, +0x4, 0x7e,0x9, 0xb0,0x7c,0x17,0x3e,0x10,0x7c,0x1, 0x2e,0x0, 0x26,0xa5,0xf6,0x7e, +0xf0,0x2, 0xac,0xfa,0x7d,0xa7,0x2d,0xa4,0x9, 0x4a,0x0, 0x1, 0x2e,0x10,0x27,0x7c, +0xb4,0xa5,0xf7,0xb, 0x70,0xb, 0xa0,0xe5,0x24,0xbc,0xba,0x28,0x3, 0x2, 0x25,0xb5, +0xa5,0xbf,0x0, 0x58,0x6c,0xaa,0x80,0x4e,0x7e,0x50,0x2, 0xac,0x5a,0x7d,0xd2,0x2d, +0xd4,0x7e,0xd9,0x40,0x1e,0x40,0x7a,0x41,0x3a,0x9, 0x5d,0x0, 0x1, 0x1e,0x50,0x7e, +0xf0,0x48,0xac,0xf4,0x7e,0x10,0x2, 0xac,0x15,0x2d,0x7, 0x2d,0xe, 0x49,0xc0,0xd, +0x80,0x49,0xf, 0x0, 0x4, 0xbd,0xc0,0x28,0x1b,0x7e,0xd9,0xb0,0x7c,0x17,0x3e,0x10, +0x7c,0x1, 0x2e,0x0, 0x26,0xa5,0xf6,0x9, 0x4d,0x0, 0x1, 0x2e,0x10,0x27,0x7c,0xb4, +0xa5,0xf7,0xb, 0x70,0xb, 0xa0,0xe5,0x24,0xbc,0xba,0x38,0xac,0x6c,0xaa,0x80,0x28, +0x7c,0x1a,0x3e,0x10,0x7c,0x1, 0x2e,0x0, 0x26,0xa5,0xe6,0x7c,0x4b,0x7e,0xf0,0x2, +0xac,0xfa,0x7d,0xf7,0x2d,0xf4,0x7a,0xf9,0x40,0x2e,0x10,0x27,0xa5,0xe7,0x7d,0x7, +0x2d,0x4, 0x19,0xb0,0x0, 0x1, 0xb, 0xa0,0xbc,0x7a,0x38,0xd4,0x19,0x74,0x0, 0x96, +0xda,0x79,0x22,0xca,0x3b,0x7d,0x72,0x6d,0x22,0x7a,0x27,0x22,0xaa,0x75,0x25,0x0, +0x75,0x26,0x0, 0x9, 0xb7,0x0, 0x96,0xf5,0x23,0x2e,0x34,0xd, 0x80,0x7a,0x37,0x22, +0xac,0x75,0x21,0x0, 0x2, 0x27,0x92,0x7e,0xa1,0x21,0x74,0x2, 0xa4,0x7d,0x45,0x2d, +0x47,0x7e,0x49,0x70,0x19,0x75,0x22,0xae,0x9, 0x74,0x0, 0x1, 0x19,0x75,0x22,0xaf, +0x5, 0x21,0xe5,0x23,0xbe,0xb1,0x21,0x38,0xde,0xe5,0x23,0xbe,0xb0,0xa, 0x38,0x3, +0x2, 0x29,0x21,0x75,0x24,0x0, 0x75,0x21,0x0, 0x2, 0x28,0x64,0x7e,0x34,0x3, 0xff, +0x7a,0x35,0x27,0x75,0x26,0x0, 0x75,0x22,0x0, 0x2, 0x28,0x13,0x7e,0xa1,0x22,0x74, +0x2, 0xa4,0x9, 0x75,0x22,0xaf,0xa, 0x27,0x7e,0xa1,0x21,0x74,0x2, 0xa4,0x9, 0x75, +0x29,0x79,0xa, 0x37,0x9d,0x32,0x12,0x5d,0x8a,0x7d,0x63,0x7e,0xa1,0x22,0x74,0x2, +0xa4,0x9, 0x75,0x22,0xae,0xa, 0x27,0x7e,0xa1,0x21,0x74,0x2, 0xa4,0x9, 0x75,0x29, +0x78,0xa, 0x37,0x9d,0x32,0x12,0x5d,0x8a,0x2d,0x36,0x7a,0x35,0x29,0x7e,0x35,0x27, +0xbe,0x35,0x29,0x38,0x3, 0x2, 0x28,0x11,0x7e,0x35,0x29,0x7a,0x35,0x27,0x85,0x22, +0x26,0x5, 0x22,0xe5,0x23,0xbe,0xb1,0x22,0x38,0xa2,0x7e,0x71,0x26,0x74,0x2, 0xac, +0x7b,0x9, 0x33,0x22,0xae,0x7c,0x43,0x1e,0x40,0x7e,0x50,0x24,0xac,0x45,0x9, 0xa3, +0x22,0xaf,0x7c,0x2a,0x1e,0x20,0xa, 0x2, 0x2d,0x20,0x3e,0x24,0x2e,0x27,0x22,0xac, +0xb, 0x28,0x20,0xbe,0x24,0x0, 0x50,0x58,0x3, 0x2, 0x28,0x62,0xe5,0x24,0x1a,0x2b, +0x3e,0x24,0x19,0x32,0x22,0xfe,0x19,0xa2,0x22,0xff,0x74,0xff,0x19,0xb3,0x22,0xae, +0x5, 0x24,0x5, 0x21,0xe5,0x13,0xbe,0xb1,0x21,0x28,0x3, 0x2, 0x27,0xac,0x85,0x24, +0x21,0x2, 0x28,0xf4,0x6d,0x33,0x7a,0x37,0x22,0xaa,0x6c,0xaa,0x75,0x22,0x0, 0x2, +0x28,0xcb,0x7e,0x51,0x22,0x74,0x2, 0xac,0x5b,0x9, 0x62,0x22,0xae,0xbe,0x60,0xff, +0x78,0x3, 0x2, 0x28,0xc9,0x7c,0x76,0x1e,0x70,0x7e,0x30,0x24,0xac,0x37,0x9, 0x72, +0x22,0xaf,0x7c,0xb7,0x1e,0xb0,0xa, 0xb, 0x2d,0x10,0x3e,0x14,0x2e,0x17,0x22,0xac, +0xb, 0x18,0x40,0xbe,0x47,0x22,0xaa,0x18,0x3, 0x2, 0x28,0xc9,0x7a,0x61,0x25,0x7a, +0x71,0x26,0x7a,0x47,0x22,0xaa,0x7e,0xa1,0x22,0x5, 0x22,0xe5,0x23,0xbe,0xb1,0x22, +0x38,0xb0,0x7e,0x71,0x25,0x7e,0x91,0x21,0x74,0x2, 0xac,0x9b,0x19,0x74,0x22,0xfe, +0xe5,0x26,0x19,0xb4,0x22,0xff,0x7e,0x70,0xff,0x7e,0x50,0x2, 0xac,0x5a,0x19,0x72, +0x22,0xae,0x5, 0x21,0xe5,0x21,0xbe,0xb0,0xa, 0x50,0x3, 0x2, 0x28,0x74,0x75,0x21, +0x0, 0x7e,0xa1,0x21,0x74,0x2, 0xa4,0x9, 0x75,0x22,0xfe,0x19,0x75,0x22,0xae,0x9, +0x75,0x22,0xff,0x19,0x75,0x22,0xaf,0x5, 0x21,0xe5,0x21,0xb4,0xa, 0xe3,0x75,0x23, +0xa, 0x75,0x21,0x0, 0x7e,0xa0,0xff,0x7e,0x71,0x21,0x74,0x2, 0xac,0x7b,0x19,0xa3, +0x29,0x78,0x74,0xff,0x19,0xb3,0x29,0x79,0x5, 0x21,0xe5,0x21,0xb4,0xa, 0xe5,0xe5, +0x23,0xbe,0xb0,0x0, 0x38,0x3, 0x2, 0x29,0x7d,0x75,0x21,0x0, 0x2, 0x29,0x76,0x7e, +0xa1,0x21,0x74,0x2, 0xa4,0x9, 0x65,0x22,0xae,0x7d,0x45,0x2d,0x47,0x7a,0x49,0x60, +0x9, 0x75,0x22,0xaf,0x7d,0x25,0x2d,0x27,0x19,0x72,0x0, 0x1, 0x19,0x65,0x29,0x78, +0x19,0x75,0x29,0x79,0x5, 0x21,0xe5,0x23,0xbe,0xb1,0x21,0x38,0xd2,0x85,0x23,0x13, +0xe5,0x23,0x19,0xb7,0x0, 0x96,0xda,0x3b,0x22,0xca,0x3b,0x7a,0x5, 0x23,0x7a,0x15, +0x21,0x7d,0x72,0x7d,0x63,0x9, 0x77,0x0, 0x8e,0x7a,0x73,0x23,0x3a,0xe4,0x19,0xb7, +0x0, 0x8e,0x75,0x28,0x0, 0x75,0x25,0x0, 0xe5,0x25,0xa, 0x3b,0x2d,0x36,0x9, 0xb3, +0x0, 0x94,0xbe,0xb1,0x28,0x50,0x3, 0x2, 0x29,0xbc,0xf5,0x28,0x5, 0x25,0xe5,0x25, +0xb4,0x20,0xe5,0xe5,0x28,0xbe,0xb0,0x3f,0x40,0x3, 0x2, 0x29,0xdc,0xe5,0x28,0xa, +0x4b,0x7e,0x54,0x0, 0x3f,0x9d,0x54,0xf5,0x28,0x2, 0x29,0xdf,0x75,0x28,0x0, 0x85, +0x28,0x27,0x2, 0x2b,0x74,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x0, 0x64,0x7a, +0x37,0x23,0x68,0x12,0x7, 0x7f,0x12,0x5e,0x16,0x60,0xfb,0x7d,0x37,0x7e,0x25,0x21, +0x12,0x4d,0x35,0x75,0x25,0x0, 0x2, 0x2a,0x75,0x75,0x26,0x0, 0x2, 0x2a,0x6a,0xe5, +0x25,0x60,0x3, 0x2, 0x2a,0x2c,0x6c,0xaa,0xe5,0x26,0xa, 0x3b,0x19,0xa3,0x23,0xa, +0x6d,0x33,0x7e,0xa1,0x26,0x74,0x2, 0xa4,0x59,0x35,0x22,0xaa,0x7e,0x71,0x25,0x74, +0x48,0xac,0x7b,0x7e,0x51,0x26,0x74,0x2, 0xac,0x5b,0x2d,0x32,0x2e,0x35,0x21,0x49, +0x13,0xd, 0x80,0xe, 0x14,0xe, 0x14,0xe, 0x14,0xe, 0x14,0xe, 0x14,0x2e,0x24,0x22, +0xaa,0xb, 0x28,0x30,0x2d,0x31,0x1b,0x28,0x30,0xe5,0x26,0xa, 0x3b,0x2e,0x34,0x23, +0xa, 0x7e,0x39,0xb0,0x4, 0x7a,0x39,0xb0,0x5, 0x26,0x9, 0x77,0x0, 0x1, 0xbe,0x71, +0x26,0x38,0x9c,0x5, 0x25,0x7e,0x79,0x70,0xbe,0x71,0x25,0x38,0x8c,0x75,0x29,0x0, +0x75,0x25,0x0, 0x2, 0x2b,0x45,0xe5,0x25,0xa, 0x2b,0x9, 0x72,0x23,0xa, 0xa5,0xbf, +0x0, 0x2, 0x80,0x3, 0x2, 0x2a,0xa9,0x7e,0x14,0x21,0x34,0x7e,0x61,0x25,0x74,0x2, +0xac,0xb6,0x59,0x15,0x22,0xaa,0x2, 0x2a,0xd0,0x7e,0x31,0x25,0x74,0x2, 0xac,0x3b, +0x49,0x51,0x22,0xaa,0xa, 0x47,0x8d,0x54,0x59,0x51,0x22,0xaa,0x2e,0x14,0x22,0xaa, +0xb, 0x18,0x30,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x1b,0x18,0x30, +0x7e,0x91,0x25,0x74,0x2, 0xac,0x9b,0x49,0x14,0x22,0xaa,0x49,0x6, 0x0, 0xed,0x49, +0x36,0x0, 0xe, 0x7d,0x53,0x9d,0x50,0xbd,0x15,0x40,0x3, 0x2, 0x2b,0x13,0x9, 0xb2, +0x23,0x6c,0xa, 0xfb,0x2e,0xf5,0x23,0x9, 0xbf,0x0, 0x24,0xbe,0xb1,0x28,0x40,0x3, +0x2, 0x2b,0xe, 0x2e,0xf4,0x0, 0x24,0x4, 0x7a,0xf9,0xb0,0x2, 0x2b,0x43,0x5, 0x29, +0x2, 0x2b,0x43,0x2d,0x30,0xbd,0x13,0x38,0x3, 0x2, 0x2b,0x41,0x9, 0x72,0x23,0x6c, +0xa, 0x37,0x2e,0x35,0x23,0x9, 0xb3,0x0, 0x24,0xbe,0xb0,0x0, 0x38,0x3, 0x2, 0x2b, +0x3c,0x2e,0x34,0x0, 0x24,0x14,0x7a,0x39,0xb0,0x2, 0x2b,0x43,0x5, 0x29,0x2, 0x2b, +0x43,0x5, 0x29,0x5, 0x25,0x9, 0x77,0x0, 0x1, 0xbe,0x71,0x25,0x28,0x3, 0x2, 0x2a, +0x86,0x53,0xdb,0xf0,0x7e,0x35,0x23,0x12,0x4c,0x86,0x53,0xdc,0xe0,0x9, 0x76,0x0, +0xec,0x7c,0xb7,0x42,0xdc,0x12,0x5d,0xdf,0x9, 0x77,0x0, 0x1, 0xbe,0x71,0x29,0x78, +0x3, 0x2, 0x2b,0x83,0x7e,0xa1,0x27,0x7c,0xba,0x14,0xf5,0x27,0x4c,0xaa,0x68,0x3, +0x2, 0x29,0xe5,0x75,0x25,0x0, 0xe5,0x25,0xa, 0x2b,0x9, 0x72,0x23,0x6c,0xa, 0x37, +0x2e,0x35,0x23,0x9, 0x73,0x0, 0x24,0x2d,0x26,0x19,0x72,0x0, 0xc4,0x5, 0x25,0xe5, +0x25,0xbe,0xb0,0x24,0x40,0xe0,0x7e,0x73,0x23,0x3a,0x19,0x77,0x0, 0x8e,0x74,0x1, +0xda,0x3b,0x22,0xca,0x3b,0x7d,0x73,0x6c,0xdd,0x75,0x26,0x0, 0x49,0x37,0x1, 0x4c, +0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x7a,0x35,0x27,0xe4,0x7e,0x79,0x70,0x12, +0x5e,0x5e,0x74,0x2, 0x9, 0x77,0x0, 0x2, 0x12,0x5e,0x5e,0x74,0x3, 0x9, 0x77,0x0, +0x3, 0x12,0x5e,0x5e,0x74,0x4, 0x9, 0x77,0x0, 0x4, 0x12,0x5e,0x5e,0x74,0x5, 0x9, +0x77,0x0, 0x5, 0x12,0x5e,0x5e,0x74,0x6, 0x9, 0x77,0x0, 0x6, 0x12,0x5e,0x5e,0x74, +0x7, 0x9, 0x77,0x0, 0x7, 0x12,0x5e,0x5e,0x74,0x8, 0x9, 0x77,0x0, 0x8, 0x12,0x5e, +0x5e,0x74,0x9, 0x7e,0x70,0xff,0x12,0x5e,0x5e,0x74,0x2, 0x7e,0x70,0x5d,0x12,0x5e, +0x5e,0x74,0xa, 0x7e,0x35,0x27,0x12,0x5e,0x5e,0x74,0x1, 0x6c,0x77,0x12,0x5e,0x5e, +0x6c,0xcc,0x74,0xb, 0x7e,0x70,0x2, 0xac,0x7c,0x2d,0x37,0x49,0x33,0x0, 0xec,0xa, +0x36,0x12,0x5e,0x5e,0x74,0xb, 0x7e,0x70,0x2, 0xac,0x7c,0x2d,0x37,0x49,0x33,0x0, +0xec,0x12,0x5e,0x5e,0xb, 0xc0,0xbe,0xc0,0x30,0x78,0xd7,0x6c,0xcc,0x2, 0x2d,0xbf, +0x9, 0x77,0x0, 0xeb,0xa, 0x37,0x9, 0x57,0x0, 0x5, 0xa, 0x25,0x9d,0x23,0xa, 0x3c, +0xbd,0x32,0x40,0x3, 0x2, 0x2d,0x52,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x10,0xa, +0x3c,0x2d,0x37,0x9, 0x73,0x0, 0x9b,0x12,0x5e,0x5e,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0, +0x24,0x11,0xa, 0x3c,0x2d,0x37,0x9, 0x73,0x0, 0xb, 0x12,0x5e,0x5e,0x7c,0xbd,0x3e, +0xb0,0x3e,0xb0,0x24,0x12,0xa, 0x3c,0x2d,0x37,0x9, 0x73,0x0, 0x3b,0x12,0x5e,0x5e, +0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x13,0xa, 0x3c,0x2d,0x37,0x9, 0x73,0x0, 0x6b, +0x12,0x5e,0x5e,0x75,0x25,0x0, 0x2, 0x2d,0x43,0xe5,0x25,0xa, 0x3b,0x2d,0x37,0x9, +0x63,0x0, 0xcb,0xa, 0x2c,0x2d,0x27,0x9, 0x72,0x0, 0x9b,0xbc,0x76,0x68,0x3, 0x2, +0x2d,0x41,0xb, 0xd0,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x10,0x7e,0xa1,0x26,0xa, +0x3a,0x2d,0x37,0x9, 0x73,0x0, 0xcb,0x2e,0x70,0x80,0x12,0x5e,0x5e,0x7c,0xbd,0x3e, +0xb0,0x3e,0xb0,0x24,0x11,0x7e,0xa1,0x26,0xa, 0x3a,0x2d,0x37,0x9, 0x73,0x0, 0xd3, +0x12,0x5e,0x5e,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x12,0x7e,0xa1,0x26,0xa, 0x3a, +0x2d,0x37,0x9, 0x73,0x0, 0xdb,0x12,0x5e,0x5e,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24, +0x13,0x7e,0xa1,0x26,0xa, 0x3a,0x2d,0x37,0x9, 0x73,0x0, 0xe3,0x12,0x5e,0x5e,0x5, +0x26,0x5, 0x25,0x9, 0x77,0x0, 0xeb,0xbe,0x71,0x25,0x28,0x3, 0x2, 0x2c,0xc9,0x2, +0x2d,0xbb,0x9, 0x77,0x0, 0xeb,0xbe,0x71,0x26,0x38,0x3, 0x2, 0x2d,0xca,0x7c,0xbd, +0x3e,0xb0,0x3e,0xb0,0x24,0x10,0x7e,0xa1,0x26,0xa, 0x3a,0x2d,0x37,0x9, 0x73,0x0, +0xcb,0x2e,0x70,0x80,0x12,0x5e,0x5e,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x11,0x7e, +0xa1,0x26,0xa, 0x3a,0x2d,0x37,0x9, 0x73,0x0, 0xd3,0x12,0x5e,0x5e,0x7c,0xbd,0x3e, +0xb0,0x3e,0xb0,0x24,0x12,0x7e,0xa1,0x26,0xa, 0x3a,0x2d,0x37,0x9, 0x73,0x0, 0xdb, +0x12,0x5e,0x5e,0x7c,0xbd,0x3e,0xb0,0x3e,0xb0,0x24,0x13,0x7e,0xa1,0x26,0xa, 0x3a, +0x2d,0x37,0x9, 0x73,0x0, 0xe3,0x12,0x5e,0x5e,0x5, 0x26,0xb, 0xd0,0xb, 0xc0,0x9, +0x77,0x0, 0x5, 0xbc,0x7c,0x28,0x3, 0x2, 0x2c,0x60,0xda,0x3b,0x22,0xc0,0x0, 0xc0, +0x3f,0xdf,0xbf,0xdf,0xbf,0xc0,0x1, 0xc0,0x82,0xc1,0x2, 0xc1,0x1, 0xc0,0x3f,0xdf, +0x3d,0xde,0x3c,0xde,0xbe,0xc0,0x2, 0xc1,0x85,0xc2,0x85,0xc2,0x2, 0xc0,0x3e,0xde, +0x3a,0xdd,0x3a,0xdd,0xbd,0xc0,0x3, 0xc2,0x87,0xc4,0x7, 0xc3,0x3, 0xc0,0x3d,0xdd, +0x38,0xdb,0xb7,0xdc,0xbc,0xc0,0x4, 0xc3,0x8a,0xc5,0x8a,0xc4,0x4, 0xc0,0x3c,0xdc, +0x35,0xda,0x35,0xdb,0xbb,0xc0,0x5, 0xc4,0x8c,0xc6,0x8d,0xc5,0x5, 0xc0,0x3b,0xdb, +0x32,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8e,0xc5,0x86,0xc0,0x3a,0xda, +0xb2,0xd8,0xb2,0xda,0xba,0xc0,0x6, 0xc5,0x8e,0xc7,0x8d,0xc5,0x5, 0xc0,0x3b,0xdb, +0x34,0xd9,0xb4,0xdb,0xbb,0xc0,0x5, 0xc4,0x8b,0xc6,0xb, 0xc4,0x4, 0xc0,0x3c,0xdc, +0x36,0xdb,0x36,0xdc,0xbc,0xc0,0x4, 0xc3,0x89,0xc4,0x88,0xc3,0x3, 0xc0,0x3d,0xdd, +0x39,0xdc,0x39,0xdd,0xbd,0xc0,0x3, 0xc2,0x86,0xc3,0x6, 0xc2,0x2, 0xc0,0x3e,0xde, +0x3b,0xdd,0xbc,0xde,0xbe,0xc0,0x2, 0xc1,0x83,0xc1,0x83,0xc1,0x1, 0xc0,0x3f,0xdf, +0x3e,0xdf,0x3e,0xdf,0xbf,0xc0,0x0, 0xc0,0x81,0xc0,0x80,0xc0,0x0, 0xca,0x3b,0x7a, +0x25,0x25,0x7d,0x73,0x6d,0x0, 0x9, 0xb7,0x0, 0x82,0xf5,0x29,0x70,0x29,0xf5,0x27, +0x6d,0x33,0xe5,0x27,0x1a,0x1b,0x7d,0x21,0x3e,0x24,0x59,0x32,0x27,0x8a,0x74,0xff, +0x7e,0x34,0x0, 0x7, 0xad,0x31,0x19,0xb3,0x27,0x48,0x74,0x2, 0x19,0xb1,0x27,0x9e, +0x5, 0x27,0xe5,0x27,0xb4,0xa, 0xd9,0x75,0x27,0x0, 0x2, 0x31,0xa2,0xe5,0x27,0x1a, +0x2b,0x7e,0x34,0x0, 0x7, 0xad,0x32,0x7d,0x13,0x2d,0x17,0x9, 0x71,0x0, 0x4, 0xbe, +0x70,0xff,0x78,0x3, 0x2, 0x31,0xa0,0xa, 0x37,0x2d,0x37,0x9, 0xb3,0x0, 0x46,0x60, +0x8, 0xb4,0x2, 0x2, 0x80,0x3, 0x2, 0x31,0xa0,0x75,0x28,0x0, 0x7e,0x51,0x28,0x74, +0x7, 0xac,0x5b,0x9, 0x22,0x27,0x48,0xe5,0x27,0x1a,0x4b,0x7e,0x54,0x0, 0x7, 0xad, +0x54,0x7d,0x35,0x2d,0x37,0x9, 0x33,0x0, 0x4, 0xbc,0x32,0x68,0x3, 0x2, 0x31,0x94, +0x49,0x22,0x27,0x46,0x49,0x33,0x0, 0x2, 0x9d,0x32,0x12,0x5d,0x8a,0x7d,0x63,0x7e, +0xa1,0x28,0x74,0x7, 0xa4,0x49,0x25,0x27,0x44,0xe5,0x27,0x1a,0xb, 0x7e,0x14,0x0, +0x7, 0xad,0x10,0x7d,0x31,0x2d,0x37,0xb, 0x38,0x30,0x9d,0x32,0x12,0x5d,0x8a,0x7d, +0x3, 0x2d,0x6, 0x7e,0x91,0x28,0x74,0x7, 0xac,0x9b,0x9, 0xa4,0x27,0x48,0xa, 0x1a, +0x9, 0x71,0x27,0x9e,0xbe,0x70,0x0, 0x28,0x16,0x7e,0x50,0x2, 0xac,0x5a,0x59,0x2, +0x27,0x8a,0x2e,0x14,0x27,0x9e,0x7c,0xb7,0x14,0x7a,0x19,0xb0,0x2, 0x31,0xa0,0x74, +0x2, 0xa4,0x49,0x15,0x27,0x8a,0xbe,0x14,0x0, 0x64,0x28,0x9, 0xbe,0x4, 0x0, 0x64, +0x28,0x3, 0x2, 0x31,0x8e,0x7d,0x31,0x2e,0x34,0x0, 0x32,0xbd,0x30,0x50,0x9, 0xbe, +0x14,0x0, 0x32,0x28,0x3, 0x2, 0x31,0x8e,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x3e,0x14, +0xbd,0x10,0x28,0x3, 0x2, 0x31,0x8e,0x7e,0x15,0x25,0x49,0x11,0x0, 0x4, 0xbd,0x10, +0x40,0x3, 0x2, 0x31,0x81,0xe5,0x27,0x1a,0x2b,0x7e,0x34,0x0, 0x7, 0xad,0x32,0x7d, +0x13,0x2d,0x17,0x9, 0x51,0x0, 0x4, 0xa, 0x25,0x2d,0x27,0x9, 0xb2,0x0, 0x46,0x70, +0x4, 0x74,0x3, 0x80,0x2, 0x74,0x1, 0x19,0xb2,0x0, 0x46,0x74,0x3, 0x7d,0x23,0x2d, +0x27,0x9, 0xa2,0x0, 0x4, 0xa, 0x2a,0x2d,0x27,0x19,0xb2,0x0, 0x50,0x2d,0x37,0x7e, +0x14,0x22,0xaa,0x74,0x7, 0x12,0x4c,0x65,0xe5,0x29,0xbe,0xb0,0x0, 0x28,0x32,0x15, +0x29,0x7e,0x71,0x29,0x74,0x7, 0xac,0x7b,0x2d,0x37,0xe5,0x27,0x1a,0x4b,0x7e,0x54, +0x0, 0x7, 0xad,0x54,0x7d,0x15,0x2d,0x17,0x74,0x7, 0x12,0x4c,0x65,0x7e,0x34,0x22, +0xaa,0x7e,0x31,0x29,0x74,0x7, 0xac,0x3b,0x2d,0x17,0x74,0x7, 0x12,0x4c,0x65,0x15, +0x27,0x7e,0xa1,0x28,0x74,0x7, 0xa4,0x9, 0xa5,0x27,0x48,0x74,0x2, 0xa4,0x59,0x5, +0x27,0x8a,0x80,0xc, 0x5, 0x28,0xe5,0x28,0xbe,0xb0,0xa, 0x50,0x3, 0x2, 0x30,0x3c, +0x5, 0x27,0x9, 0x77,0x0, 0x82,0xbe,0x71,0x27,0x28,0x3, 0x2, 0x30,0xd, 0xe5,0x29, +0x19,0xb7,0x0, 0x82,0x7e,0x34,0x27,0x44,0x7d,0x27,0x7e,0x14,0x0, 0x46,0x12,0x5d, +0x1b,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x63,0x6c,0xaa,0x49,0x36,0x0, 0x93,0x7a,0x37, +0x22,0xaa,0x9, 0xb6,0x0, 0x92,0x20,0xe0,0x9, 0x20,0xe2,0x6, 0x20,0xe1,0x3, 0x2, +0x33,0x9c,0x20,0x0, 0x6, 0x7e,0x74,0x28,0x89,0x80,0x4, 0x7e,0x74,0x28,0xcb,0x75, +0x21,0x0, 0x7e,0x30,0xff,0xe5,0x21,0xa, 0x3b,0x2d,0x37,0x7a,0x39,0x30,0x5, 0x21, +0xe5,0x21,0xb4,0x42,0xed,0x74,0xaa,0x7a,0x79,0xb0,0x74,0xaa,0x19,0xb7,0x0, 0x1, +0x74,0x42,0x19,0xb7,0x0, 0x2, 0x9, 0xb6,0x0, 0x8c,0x19,0xb7,0x0, 0x4, 0x6c,0x77, +0x75,0x21,0x0, 0x2, 0x33,0x26,0x7e,0x91,0x21,0x74,0x7, 0xac,0x9b,0x2d,0x46,0x9, +0x64,0x0, 0x4, 0x7c,0xb6,0x54,0xf0,0xbe,0xb0,0x0, 0x28,0x30,0xb4,0xb0,0x2, 0x80, +0x3, 0x2, 0x33,0x24,0xb, 0x46,0x7c,0xb6,0x54,0xf, 0x7a,0x49,0xb0,0x7e,0x31,0x21, +0x74,0x7, 0xac,0x3b,0x2d,0x16,0x9, 0x61,0x0, 0x4, 0xa, 0x16,0x2e,0x17,0x22,0xaa, +0x9, 0xb1,0x0, 0x46,0xb4,0x1, 0x2, 0x80,0x3, 0x2, 0x33,0x24,0x7e,0x31,0x21,0x74, +0x7, 0xac,0x3b,0x7d,0xe1,0x2d,0xe6,0x9, 0xe, 0x0, 0x4, 0xa, 0xf0,0x2e,0xf7,0x22, +0xaa,0x9, 0xbf,0x0, 0x46,0xbe,0xb0,0x3, 0x78,0x3, 0x2, 0x33,0x24,0x7e,0x30,0x6, +0xac,0x37,0x7c,0x63,0x49,0x4e,0x0, 0x2, 0xa, 0x18,0x5e,0x14,0x0, 0xf, 0x7c,0x13, +0xa, 0x16,0x2d,0x17,0x19,0x11,0x0, 0x5, 0x7c,0x19,0xa, 0x16,0x2d,0x17,0x19,0x11, +0x0, 0x6, 0xb, 0xe8,0x40,0xa, 0x18,0x5e,0x14,0x0, 0xf, 0x7c,0x13,0xa, 0x16,0x2d, +0x17,0x19,0x11,0x0, 0x7, 0x7c,0x19,0xa, 0x16,0x2d,0x17,0x19,0x11,0x0, 0x8, 0x9, +0xbe,0x0, 0x4, 0xc4,0x54,0xf0,0xa, 0x16,0x2d,0x17,0x2e,0x14,0x0, 0x7, 0x7e,0x19, +0x10,0x2c,0x1b,0x7a,0x19,0x10,0xbe,0x0, 0xff,0x68,0x27,0x9, 0xbf,0x0, 0x46,0xbe, +0xb0,0x1, 0x68,0x2, 0xb, 0xa0,0x9, 0x1f,0x0, 0x46,0x7c,0xb1,0xc4,0x33,0x33,0x54, +0xc0,0x7c,0x1b,0xa, 0x16,0x2d,0x17,0x2e,0x14,0x0, 0x5, 0x7e,0x19,0xb0,0x2c,0xb1, +0x80,0xd, 0xa, 0x16,0x2d,0x17,0x2e,0x14,0x0, 0x5, 0x7e,0x19,0xb0,0x24,0xc0,0x7a, +0x19,0xb0,0xb, 0x70,0x5, 0x21,0x7e,0x29,0xb0,0xbe,0xb1,0x21,0x28,0x3, 0x2, 0x32, +0x26,0x19,0xa7,0x0, 0x3, 0xe4,0x19,0xb7,0x0, 0x41,0x75,0x21,0x0, 0xe5,0x21,0xa, +0x3b,0x2d,0x37,0x7e,0x39,0x60,0x7d,0x27,0x2e,0x24,0x0, 0x41,0x7e,0x29,0x70,0x6c, +0x76,0x7a,0x29,0x70,0x5, 0x21,0xe5,0x21,0xb4,0x41,0xe2,0xb2,0x0, 0x74,0x1, 0x12, +0x5e,0x33,0x9, 0xb6,0x0, 0x92,0x30,0xe2,0x7, 0x7e,0x37,0x22,0xaa,0x12,0x58,0xce, +0x7d,0x36,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xfe,0x7a,0x39,0xb0,0x7d,0x36, +0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xfb,0x7a,0x39,0xb0,0x7d,0x36,0x2e,0x34, +0x0, 0x92,0x7e,0x39,0xb0,0x54,0xfd,0x7a,0x39,0xb0,0x80,0x4, 0xe4,0x12,0x5e,0x33, +0xda,0x3b,0x22,0xca,0x3b,0x7d,0x73,0x6d,0x33,0x7a,0x35,0x25,0x9, 0xb2,0x0, 0x96, +0x60,0x6, 0x9, 0xb2,0x0, 0x97,0x60,0x4, 0xe4,0x2, 0x35,0x48,0x7e,0x29,0xb0,0x1e, +0xb0,0xf5,0x22,0x9, 0xb2,0x0, 0x1, 0x1e,0xb0,0xf5,0x23,0x75,0x24,0x0, 0x75,0x21, +0x0, 0x7e,0x51,0x22,0x74,0x48,0xac,0x5b,0x7e,0x71,0x21,0x74,0x2, 0xac,0x7b,0x2d, +0x32,0x2d,0x37,0x49,0x33,0xd, 0x80,0x12,0x5d,0x8a,0xbe,0x34,0x0, 0x32,0x8, 0x2, +0x5, 0x24,0x5, 0x21,0xe5,0x21,0xb4,0x14,0xd8,0xe5,0x24,0xbe,0xb0,0x10,0x28,0x14, +0xe5,0x24,0xa, 0x2b,0x9e,0x24,0x0, 0x10,0x7e,0x34,0x0, 0x5, 0xad,0x32,0x2e,0x35, +0x25,0x7a,0x35,0x25,0x75,0x24,0x0, 0xe5,0x22,0xbe,0xb0,0x0, 0x28,0x44,0x75,0x21, +0x0, 0x7e,0x51,0x22,0x74,0x48,0xac,0x5b,0x7e,0x71,0x21,0x74,0x2, 0xac,0x7b,0x2d, +0x32,0x2d,0x37,0x49,0x33,0xd, 0x38,0x12,0x5d,0x8a,0x7d,0x63,0x7e,0x51,0x22,0x74, +0x48,0xac,0x5b,0x7e,0x71,0x21,0x74,0x2, 0xac,0x7b,0x2d,0x32,0x2d,0x37,0x49,0x33, +0xd, 0x80,0x12,0x5d,0x8a,0xbd,0x36,0x8, 0x2, 0x5, 0x24,0x5, 0x21,0xe5,0x21,0xb4, +0x14,0xbf,0xe5,0x24,0xbe,0xb0,0x10,0x28,0x14,0xe5,0x24,0xa, 0x2b,0x9e,0x24,0x0, +0x10,0x7e,0x34,0x0, 0x5, 0xad,0x32,0x2e,0x35,0x25,0x7a,0x35,0x25,0x75,0x24,0x0, +0xe5,0x22,0xbe,0xb0,0x1f,0x50,0x44,0x75,0x21,0x0, 0x7e,0x51,0x22,0x74,0x48,0xac, +0x5b,0x7e,0x71,0x21,0x74,0x2, 0xac,0x7b,0x2d,0x32,0x2d,0x37,0x49,0x33,0xd, 0xc8, +0x12,0x5d,0x8a,0x7d,0x63,0x7e,0x51,0x22,0x74,0x48,0xac,0x5b,0x7e,0x71,0x21,0x74, +0x2, 0xac,0x7b,0x2d,0x32,0x2d,0x37,0x49,0x33,0xd, 0x80,0x12,0x5d,0x8a,0xbd,0x36, +0x8, 0x2, 0x5, 0x24,0x5, 0x21,0xe5,0x21,0xb4,0x14,0xbf,0xe5,0x24,0xbe,0xb0,0x10, +0x28,0x14,0xe5,0x24,0xa, 0x2b,0x9e,0x24,0x0, 0x10,0x7e,0x34,0x0, 0x5, 0xad,0x32, +0x2e,0x35,0x25,0x7a,0x35,0x25,0xe5,0x23,0xbe,0xb0,0x0, 0x28,0x26,0x7e,0x51,0x22, +0x74,0x48,0xac,0x5b,0x7e,0x71,0x23,0x74,0x2, 0xac,0x7b,0x2d,0x32,0x2d,0x37,0x49, +0x33,0xd, 0x7e,0xbe,0x34,0xff,0xb0,0x58,0xa, 0x7e,0x35,0x25,0x2e,0x34,0x0, 0x5, +0x7a,0x35,0x25,0xe5,0x23,0xa, 0x3b,0xb, 0x34,0xbe,0x34,0x0, 0x20,0x58,0x26,0x7e, +0x51,0x22,0x74,0x48,0xac,0x5b,0x7e,0x71,0x23,0x74,0x2, 0xac,0x7b,0x2d,0x32,0x2d, +0x37,0x49,0x33,0xd, 0x82,0xbe,0x34,0xff,0xb0,0x58,0xa, 0x7e,0x35,0x25,0x2e,0x34, +0x0, 0x5, 0x7a,0x35,0x25,0x7e,0x55,0x25,0xda,0x3b,0x22,0xca,0x3b,0x7a,0x5, 0x23, +0x7a,0x15,0x21,0x7d,0x62,0x7d,0x73,0xe5,0xcc,0xf5,0x27,0xb, 0x68,0x30,0x4d,0x33, +0x78,0x38,0x9, 0x57,0x0, 0x8e,0xbe,0x50,0x0, 0x28,0x6, 0x75,0x9, 0x0, 0x2, 0x36, +0x82,0x9, 0xb6,0x0, 0x2, 0x20,0xe0,0x3, 0x2, 0x36,0x82,0x9, 0x56,0x0, 0x8, 0xbe, +0x51,0x9, 0x28,0x3, 0x2, 0x36,0x82,0x75,0x9, 0x0, 0x7e,0x24,0x0, 0x1, 0x1b,0x68, +0x20,0x74,0x1, 0x7a,0xb3,0x29,0xed,0x2, 0x36,0x82,0xbe,0x34,0x0, 0x1, 0x78,0x1c, +0x9, 0xb7,0x0, 0x8e,0x70,0x3, 0x2, 0x36,0x82,0x6d,0x22,0x1b,0x68,0x20,0xe4,0x7a, +0xb3,0x29,0xed,0x75,0xb, 0x29,0x75,0xa, 0x1, 0x2, 0x36,0x82,0xbe,0x34,0x0, 0x3, +0x68,0x3, 0x2, 0x36,0x82,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x4, 0x8f,0x7a, +0x37,0x23,0x68,0x12,0x7, 0x7f,0xa9,0xd6,0xeb,0xa9,0xc6,0xac,0xa9,0xc6,0xec,0xc2, +0x96,0xc2,0x89,0xd2,0xb8,0xa9,0xd0,0xb7,0xd2,0xa8,0x12,0x5e,0x16,0x60,0xfb,0x20, +0x93,0xfd,0x43,0x87,0x2, 0x0, 0x0, 0x0, 0xc2,0xaf,0x75,0x28,0x0, 0xe5,0xa8,0xb4, +0x1, 0x8, 0x75,0xa8,0x0, 0x75,0x28,0x0, 0x80,0x2, 0x5, 0x28,0xe5,0x28,0xbe,0xb0, +0xfa,0x38,0x13,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x4, 0x8f,0x7a,0x37,0x23, +0x68,0x12,0x7, 0x7f,0x80,0xd7,0xd2,0xaf,0xc2,0xa8,0xc2,0x95,0xa9,0xc6,0xeb,0xa9, +0xd6,0xac,0xa9,0xd6,0xec,0xd2,0x86,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x4, +0x8f,0x7a,0x37,0x23,0x68,0x12,0x7, 0x7f,0x53,0xdb,0xf0,0x12,0x5d,0xdf,0x7e,0x35, +0x25,0x7d,0x27,0x12,0x52,0x33,0x6d,0x33,0x1b,0x68,0x30,0xe4,0x7a,0xb3,0x29,0xed, +0x7e,0x35,0x23,0x12,0x56,0xb0,0x7e,0x34,0x0, 0x14,0x7a,0x37,0x27,0x42,0x7e,0x37, +0x27,0x42,0x4d,0x33,0x78,0xf8,0x7e,0x35,0x21,0x7e,0x25,0x23,0x12,0x50,0x26,0x75, +0x11,0x0, 0x6c,0xdd,0xc2,0xcc,0x80,0x15,0xe4,0x12,0x5d,0x48,0xa9,0x31,0xdb,0xd, +0x4c,0xdd,0x78,0x9, 0x7e,0xd0,0x1, 0x53,0xcc,0xfc,0x43,0xcc,0x3, 0xe5,0xa, 0x60, +0xe7,0xd2,0xcc,0x75,0xb, 0x0, 0x75,0xa, 0x0, 0x7d,0x37,0x2e,0x34,0x0, 0x92,0x7e, +0x39,0xb0,0x54,0xef,0x7a,0x39,0xb0,0x9, 0x77,0x0, 0x8e,0x19,0x77,0x0, 0x8f,0x85, +0x27,0xcc,0xda,0x3b,0x22,0xca,0x3b,0xf5,0x21,0x7d,0x72,0x7d,0x63,0x6d,0x33,0x7a, +0x37,0x20,0xef,0xe4,0x7e,0x37,0x20,0xef,0x19,0xb3,0x24,0x72,0x7e,0x37,0x20,0xef, +0xb, 0x34,0x7a,0x37,0x20,0xef,0xbe,0x34,0x2, 0x80,0x78,0xe7,0x12,0x5b,0xbe,0x12, +0x5d,0xdf,0x7d,0x36,0x7d,0x27,0x12,0x4d,0x35,0xbe,0xb0,0xaa,0x68,0xf4,0x7d,0x37, +0x2e,0x34,0xd, 0x80,0x7a,0x37,0x29,0x1b,0x6d,0x33,0x7a,0x35,0x22,0x6c,0xaa,0x7e, +0x25,0x22,0x4d,0x22,0x68,0x3, 0x2, 0x37,0x24,0x6d,0x44,0x7e,0x30,0x2, 0xac,0x3a, +0x59,0x41,0x20,0xc7,0x7e,0x14,0x0, 0x24,0xad,0x12,0x7d,0x1, 0x3e,0x4, 0x7e,0x30, +0x2, 0xac,0x3a,0x2d,0x10,0x2e,0x17,0x29,0x1b,0xb, 0x18,0x40,0x7e,0x30,0x2, 0xac, +0x3a,0x49,0x1, 0x20,0xc7,0xbd,0x40,0x38,0x3, 0x2, 0x37,0x59,0xbe,0x44,0x23,0x28, +0x40,0x3, 0x2, 0x37,0x59,0x59,0x41,0x20,0xc7,0xb, 0xa0,0xbe,0xa0,0x14,0x78,0xaf, +0xb, 0x24,0x7a,0x25,0x22,0xbe,0x24,0x0, 0x20,0x78,0xa2,0x7d,0x43,0x7a,0x35,0x22, +0x6c,0xaa,0x7e,0x25,0x22,0x7e,0x34,0x0, 0x24,0xad,0x32,0x7d,0x23,0x3e,0x24,0x7e, +0x70,0x2, 0xac,0x7a,0x2d,0x32,0x2e,0x37,0x29,0x1b,0xb, 0x38,0x20,0xbe,0x24,0x23, +0x28,0x38,0x3, 0x2, 0x37,0x9b,0xb, 0x44,0x2, 0x37,0xd3,0x7e,0x70,0x2, 0xac,0x7a, +0x49,0x33,0x20,0xc7,0x9d,0x32,0x7a,0x37,0x20,0xef,0x1e,0x34,0x1e,0x34,0x1e,0x34, +0x7a,0x37,0x20,0xef,0xbe,0x34,0x0, 0xff,0x38,0x3, 0x2, 0x37,0xc5,0x7e,0x34,0x0, +0xff,0x7a,0x37,0x20,0xef,0x7e,0x37,0x20,0xef,0x7c,0xb7,0x7d,0x34,0xb, 0x44,0x19, +0xb3,0x24,0x72,0xb, 0xa0,0xbe,0xa0,0x14,0x78,0x98,0x7e,0x35,0x22,0xb, 0x34,0x7a, +0x35,0x22,0xbe,0x34,0x0, 0x20,0x78,0x88,0x7e,0x64,0x23,0x83,0x6c,0xff,0x6d,0x33, +0x7a,0x35,0x22,0x7e,0x69,0x70,0x6c,0xf7,0xe5,0x21,0xa, 0x3b,0x2e,0x35,0x22,0x7d, +0x26,0xb, 0x64,0x7e,0x29,0xb0,0x12,0x5b,0x3b,0x7e,0x35,0x22,0xb, 0x34,0x7a,0x35, +0x22,0xbe,0x34,0x3, 0x6f,0x40,0xdc,0x7e,0x34,0x7, 0xf0,0x7c,0xbf,0x12,0x5b,0x3b, +0x7e,0x34,0x7, 0xf1,0x74,0xff,0x9c,0xbf,0x12,0x5b,0x3b,0x74,0x1, 0xda,0x3b,0x22, +0xca,0x3b,0x75,0x22,0x0, 0x75,0x23,0x0, 0x75,0x24,0x0, 0x6c,0xff,0x7d,0x63,0x2e, +0x64,0xd, 0x80,0x75,0x25,0x1, 0x6c,0xee,0x2, 0x38,0xd2,0x74,0x24,0xac,0xbe,0x7a, +0x57,0x22,0xaa,0x75,0x21,0x0, 0x2, 0x38,0xc7,0x7e,0x37,0x22,0xaa,0x3e,0x34,0x2d, +0x36,0xb, 0x38,0x30,0x12,0x5d,0x8a,0xbe,0x37,0x2a,0x1e,0x38,0x3, 0x2, 0x38,0xbb, +0xe5,0x25,0x70,0x3, 0x2, 0x38,0x88,0x85,0x21,0x22,0x85,0x21,0x23,0x7a,0xe1,0x24, +0x7c,0xfe,0x75,0x25,0x0, 0x2, 0x38,0xbb,0xe5,0x21,0xbe,0xb1,0x22,0x40,0x3, 0x2, +0x38,0x98,0x85,0x21,0x22,0x2, 0x38,0xa5,0xe5,0x21,0xbe,0xb1,0x23,0x38,0x3, 0x2, +0x38,0xa5,0x85,0x21,0x23,0xbe,0xe1,0x24,0x40,0x3, 0x2, 0x38,0xb2,0x7c,0xfe,0x2, +0x38,0xbb,0xbc,0xef,0x38,0x3, 0x2, 0x38,0xbb,0x7c,0xfe,0x7e,0x37,0x22,0xaa,0xb, +0x34,0x7a,0x37,0x22,0xaa,0x5, 0x21,0x7e,0x73,0x2a,0x11,0xbe,0x71,0x21,0x38,0x89, +0xb, 0xe0,0x7e,0x73,0x2a,0x10,0xbc,0x7e,0x28,0x3, 0x2, 0x38,0x4b,0xe5,0x22,0x7a, +0xb3,0x2a,0x15,0xe5,0x23,0x7a,0xb3,0x2a,0x14,0xe5,0x24,0x7a,0xb3,0x2a,0x13,0x7a, +0xf3,0x2a,0x12,0x7e,0x53,0x2a,0x17,0x4c,0x55,0x78,0x3, 0x2, 0x39,0x94,0xa, 0x5, +0x7e,0x43,0x2a,0x14,0xa, 0x14,0x2d,0x10,0x7e,0x43,0x2a,0x11,0xa, 0x34,0x1b,0x34, +0xbd,0x13,0x28,0x3, 0x2, 0x39,0x22,0x2e,0x53,0x2a,0x14,0x7a,0x53,0x2a,0x14,0x2, +0x39,0x26,0x7a,0x73,0x2a,0x14,0x7e,0x73,0x2a,0x17,0xbe,0x73,0x2a,0x15,0x28,0x3, +0x2, 0x39,0x42,0x7e,0x73,0x2a,0x15,0x9e,0x73,0x2a,0x17,0x7a,0x73,0x2a,0x15,0x2, +0x39,0x47,0xe4,0x7a,0xb3,0x2a,0x15,0x7e,0x53,0x2a,0x17,0xa, 0x5, 0x7e,0x43,0x2a, +0x12,0xa, 0x14,0x2d,0x10,0x7e,0x43,0x2a,0x10,0xa, 0x34,0x1b,0x34,0xbd,0x13,0x28, +0x3, 0x2, 0x39,0x6f,0x2e,0x53,0x2a,0x12,0x7a,0x53,0x2a,0x12,0x2, 0x39,0x73,0x7a, +0x73,0x2a,0x14,0x7e,0x73,0x2a,0x17,0xbe,0x73,0x2a,0x13,0x28,0x3, 0x2, 0x39,0x8f, +0x7e,0x73,0x2a,0x13,0x9e,0x73,0x2a,0x17,0x7a,0x73,0x2a,0x13,0x2, 0x39,0x94,0xe4, +0x7a,0xb3,0x2a,0x13,0xda,0x3b,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca, +0x2b,0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x0, 0x5e,0x7e,0x35, +0xd, 0xb, 0x34,0x7a,0x35,0xd, 0xe5,0xcc,0x54,0x3, 0xb4,0x3, 0x2, 0x80,0x3, 0x2, +0x39,0xcc,0x7e,0x35,0xd, 0x2e,0x34,0x0, 0x3, 0x7a,0x35,0xd, 0xe5,0xcc,0x54,0x3, +0x68,0x3, 0x2, 0x39,0xdd,0x7e,0x35,0xd, 0xb, 0x34,0x7a,0x35,0xd, 0x7e,0x37,0x27, +0x42,0x4d,0x33,0x78,0x3, 0x2, 0x39,0xee,0x1b,0x34,0x7a,0x37,0x27,0x42,0x7e,0x35, +0xd, 0xbe,0x34,0x2, 0x9b,0x50,0x3, 0x2, 0x3a,0xb, 0x6d,0x33,0x7a,0x35,0xd, 0xe5, +0x9, 0xbe,0xb0,0x64,0x40,0x3, 0x2, 0x3a,0xb, 0x5, 0x9, 0x7e,0x37,0x23,0x80,0xb, +0x34,0x7a,0x37,0x23,0x80,0x7e,0x37,0x23,0x68,0xbe,0x37,0x23,0x80,0x38,0x3, 0x2, +0x3a,0x25,0x12,0x7, 0x7f,0x7e,0x37,0x0, 0x17,0xbe,0x34,0x0, 0x0, 0x38,0x3, 0x2, +0x3a,0x38,0x1b,0x34,0x7a,0x37,0x0, 0x17,0x7e,0xb3,0x29,0xef,0xb4,0xaa,0x2, 0x80, +0x3, 0x2, 0x3a,0x5d,0x7e,0xa3,0x23,0x6a,0x7c,0xba,0x4, 0x7a,0xb3,0x23,0x6a,0xbe, +0xa0,0x64,0x38,0x3, 0x2, 0x3a,0x5d,0x74,0x1, 0x7a,0xb3,0x29,0xef,0xe5,0xc, 0xbe, +0xb1,0xb, 0x38,0x3, 0x2, 0x3a,0x89,0x5, 0xb, 0xe5,0xcc,0x54,0x3, 0xb4,0x3, 0x2, +0x80,0x3, 0x2, 0x3a,0x7b,0xe5,0xb, 0x24,0x3, 0xf5,0xb, 0xe5,0xcc,0x54,0x3, 0x68, +0x3, 0x2, 0x3a,0x8c,0x5, 0xb, 0x2, 0x3a,0x8c,0x75,0xa, 0x1, 0x7e,0xb3,0x29,0xe, +0x70,0x3, 0x2, 0x3a,0xd3,0xbe,0xb0,0x18,0x40,0x3, 0x2, 0x3a,0xcd,0x4, 0x7a,0xb3, +0x29,0xe, 0xe5,0xcc,0x54,0x3, 0xb4,0x3, 0x2, 0x80,0x3, 0x2, 0x3a,0xb8,0x7e,0xb3, +0x29,0xe, 0x24,0x3, 0x7a,0xb3,0x29,0xe, 0xe5,0xcc,0x54,0x3, 0x68,0x3, 0x2, 0x3a, +0xd3,0x7e,0xb3,0x29,0xe, 0x4, 0x7a,0xb3,0x29,0xe, 0x2, 0x3a,0xd3,0x12,0x54,0xb9, +0x12,0x5d,0xd3,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda, +0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x6c,0xaa,0xa, 0x2a,0x9, 0xb2,0x23,0xc3, +0x2d,0x23,0x19,0xb2,0x0, 0xb, 0x7e,0x53,0x23,0x83,0xbc,0x5a,0x38,0x3, 0x2, 0x3b, +0x23,0xa, 0x1a,0x9, 0x41,0x24,0x17,0x2d,0x13,0x19,0x41,0x0, 0x3b,0xa, 0x1a,0x2e, +0x14,0x4e,0xe0,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,0x93,0xa, 0x4a,0x2d,0x43,0x19, +0xb4,0x0, 0x6b,0xbe,0xa0,0x20,0x40,0x3, 0x2, 0x3b,0x43,0x7e,0x10,0x2, 0xac,0x1a, +0x7d,0xf0,0x2e,0xf4,0x4e,0xa0,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x10,0x2d,0x3, 0x59, +0x10,0x0, 0xec,0xb, 0xa0,0xbe,0xa0,0x30,0x78,0xa0,0x74,0x2, 0x19,0xb3,0x0, 0x4, +0x74,0x7f,0x7a,0x39,0xb0,0x7e,0x14,0x0, 0xc8,0x59,0x13,0x1, 0x4c,0x74,0xc8,0x19, +0xb3,0x0, 0x8, 0x74,0x21,0x19,0xb3,0x0, 0x2, 0x53,0xdc,0xe0,0x7e,0x43,0x24,0x6f, +0x7c,0xb4,0x42,0xdc,0x74,0x5d,0x19,0xb3,0x0, 0x3, 0x19,0x53,0x0, 0x5, 0xe4,0x19, +0xb3,0x0, 0xeb,0x7e,0xb3,0x23,0x84,0xa, 0x2b,0x9, 0xb2,0x23,0x6b,0xbe,0xb3,0x23, +0x6c,0x38,0x3, 0x2, 0x3b,0xa5,0x7e,0x33,0x23,0x6c,0x19,0x33,0x0, 0x6, 0x19,0xb3, +0x0, 0x7, 0x2, 0x3b,0xb1,0x19,0xb3,0x0, 0x6, 0x7e,0x53,0x23,0x6c,0x19,0x53,0x0, +0x7, 0x6c,0xaa,0x2, 0x3b,0xc4,0xa, 0x2a,0x9, 0xb2,0x23,0x93,0x2d,0x23,0x19,0xb2, +0x0, 0x9b,0xb, 0xa0,0x7e,0xb3,0x23,0x83,0xbc,0xba,0x38,0xea,0x6c,0xaa,0x2, 0x3c, +0x2b,0xa, 0x2a,0x2e,0x24,0x4e,0x80,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0xa, +0x2a,0x2d,0x23,0x19,0xb2,0x0, 0xcb,0xa, 0x2a,0x2e,0x24,0x4e,0x88,0x7a,0x51,0x82, +0x7a,0x41,0x83,0xe4,0x93,0xa, 0x2a,0x2d,0x23,0x19,0xb2,0x0, 0xd3,0xa, 0x2a,0x2e, +0x24,0x4e,0x90,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0xa, 0x2a,0x2d,0x23,0x19, +0xb2,0x0, 0xdb,0xa, 0x2a,0x2e,0x24,0x4e,0x98,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4, +0x93,0xa, 0x2a,0x2d,0x23,0x19,0xb2,0x0, 0xe3,0xb, 0xa0,0xbe,0xa0,0x0, 0x40,0xa1, +0x22,0xca,0x3b,0x6d,0x0, 0x7a,0x7, 0x22,0xaa,0x7a,0x37,0x22,0xac,0x2e,0x34,0xd, +0x80,0x7a,0x37,0x22,0xae,0x7a,0x27,0x22,0xb0,0x75,0x26,0x0, 0x7e,0x19,0x60,0x1e, +0x60,0x7a,0x61,0x25,0x9, 0x71,0x0, 0x1, 0x1e,0x70,0x7a,0x71,0x24,0x7e,0xf0,0x24, +0xac,0xf6,0xa, 0x47,0x2d,0x74,0x7e,0x73,0x2a,0x11,0xac,0x67,0x2d,0x34,0x7a,0x35, +0x22,0x7d,0x52,0x2e,0x55,0x22,0x7e,0x59,0x70,0xa, 0x57,0x7a,0x57,0x22,0xb2,0x3e, +0x54,0x3e,0x54,0x3e,0x54,0x7a,0x57,0x22,0xb2,0x7d,0x27,0x3e,0x24,0x7d,0x32,0x2e, +0x37,0x22,0xae,0xb, 0x38,0x30,0x2e,0x27,0x22,0xac,0xb, 0x28,0x50,0x2d,0x53,0x2e, +0x57,0x22,0xb2,0x7a,0x57,0x22,0xb4,0x7e,0xa3,0x2a,0x32,0x7e,0xf0,0x24,0xac,0xfa, +0x2d,0x74,0x7a,0xa1,0x21,0x2, 0x3d,0x30,0xe5,0x21,0xbe,0xb1,0x25,0x68,0x3, 0x2, +0x3c,0xc5,0x2, 0x3d,0x2a,0x7e,0x63,0x2a,0x11,0x7e,0x71,0x21,0xac,0x76,0xe5,0x24, +0xa, 0x2b,0x2d,0x32,0x7a,0x35,0x22,0x7e,0x37,0x22,0xb0,0x2e,0x35,0x22,0x7e,0x39, +0x70,0xa, 0x37,0x7a,0x37,0x22,0xb2,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x7a,0x37,0x22, +0xb2,0x7d,0x37,0x3e,0x34,0x7d,0x23,0x2e,0x27,0x22,0xae,0xb, 0x28,0x20,0x2e,0x37, +0x22,0xac,0xb, 0x38,0x30,0x2d,0x32,0x2e,0x37,0x22,0xb2,0x7a,0x37,0x22,0xaa,0x12, +0x5d,0x8a,0x7e,0x53,0x2a,0x18,0xa, 0x65,0x2d,0x63,0x7e,0x37,0x22,0xb4,0x12,0x5d, +0x8a,0xbd,0x36,0x18,0x3, 0x2, 0x3d,0x2a,0x5, 0x26,0x2e,0x74,0x0, 0x24,0x5, 0x21, +0x7e,0x73,0x2a,0x33,0xbe,0x71,0x21,0x28,0x3, 0x2, 0x3c,0xb8,0x7e,0x73,0x2a,0x10, +0x1e,0x70,0xa, 0x27,0xe5,0x26,0xa, 0x3b,0xbd,0x32,0x38,0x3, 0x2, 0x3d,0x56,0x7e, +0x34,0x0, 0x1, 0x2, 0x3d,0x6d,0x7e,0x37,0x2a,0x43,0x7d,0x23,0xb, 0x24,0x7a,0x27, +0x2a,0x43,0xbe,0x34,0x0, 0x64,0x38,0x3, 0x2, 0x3d,0x77,0x6d,0x33,0x7a,0x37,0x2a, +0x3e,0x6d,0x33,0x7a,0x37,0x2a,0x43,0xda,0x3b,0x22,0xca,0xf8,0x7e,0x34,0xe, 0x72, +0x7a,0x37,0x29,0x1b,0x53,0xdb,0xf0,0x12,0x0, 0x2e,0x12,0x5d,0xd3,0x7e,0x34,0x0, +0x3c,0x12,0x45,0xa2,0x7e,0x34,0x1f,0x11,0x12,0x43,0x79,0x7e,0x34,0x1f,0x79,0x12, +0x3a,0xe8,0x7e,0x34,0x1f,0x79,0x12,0x2b,0xb3,0x12,0x5e,0x4a,0x74,0x21,0x7a,0xb3, +0x0, 0xcc,0x53,0xdb,0x7f,0x12,0x5d,0xdf,0x7e,0x73,0x0, 0x3d,0x7a,0x73,0x29,0x6b, +0x7e,0x73,0x0, 0x3c,0x7a,0x73,0x29,0x6a,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34, +0x4, 0x8f,0x7a,0x37,0x23,0x68,0x7e,0x34,0x0, 0xf2,0x12,0x56,0xb0,0x7e,0x34,0x0, +0x3c,0x7e,0x24,0x0, 0xf2,0x12,0x50,0x26,0xe4,0x7a,0xb3,0x0, 0xca,0x7e,0x73,0x24, +0x6f,0x7a,0x73,0x0, 0xcb,0x74,0x3, 0x7a,0xb3,0x29,0x68,0x6d,0x33,0x7a,0x37,0x23, +0x80,0x7e,0x34,0x4, 0x8f,0x7a,0x37,0x23,0x68,0x7e,0xb3,0x29,0x67,0x60,0x3, 0x2, +0x3e,0x47,0x12,0x7, 0x7f,0x74,0x1, 0x7a,0xb3,0x29,0x67,0x7e,0x34,0x78,0x0, 0x12, +0x0, 0x6, 0x7e,0x34,0x7c,0x0, 0x12,0x0, 0x6, 0x7e,0x34,0x0, 0x3c,0x7e,0x24,0x0, +0xf2,0x74,0x4, 0x12,0x36,0xc5,0x6d,0x33,0xe4,0x12,0x5b,0x3b,0x74,0x4, 0x12,0x51, +0xb4,0x74,0xff,0x7a,0xb3,0x29,0x67,0x7e,0xf3,0x29,0x68,0xbe,0xf0,0x3, 0x68,0x3, +0x2, 0x3e,0xaf,0x7e,0xb3,0x29,0x15,0x30,0xe7,0xa1,0x7e,0x34,0x0, 0x3c,0x12,0x45, +0xa2,0x12,0x5e,0x16,0x60,0xfb,0x53,0xdb,0xf0,0x7e,0x34,0x1f,0x11,0x12,0x43,0x79, +0x7e,0x34,0x1f,0x79,0x12,0x3a,0xe8,0x7e,0x34,0x1f,0x79,0x12,0x2b,0xb3,0x12,0x5e, +0x4a,0x74,0x21,0x7a,0xb3,0x0, 0xcc,0xe4,0x7a,0xb3,0x0, 0xca,0x7e,0x34,0x0, 0x3c, +0x7e,0x24,0x0, 0xf2,0x12,0x4d,0x35,0x12,0x5d,0xdf,0x7e,0x34,0xe, 0x72,0x7a,0x37, +0x29,0x1b,0x7e,0xb3,0x29,0x15,0x54,0x7f,0x7a,0xb3,0x29,0x15,0x2, 0x3d,0xfb,0x7a, +0xf3,0x29,0xef,0x12,0x5e,0x16,0x60,0xfb,0xda,0xf8,0x22,0xca,0x69,0xca,0xf8,0x7d, +0xb2,0x7d,0xe3,0x6d,0xaa,0x7d,0xa, 0x6c,0x66,0x7d,0x2a,0x7d,0x4a,0x6c,0xaa,0x7d, +0xfe,0x2e,0xe4,0xd, 0x80,0x7d,0xda,0x7d,0xca,0x6c,0x77,0x7e,0xf3,0x2a,0x34,0x2, +0x3f,0xd0,0x6d,0x22,0x7e,0x44,0x7f,0xff,0x7e,0x63,0x2a,0x32,0x7e,0xd0,0x24,0xac, +0xd6,0xa, 0xdf,0x2d,0xd6,0x80,0x3f,0x7e,0x13,0x2a,0x11,0xac,0x16,0xa, 0xcf,0x2d, +0xc0,0x7d,0xb, 0x2d,0xc, 0x7e,0x9, 0xb0,0xa, 0xab,0x3e,0xa4,0x3e,0xa4,0x3e,0xa4, +0x7d,0xd, 0x3e,0x4, 0x7d,0x90,0x2d,0x9e,0xb, 0x98,0x90,0x2d,0xf, 0xb, 0x8, 0x0, +0x2d,0x9, 0x2d,0xa, 0xbd,0x20,0x50,0x2, 0x7d,0x20,0xbd,0x40,0x28,0x2, 0x7d,0x40, +0x2e,0xd4,0x0, 0x24,0xb, 0x60,0x7e,0xb3,0x2a,0x33,0xbc,0xb6,0x38,0xb9,0x7d,0x92, +0x9d,0x94,0xbe,0x97,0x2a,0x36,0x28,0x3, 0x7e,0xa0,0x1, 0xbe,0xa0,0x1, 0x78,0x46, +0x7e,0xd0,0x4, 0xac,0xdf,0x7d,0x96,0x2d,0x91,0xb, 0x98,0x90,0xbe,0x94,0x0, 0x1, +0x78,0x53,0x7e,0xd0,0x4, 0xac,0xdf,0x2d,0x61,0xb, 0x65,0xb, 0x68,0x90,0x7d,0x89, +0xb, 0x84,0x1b,0x68,0x80,0xbe,0x97,0x2a,0x3c,0x28,0x3a,0x6d,0x99,0x74,0x4, 0xac, +0xbf,0x2d,0x51,0x59,0x95,0x0, 0x2, 0x6d,0x99,0x74,0x4, 0xac,0xbf,0x2d,0x51,0x1b, +0x58,0x90,0x6c,0xaa,0x80,0x1f,0x6d,0x99,0x7e,0xd0,0x4, 0xac,0xdf,0x7d,0x86,0x2d, +0x81,0x59,0x98,0x0, 0x2, 0x7e,0x84,0x0, 0x1, 0x7e,0xd0,0x4, 0xac,0xdf,0x7d,0x96, +0x2d,0x91,0x1b,0x98,0x80,0xbe,0xa0,0x1, 0x78,0x14,0x7e,0xd0,0x4, 0xac,0xdf,0x7d, +0x96,0x2d,0x91,0xb, 0x98,0x90,0xbe,0x94,0x0, 0x1, 0x78,0x2, 0xb, 0x70,0xb, 0xf0, +0x7e,0xb3,0x2a,0x35,0xbc,0xbf,0x28,0x3, 0x2, 0x3e,0xe2,0xbe,0x70,0x0, 0x28,0x3, +0x7e,0xa0,0x1, 0xbe,0xa0,0x1, 0x78,0x6, 0x7e,0x34,0x0, 0x2, 0x80,0x2, 0x6d,0x33, +0x7a,0x37,0x2a,0xa, 0xda,0xf8,0xda,0x69,0x22,0xca,0x3b,0x7e,0xd0,0xff,0x6d,0x33, +0x12,0x5e,0x43,0xf5,0x26,0x7e,0xb3,0x29,0xe8,0x60,0x3, 0x2, 0x40,0x11,0x75,0x26, +0xff,0xe5,0x26,0xbe,0xb0,0xff,0x78,0x3, 0x2, 0x40,0x5a,0x7e,0x34,0x7, 0xf0,0x12, +0x5e,0x43,0xf5,0x25,0x7e,0x34,0x7, 0xf1,0x12,0x5e,0x43,0x7c,0xcb,0x65,0x25,0xbe, +0xb0,0xff,0x78,0x3, 0x2, 0x40,0x3a,0x75,0x26,0xff,0x6c,0xcc,0x6d,0x77,0x7d,0x37, +0xb, 0x36,0x12,0x5e,0x43,0x6c,0xcb,0xb, 0x74,0xbe,0x74,0x3, 0x6f,0x78,0xef,0xbe, +0xc1,0x25,0x78,0x3, 0x2, 0x40,0x5a,0x75,0x26,0xff,0x74,0x20,0x7a,0xb3,0x23,0x83, +0x74,0x14,0x7a,0xb3,0x23,0x84,0x74,0x3, 0x7a,0xb3,0x23,0x85,0x74,0x13,0x7a,0xb3, +0x24,0x6f,0xe4,0x7a,0xb3,0x23,0x86,0x74,0x6d,0x7a,0xb3,0x23,0x87,0x7e,0x34,0x21, +0x34,0x7a,0x37,0x23,0x91,0x7e,0x34,0x5, 0xdc,0x7a,0x37,0x24,0x70,0x75,0x27,0x8a, +0x7e,0x14,0x48,0x98,0x7e,0x4, 0x0, 0xff,0x7e,0x18,0x23,0x93,0x74,0x20,0x12,0x53, +0x1b,0x6c,0xdd,0x7e,0x73,0x23,0x83,0xbc,0x7d,0x28,0x3, 0x2, 0x40,0xb6,0x74,0xff, +0xa, 0x3d,0x19,0xb3,0x23,0x93,0xa, 0x3d,0x2e,0x34,0x49,0xe, 0x7a,0x71,0x82,0x7a, +0x61,0x83,0xe4,0x93,0xa, 0x3d,0x19,0xb3,0x23,0xc3,0x2e,0x34,0x48,0xba,0x7a,0x71, +0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x3d,0x19,0xb3,0x24,0x17,0xb, 0xd0,0xbe,0xd0, +0x30,0x78,0xc0,0x6c,0xdd,0xa, 0x3d,0x2e,0x34,0x48,0xea,0x7a,0x71,0x82,0x7a,0x61, +0x83,0xe4,0x93,0xa, 0x3d,0x19,0xb3,0x23,0xf3,0x2e,0x34,0x49,0x3e,0x7a,0x71,0x82, +0x7a,0x61,0x83,0xe4,0x93,0xa, 0x3d,0x19,0xb3,0x24,0x47,0xb, 0xd0,0xbe,0xd0,0x24, +0x78,0xd3,0x6d,0x77,0xe4,0x19,0xb7,0x24,0x72,0xb, 0x74,0xbe,0x74,0x2, 0x80,0x78, +0xf4,0xe5,0x26,0xbe,0xb0,0xff,0x78,0x3, 0x2, 0x41,0x30,0x74,0x4, 0x12,0x51,0xb4, +0xda,0x3b,0x22,0x7e,0xb3,0x2a,0x8, 0x54,0xfe,0x7a,0xb3,0x2a,0x8, 0x74,0x14,0x7a, +0xb3,0x29,0xc8,0x74,0x3c,0x7a,0xb3,0x29,0xc9,0x74,0xa0,0x7a,0xb3,0x29,0xcd,0x74, +0x1, 0x7a,0xb3,0x29,0xce,0x74,0xa, 0x7a,0xb3,0x29,0xcf,0x74,0x14,0x7a,0xb3,0x29, +0xd0,0x74,0x1b,0x7a,0xb3,0x29,0xd1,0x74,0x32,0x7a,0xb3,0x29,0xdf,0x74,0xff,0x7a, +0xb3,0x29,0xe8,0x74,0x8, 0x7a,0xb3,0x29,0xeb,0x74,0x1, 0x7a,0xb3,0x29,0xec,0xe4, +0x7a,0xb3,0x29,0xed,0x74,0x4, 0x7a,0xb3,0x29,0xee,0x74,0x1, 0x7a,0xb3,0x29,0xef, +0x74,0x5c,0x7a,0xb3,0x29,0xf0,0xe4,0x7a,0xb3,0x29,0xf1,0x7a,0xb3,0x29,0xf2,0x74, +0x2, 0x7a,0xb3,0x29,0xf7,0x74,0xc8,0x7a,0xb3,0x29,0xf6,0x6d,0x0, 0x1b,0x28,0x0, +0x74,0x1, 0x19,0xb2,0x0, 0x2, 0xe4,0x19,0xb2,0x0, 0x9, 0x74,0x5, 0x19,0xb2,0x0, +0x4, 0x74,0x14,0x19,0xb2,0x0, 0x5, 0x74,0x1b,0x19,0xb2,0x0, 0x6, 0x74,0x1b,0x19, +0xb2,0x0, 0x7, 0x74,0xa, 0x19,0xb2,0x0, 0x8, 0x74,0x1, 0x19,0xb2,0x0, 0xa, 0x7e, +0x24,0x0, 0x50,0x1b,0x38,0x20,0x74,0x14,0x19,0xb3,0x0, 0x2, 0x7e,0x24,0x0, 0x3c, +0x59,0x23,0x0, 0x3, 0x7e,0x24,0x7, 0xd0,0x59,0x23,0x0, 0x9, 0xe4,0x19,0xb3,0x0, +0xf, 0x74,0x3, 0x19,0xb3,0x0, 0x10,0x74,0x2, 0x19,0xb3,0x0, 0x11,0x74,0x4, 0x19, +0xb3,0x0, 0x12,0x7e,0x24,0x0, 0x64,0x59,0x23,0x0, 0x13,0x74,0x6, 0x19,0xb3,0x0, +0x15,0x74,0xa, 0x7a,0x19,0xb0,0x7e,0x4, 0xa, 0x0, 0x59,0x1, 0x0, 0x1, 0x74,0xa0, +0x19,0xb1,0x0, 0x3, 0x7e,0x34,0x0, 0xc8,0x7a,0x37,0x2a,0x36,0xe4,0x7a,0xb3,0x2a, +0x32,0x74,0x20,0x7a,0xb3,0x2a,0x33,0xe4,0x7a,0xb3,0x2a,0x34,0x74,0x14,0x7a,0xb3, +0x2a,0x35,0x59,0x31,0x0, 0x4, 0x22,0xca,0x79,0x7d,0x81,0x9, 0xb3,0x0, 0x96,0xf5, +0x25,0x9, 0xa8,0x1e,0x1e,0x7d,0x38,0x7d,0x48,0x2e,0x44,0xd, 0x80,0x7d,0x98,0x2e, +0x94,0x1d,0x40,0x9, 0xb8,0x1e,0x19,0xf5,0x22,0x9, 0xb8,0x1e,0x1a,0xf5,0x23,0x9, +0xb8,0x1e,0x1b,0xf5,0x24,0x9, 0x38,0x1e,0x1c,0x9, 0x28,0x1e,0x1d,0x6c,0x11,0x2, +0x43,0x6c,0x7e,0xf0,0x24,0xac,0xf1,0x7d,0xf7,0x75,0x21,0x0, 0x2, 0x43,0x5e,0x7d, +0xef,0x5e,0xe4,0x0, 0x7, 0x7d,0xde,0x2e,0xd4,0x5e,0x3b,0x7d,0x7d,0x7a,0xf1,0x82, +0x7a,0xe1,0x83,0xe4,0x93,0x7c,0xb, 0x7d,0xdf,0x1e,0xd4,0x1e,0xd4,0x1e,0xd4,0x2d, +0xd9,0x7e,0xd9,0xb0,0x5c,0xb0,0x78,0x3, 0x2, 0x43,0x36,0xe5,0x22,0xbe,0xb1,0x25, +0x40,0x29,0x7d,0xcf,0x3e,0xc4,0x7d,0xdc,0x2d,0xd4,0xb, 0xd8,0xb0,0xa, 0xda,0xbd, +0xbd,0x8, 0x6, 0xe5,0x23,0xa, 0x7b,0x80,0x25,0xa, 0xda,0x6e,0xd4,0xff,0xff,0xb, +0xd4,0xbd,0xbd,0x58,0x65,0xe5,0x24,0xa, 0xbb,0x80,0x2f,0x7d,0xcf,0x3e,0xc4,0x7d, +0xdc,0x2d,0xd4,0xb, 0xd8,0xb0,0xa, 0xda,0xbd,0xbd,0x8, 0x10,0xa, 0x73,0x7d,0xac, +0x2d,0xa3,0xb, 0xa8,0xd0,0x2d,0xd7,0x1b,0xa8,0xd0,0x80,0x3e,0xa, 0xda,0x6e,0xd4, +0xff,0xff,0xb, 0xd4,0xbd,0xbd,0x58,0x32,0xa, 0xb2,0x2d,0xc3,0xb, 0xc8,0xd0,0x9d, +0xdb,0x1b,0xc8,0xd0,0x80,0x24,0x2e,0xe4,0x5e,0x3b,0x7d,0x7e,0x7a,0xf1,0x82,0x7a, +0xe1,0x83,0xe4,0x93,0x7d,0xef,0x1e,0xe4,0x1e,0xe4,0x1e,0xe4,0x2d,0xe8,0x2e,0xe4, +0x1d,0x40,0x7e,0xe9,0x0, 0x4c,0xb, 0x7a,0xe9,0x0, 0xb, 0xf4,0x5, 0x21,0x9, 0x2, +0x0, 0x1, 0xbe,0x1, 0x21,0x28,0x3, 0x2, 0x42,0x9f,0xb, 0x10,0x7e,0x29,0x0, 0xbc, +0x1, 0x28,0x3, 0x2, 0x42,0x92,0xda,0x79,0x22,0x6c,0xaa,0xe4,0xa, 0x2a,0x2d,0x23, +0x19,0xb2,0x0, 0x24,0xa, 0x2a,0x2d,0x23,0x7a,0x29,0xb0,0xb, 0xa0,0xbe,0xa0,0x24, +0x78,0xe9,0x6c,0xaa,0xa, 0x2a,0x9, 0xb2,0x23,0xf3,0x9, 0x52,0x23,0x6c,0x7d,0x12, +0x2d,0x13,0x7a,0x19,0xb0,0xa, 0x1a,0x9, 0xb1,0x24,0x47,0x2d,0x23,0x19,0xb2,0x0, +0x24,0xb, 0xa0,0xbe,0xa0,0x14,0x78,0xdc,0x6c,0xaa,0xa, 0x2a,0x2e,0x24,0x5e,0x2a, +0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0xa, 0x2a,0x2d,0x23,0x19,0xb2,0x0, 0x51, +0xb, 0xa0,0xbe,0xa0,0x9, 0x78,0xe3,0x6c,0xaa,0xe4,0xa, 0x2a,0x2d,0x23,0x19,0xb2, +0x0, 0x5a,0xb, 0xa0,0xbe,0xa0,0x5, 0x78,0xf1,0x6c,0xaa,0x2, 0x44,0x20,0xa, 0x2a, +0x9, 0x42,0x23,0x6c,0x7c,0x54,0x1e,0x50,0x1e,0x50,0x1e,0x50,0x5e,0x40,0x7, 0x7e, +0x30,0x1, 0x7c,0xb4,0x70,0x3, 0x2, 0x44,0xe, 0x3e,0x30,0x14,0x78,0xfb,0xa, 0x45, +0x2d,0x43,0x2e,0x44,0x0, 0x5a,0x7e,0x49,0xb0,0x4c,0xb3,0x7a,0x49,0xb0,0xb, 0xa0, +0x7e,0xb3,0x23,0x84,0xbc,0xba,0x38,0xc6,0x7e,0x53,0x23,0x85,0x19,0x53,0x0, 0x48, +0x7e,0x53,0x23,0xc3,0x19,0x53,0x0, 0x49,0x7e,0x53,0x24,0x17,0x19,0x53,0x0, 0x4a, +0xe4,0x19,0xb3,0x0, 0x4b,0x7e,0x53,0x23,0x87,0x19,0x53,0x0, 0x4c,0x74,0x13,0x19, +0xb3,0x0, 0x4e,0xe4,0x19,0xb3,0x0, 0x50,0x74,0xa, 0x19,0xb3,0x0, 0x4d,0x74,0x1, +0x19,0xb3,0x0, 0x4f,0x74,0x21,0x19,0xb3,0x0, 0x64,0x74,0x23,0x19,0xb3,0x0, 0x65, +0xe4,0x19,0xb3,0x0, 0x63,0x19,0xb3,0x0, 0x62,0x19,0xb3,0x0, 0x61,0x74,0x1, 0x19, +0xb3,0x0, 0x5f,0x74,0x7c,0x19,0xb3,0x0, 0x60,0x74,0x1, 0x19,0xb3,0x0, 0x66,0x74, +0x1, 0x19,0xb3,0x0, 0x67,0x2, 0x4c,0x86,0xca,0x3b,0x7d,0x23,0x7e,0x74,0x2a,0x10, +0x49,0x37,0x0, 0xa, 0x49,0x17,0x0, 0xc, 0x2d,0x31,0x7a,0x37,0x22,0xaa,0x6d,0x33, +0x75,0x21,0x0, 0x75,0x22,0x0, 0x75,0x23,0x0, 0x75,0x24,0x0, 0x2e,0x24,0xd, 0x80, +0x7a,0x27,0x22,0xac,0x6d,0x66,0x9, 0x57,0x0, 0x30,0xa, 0x25,0xbd,0x12,0x28,0x4, +0x7e,0x34,0x0, 0x1, 0xbe,0x34,0x0, 0x1, 0x68,0x3, 0x2, 0x45,0x83,0x75,0x21,0x0, +0x2, 0x45,0x78,0x7e,0xd1,0x21,0x74,0x24,0xac,0xdb,0x75,0x22,0x0, 0x80,0x60,0x7d, +0x36,0x3e,0x34,0x2e,0x37,0x22,0xac,0xb, 0x38,0x30,0xbe,0x34,0x0, 0x0, 0x8, 0x1e, +0x49,0x27,0x0, 0xe, 0xbd,0x32,0x28,0x16,0x7e,0xa1,0x23,0x7c,0xba,0x4, 0xf5,0x23, +0xa, 0x1a,0x9, 0x57,0x0, 0x31,0xa, 0x25,0xbd,0x12,0x50,0x3c,0x80,0x3, 0x75,0x23, +0x0, 0xbe,0x34,0x0, 0x0, 0x58,0x21,0x12,0x5d,0x8a,0x49,0x27,0x0, 0xe, 0xbd,0x32, +0x28,0x16,0x7e,0xa1,0x24,0x7c,0xba,0x4, 0xf5,0x24,0xa, 0x2a,0x9, 0x77,0x0, 0x31, +0xa, 0x37,0xbd,0x23,0x50,0x12,0x80,0x3, 0x75,0x24,0x0, 0xb, 0x64,0x5, 0x22,0x9, +0x77,0x0, 0x1, 0xbe,0x71,0x22,0x38,0x97,0x9, 0x77,0x0, 0x31,0xbe,0x71,0x23,0x28, +0x5, 0xbe,0x71,0x24,0x38,0xa, 0x7e,0x34,0x0, 0x1, 0x59,0x37,0x0, 0x1e,0x80,0x13, +0x75,0x23,0x0, 0x75,0x24,0x0, 0x5, 0x21,0x7e,0x79,0x70,0xbe,0x71,0x21,0x28,0x3, +0x2, 0x44,0xe3,0x49,0x37,0x0, 0x1e,0xbe,0x34,0x0, 0x1, 0x78,0x12,0x49,0x37,0x0, +0x12,0x1e,0x34,0xbe,0x37,0x22,0xaa,0x28,0x6, 0x6d,0x33,0x59,0x37,0x0, 0x1e,0xda, +0x3b,0x22,0xca,0x3b,0x7d,0x73,0x6c,0xdd,0x75,0x25,0xff,0x6c,0xcc,0x74,0x1, 0x19, +0xb7,0x0, 0x8e,0x7e,0x73,0x24,0x6f,0x19,0x77,0x0, 0x8f,0x7e,0x73,0x23,0x83,0x7a, +0x79,0x70,0x7e,0x73,0x23,0x84,0x19,0x77,0x0, 0x1, 0x9, 0xa7,0x0, 0x1, 0x7e,0x79, +0xb0,0xa4,0x59,0x57,0x0, 0x2, 0x6c,0xaa,0x2, 0x45,0xf7,0xa, 0x3a,0x9, 0xb3,0x23, +0x93,0xa, 0x4a,0x2d,0x47,0x19,0xb4,0x0, 0x4, 0x9, 0xb3,0x23,0xc3,0xa, 0x4a,0x2d, +0x47,0x19,0xb4,0x0, 0x59,0xb, 0xa0,0x7e,0x79,0xb0,0xbc,0xba,0x38,0xdd,0x75,0x26, +0x8a,0x7e,0x14,0x48,0x84,0x7e,0x4, 0x0, 0xff,0x7e,0x18,0x22,0xaa,0x74,0x14,0x12, +0x52,0xb0,0x6c,0xaa,0x2, 0x46,0x2d,0xa, 0x3a,0x9, 0xb3,0x22,0xaa,0xa, 0x4a,0x2d, +0x47,0x19,0xb4,0x0, 0x34,0xa, 0x4a,0x19,0xb4,0x23,0x6c,0xb, 0xa0,0x9, 0xb7,0x0, +0x1, 0xbc,0xba,0x38,0xe2,0x6c,0xaa,0x2, 0x46,0x70,0x6c,0xdd,0x2, 0x46,0x53,0xa, +0x3d,0x9, 0xb3,0x22,0xaa,0xbe,0xb1,0x25,0x40,0x3, 0x2, 0x46,0x51,0xf5,0x25,0x7c, +0xcd,0xb, 0xd0,0x7e,0xb3,0x23,0x84,0xbc,0xbd,0x38,0xe4,0x74,0xff,0xa, 0x4c,0x19, +0xb4,0x22,0xaa,0x75,0x25,0xff,0xa, 0x3a,0x2d,0x37,0x19,0xc3,0x0, 0x91,0xb, 0xa0, +0x7e,0xb3,0x23,0x84,0xbc,0xba,0x38,0xc2,0x7e,0x73,0x23,0x86,0x19,0x77,0x0, 0x58, +0x9, 0x77,0x0, 0x59,0x19,0x77,0x0, 0x8d,0x7e,0x73,0x24,0x17,0x19,0x77,0x0, 0x89, +0x7e,0x73,0x23,0x87,0x19,0x77,0x0, 0x8a,0x19,0x77,0x0, 0x8b,0x19,0x77,0x0, 0x8c, +0xe4,0x19,0xb7,0x0, 0xb5,0xda,0x3b,0x22,0x7d,0x1, 0x7d,0x43,0x7e,0x14,0x29,0xc8, +0x7e,0xb3,0x2a,0x8, 0x20,0xe0,0x3, 0x2, 0x47,0xa2,0x54,0xfe,0x7a,0xb3,0x2a,0x8, +0x9, 0x64,0x0, 0x2, 0x7e,0x19,0x70,0xbc,0x76,0x68,0xd, 0x19,0x74,0x0, 0x2, 0xa, +0x37,0x3e,0x34,0x3e,0x34,0x1b,0x48,0x30,0x9, 0x71,0x0, 0x1, 0xa, 0x37,0x49,0x54, +0x0, 0x3, 0xbd,0x35,0x68,0x4, 0x59,0x34,0x0, 0x3, 0x9, 0x60,0x0, 0x3, 0x9, 0x71, +0x0, 0x5, 0xbc,0x76,0x68,0x14,0x19,0x70,0x0, 0x3, 0xa, 0x37,0x3e,0x34,0x3e,0x34, +0x3e,0x34,0x3e,0x34,0x3e,0x34,0x59,0x30,0x0, 0x1, 0x9, 0x71,0x0, 0x2e,0xa, 0x37, +0x49,0x50,0x0, 0x4, 0xbd,0x35,0x68,0x4, 0x59,0x30,0x0, 0x4, 0x9, 0x71,0x0, 0x25, +0xa, 0x37,0xb, 0x28,0x0, 0xbd,0x30,0x68,0x3, 0x1b,0x28,0x30,0x9, 0x62,0x0, 0x2, +0x9, 0x71,0x0, 0x6, 0xbc,0x76,0x68,0x4, 0x19,0x72,0x0, 0x2, 0x9, 0x62,0x0, 0x5, +0x9, 0x71,0x0, 0x8, 0xbc,0x76,0x68,0x16,0x19,0x72,0x0, 0x5, 0xbe,0x70,0xf, 0x40, +0x5, 0xe4,0x19,0xb1,0x0, 0x8, 0x9, 0x72,0x0, 0x5, 0x19,0x72,0x0, 0x4, 0x9, 0x62, +0x0, 0x7, 0x9, 0x71,0x0, 0x9, 0xbc,0x76,0x68,0x8, 0x19,0x72,0x0, 0x7, 0x19,0x72, +0x0, 0x6, 0x9, 0x62,0x0, 0x8, 0x9, 0x71,0x0, 0x7, 0xbc,0x76,0x68,0x4, 0x19,0x72, +0x0, 0x8, 0x9, 0x62,0x0, 0x9, 0x9, 0x71,0x0, 0x29,0xbc,0x76,0x68,0x4, 0x19,0x72, +0x0, 0x9, 0x9, 0x62,0x0, 0xa, 0x9, 0x71,0x0, 0x24,0xbc,0x76,0x68,0x4, 0x19,0x72, +0x0, 0xa, 0x22,0xca,0x79,0x20,0x90,0x3, 0x2, 0x48,0x34,0xc2,0x90,0x7e,0xb3,0x29, +0xf, 0x4, 0x7a,0xb3,0x29,0xf, 0x7e,0xf3,0x29,0xf, 0xbe,0xf0,0x1, 0x78,0x8, 0xe5, +0x91,0x7a,0xb3,0x29,0x19,0x80,0x36,0x7e,0xb3,0x29,0x15,0xc4,0x54,0xf, 0x7c,0xeb, +0x5e,0xe0,0x7, 0x78,0x10,0x7c,0xbf,0x2e,0xb3,0x29,0x19,0x24,0xfe,0x7e,0x71,0x91, +0x12,0x53,0x86,0x80,0x18,0xbe,0xe0,0x4, 0x40,0x13,0xbe,0xe0,0x5, 0x68,0xe, 0x7c, +0xbf,0x2e,0xb3,0x29,0x19,0x24,0xfe,0x7e,0x71,0x91,0x12,0x1c,0xbe,0x7e,0xb3,0x29, +0x15,0xc4,0x54,0xf, 0x7c,0x5b,0x5e,0x50,0x7, 0xa5,0xbd,0x0, 0x14,0xe4,0x12,0x4f, +0x9b,0xbe,0xb0,0x10,0x68,0x1e,0x7e,0xb3,0x29,0x19,0x12,0x4f,0x9b,0xf5,0x91,0x80, +0x13,0xbe,0x50,0x4, 0x40,0xe, 0xbe,0x50,0x5, 0x68,0x9, 0x7e,0xb3,0x29,0x19,0x12, +0x22,0x58,0xf5,0x91,0x30,0x91,0x4a,0xc2,0x91,0x7e,0xb3,0x29,0xd, 0x4, 0x7a,0xb3, +0x29,0xd, 0x7e,0xb3,0x29,0x15,0xc4,0x54,0xf, 0x7c,0x5b,0x5e,0x50,0x7, 0xa5,0xbd, +0x0, 0x18,0xe4,0x12,0x4f,0x9b,0xbe,0xb0,0x10,0x68,0x26,0x7e,0xb3,0x29,0xd, 0x2e, +0xb3,0x29,0x19,0x12,0x4f,0x9b,0xf5,0x91,0x80,0x17,0xbe,0x50,0x4, 0x40,0x12,0xbe, +0x50,0x5, 0x68,0xd, 0x7e,0xb3,0x29,0xd, 0x2e,0xb3,0x29,0x19,0x12,0x22,0x58,0xf5, +0x91,0xda,0x79,0x22,0x13,0x12,0x11,0x10,0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, +0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, +0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, +0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0x1e,0x64,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58,0x58,0x58,0x58,0x58,0x58, +0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58, +0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x28,0x28, +0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, +0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x2d,0x28,0x28, +0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0xa, 0xa, +0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, +0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, +0xa, 0xa, 0x7d,0x43,0x74,0x20,0x7a,0xb3,0x2a,0x10,0x74,0x14,0x7a,0xb3,0x2a,0x11, +0xe4,0x7a,0xb3,0x2a,0x12,0x7a,0xb3,0x2a,0x13,0x7a,0xb3,0x2a,0x14,0x7a,0xb3,0x2a, +0x15,0x7a,0xb3,0x2a,0x16,0x74,0x3, 0x7a,0xb3,0x2a,0x17,0x6d,0x22,0x7a,0x27,0x2a, +0x2e,0x6d,0x33,0x7a,0x37,0x2a,0x1c,0x7a,0x37,0x2a,0x1a,0x7a,0x27,0x2a,0x30,0x7e, +0x54,0x0, 0x64,0x7a,0x57,0x2a,0x1e,0x7e,0x54,0xff,0x9c,0x7a,0x57,0x2a,0x20,0x7e, +0x54,0x0, 0x46,0x7a,0x57,0x2a,0x22,0x7e,0x54,0x0, 0x14,0x7a,0x57,0x2a,0x24,0x7e, +0x54,0x0, 0x1e,0x7a,0x57,0x2a,0x26,0x7a,0x37,0x2a,0x28,0xb, 0x48,0x0, 0x7e,0x14, +0x0, 0x3, 0xad,0x10,0x1e,0x14,0x1e,0x14,0x7a,0x33,0x2a,0x19,0x7a,0x33,0x2a,0x18, +0x7a,0x27,0x2a,0xa, 0x7a,0x27,0x2a,0xc, 0x7a,0x27,0x2a,0xe, 0x7e,0x24,0x1, 0x90, +0x7a,0x27,0x2a,0x3a,0x7a,0x37,0x2a,0x38,0x7e,0x34,0x3, 0xe8,0x7a,0x37,0x2a,0x3c, +0x6c,0xaa,0x6d,0x33,0x7e,0x50,0x4, 0xac,0x5a,0x59,0x32,0x26,0xf4,0x7e,0x34,0x0, +0x1, 0x59,0x32,0x26,0xf2,0xb, 0xa0,0xbe,0xa0,0x14,0x40,0xe6,0x7a,0x37,0x2a,0x3e, +0x74,0x5, 0x7a,0xb3,0x2a,0x40,0x74,0x5, 0x7a,0xb3,0x2a,0x41,0x74,0xa, 0x7a,0xb3, +0x2a,0x42,0x22,0xca,0x79,0x7d,0x73,0x74,0x6, 0x9, 0x77,0x0, 0x49,0x12,0x5b,0x7d, +0x74,0xa, 0x9, 0x77,0x0, 0x4a,0x12,0x5b,0x7d,0x74,0x8, 0x9, 0x77,0x0, 0x50,0x12, +0x5b,0x7d,0x74,0xc, 0x9, 0x77,0x0, 0x4c,0x12,0x5b,0x7d,0x74,0x2a,0x9, 0x77,0x0, +0x4d,0x12,0x5b,0x7d,0x74,0x2e,0x9, 0x77,0x0, 0x4e,0x12,0x5b,0x7d,0x74,0x24,0x9, +0x77,0x0, 0x5f,0x12,0x5b,0x7d,0x74,0x2, 0x9, 0x77,0x0, 0x5b,0x12,0x5b,0x7d,0x74, +0x4, 0x9, 0x77,0x0, 0x5a,0x12,0x5b,0x7d,0x74,0x28,0x12,0x5b,0xde,0x7c,0x7b,0x5e, +0x70,0xf, 0x9, 0xb7,0x0, 0x5e,0xc4,0x54,0xf0,0x2c,0x7b,0x74,0x28,0x12,0x5b,0x7d, +0x74,0x26,0x9, 0x77,0x0, 0x5c,0x12,0x5b,0x7d,0x74,0x30,0x9, 0x77,0x0, 0x5d,0x12, +0x5b,0x7d,0x74,0x1e,0x9, 0x77,0x0, 0x60,0x12,0x5b,0x7d,0x74,0x20,0x9, 0x77,0x0, +0x61,0x12,0x5b,0x7d,0x74,0x22,0x9, 0x77,0x0, 0x62,0x12,0x5b,0x7d,0x74,0x1c,0x9, +0x77,0x0, 0x63,0x12,0x5b,0x7d,0x74,0x18,0x9, 0x77,0x0, 0x64,0x12,0x5b,0x7d,0x74, +0x2e,0x9, 0x77,0x0, 0x65,0x12,0x5b,0x7d,0x74,0x12,0x9, 0x77,0x0, 0x67,0x12,0x5b, +0x7d,0x74,0xe, 0x9, 0x77,0x0, 0x66,0x12,0x5b,0x7d,0xda,0x79,0x22,0x8, 0x9, 0xa, +0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, +0x1b,0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13, +0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x0, 0x1, 0x2, 0x3, +0x4, 0x5, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, +0x1c,0x1d,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x0, 0x1, 0x2, 0x3, +0x4, 0x5, 0x6, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, +0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d, +0x2e,0x2f,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, +0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, +0x1e,0x1f,0x20,0x21,0x22,0x23,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, +0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, +0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, +0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0xc2,0xd5,0x7c,0xb4,0x30,0xe7,0x8, 0xb2,0xd5,0x6e, +0x24,0xff,0xff,0xb, 0x24,0x7c,0xb6,0x30,0xe7,0x12,0xb2,0xd5,0x6e,0x34,0xff,0xff, +0xb, 0x34,0x8d,0x32,0x6e,0x24,0xff,0xff,0xb, 0x24,0x80,0x2, 0x8d,0x32,0x30,0xd5, +0x6, 0x6e,0x34,0xff,0xff,0xb, 0x34,0x22,0x7d,0x51,0xad,0x3, 0x7d,0x2, 0x7d,0x21, +0xad,0x5, 0x2d,0x12,0xad,0x35,0x2d,0x21,0x22,0x7d,0x2, 0xad,0x31,0xad,0x10,0x2d, +0x21,0x22,0x6d,0x0, 0x74,0x10,0x4d,0x0, 0x78,0xb, 0x4d,0x22,0x78,0x27,0x8d,0x31, +0x7d,0x12,0x6d,0x22,0x22,0x7d,0x43,0x7d,0x32,0x6d,0x22,0x2f,0x11,0x2d,0x44,0x50, +0x2, 0xa5,0xf, 0xbf,0x10,0x40,0x4, 0x9f,0x10,0xb, 0x90,0x14,0x78,0xed,0x7f,0x1, +0x6d,0x22,0x7d,0x34,0x22,0x7d,0x41,0x7d,0x13,0x8d,0x24,0x7d,0x2, 0x2f,0x0, 0x40, +0x4, 0xbd,0x4, 0x40,0x4, 0x9d,0x4, 0xb, 0x14,0x14,0x78,0xf1,0x7d,0x23,0x7d,0x31, +0x7d,0x10,0x6d,0x0, 0x22,0x6c,0xaa,0x4d,0x11,0x68,0x1a,0x1e,0x54,0x68,0xe, 0xb, +0x38,0x20,0x1b,0x18,0x20,0xb, 0x35,0xb, 0x15,0x1b,0x54,0x78,0xf2,0x50,0x6, 0x7e, +0x39,0x40,0x7a,0x19,0x40,0x22,0xca,0x3b,0x7d,0x73,0xe4,0x12,0x5e,0x20,0x9, 0xb7, +0x0, 0x48,0x12,0x5c,0xd6,0x74,0x1, 0x12,0x5c,0x1e,0x12,0x5d,0xb8,0x70,0x4, 0xe4, +0x2, 0x4d,0x32,0x74,0x14,0x7e,0x70,0x7f,0x12,0x5d,0x4, 0x70,0x4, 0xe4,0x2, 0x4d, +0x32,0x74,0x10,0x12,0x5b,0xde,0x7c,0x7b,0x5e,0x70,0x3f,0x74,0x10,0x12,0x5b,0x7d, +0x7d,0x37,0x7d,0x27,0x2e,0x24,0x0, 0x24,0x12,0x50,0xac,0x75,0x2a,0x0, 0xe5,0x2a, +0xa, 0x3b,0x2d,0x37,0x9, 0x73,0x0, 0x51,0xa, 0x67,0x2e,0x64,0xc0,0x0, 0xa, 0x5c, +0x7c,0x7d,0x12,0x5a,0x14,0x5, 0x2a,0xe5,0x2a,0xb4,0x9, 0xe2,0x75,0x2a,0x0, 0x7e, +0x71,0x2a,0x74,0x2, 0xac,0x7b,0x2e,0x34,0x2d,0xcd,0x7e,0x24,0x0, 0xff,0xb, 0x1a, +0x60,0xa, 0x5c,0x7c,0x7d,0x12,0x5a,0x14,0x5, 0x2a,0xe5,0x2a,0xb4,0xff,0xe0,0x7e, +0x34,0x2f,0xcb,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,0xa, 0x56,0x12,0x5a,0x14,0x7d, +0x37,0x12,0x4a,0x33,0xe4,0x12,0x5c,0x1e,0x12,0x5d,0xc6,0x60,0x4, 0x74,0x1, 0x80, +0x1, 0xe4,0xda,0x3b,0x22,0x7d,0x43,0x9, 0x14,0x0, 0x1, 0x7e,0x49,0x20,0x9, 0x34, +0x0, 0x8e,0x6c,0xaa,0xa9,0x33,0xdd,0x5, 0xa9,0xc3,0xdd,0x80,0x3, 0xa9,0xd3,0xdd, +0x9, 0xb4,0x0, 0x35,0x9, 0x4, 0x0, 0x34,0xbc,0xb, 0x28,0x3, 0x7e,0xa0,0x1, 0x7a, +0x11,0xc3,0x7a,0x21,0xc4,0x4c,0x33,0x68,0x3f,0x75,0xba,0x40,0x75,0xb9,0x0, 0x7d, +0x32,0xa, 0x16,0x7c,0xb3,0xf5,0xbc,0x7c,0xb7,0xf5,0xbb,0x2e,0x34,0xd, 0x80,0xa, +0x16,0x7c,0xb3,0xf5,0xc1,0x7c,0xb7,0xf5,0xbd,0xbe,0xa0,0x1, 0x78,0x3, 0x75,0xc2, +0x8, 0x43,0xc2,0x3, 0x80,0x3, 0x43,0xc2,0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0xe5,0xc2,0x30,0xe7,0xf0,0x80,0x33,0x75,0xba,0x40,0x75,0xb9,0x0, 0x7d,0x32, +0x2e,0x34,0xd, 0x80,0xa, 0x26,0x7c,0xb5,0xf5,0xc1,0x7c,0xb7,0xf5,0xbd,0xbe,0xa0, +0x1, 0x78,0x3, 0x75,0xc2,0x8, 0x43,0xc2,0x5, 0x80,0x3, 0x43,0xc2,0x1, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5,0xc2,0x30,0xe7,0xf0,0x75,0xc2,0x0, 0xe4,0x22, +0x75,0xdb,0x0, 0xc2,0xc8,0xa9,0xc7,0xcb,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34, +0x4, 0x8f,0x7a,0x37,0x23,0x68,0x12,0x0, 0x58,0x12,0x5e,0x58,0x12,0x5e,0x6a,0x12, +0x5d,0xeb,0x12,0x3f,0xf9,0x74,0x1, 0x7a,0xb3,0x29,0xef,0x7e,0xb3,0x29,0xef,0x24, +0xfd,0x68,0x14,0x14,0x68,0x16,0x24,0xaf,0x68,0x33,0x24,0xab,0x68,0x13,0x24,0xa9, +0x78,0xe9,0x12,0x1f,0xa5,0x80,0xe4,0x12,0x3d,0x7a,0x80,0xdf,0x12,0x54,0x55,0x80, +0xda,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0xb3,0x23,0x82,0xbe,0xb0,0xaa,0x68,0xcb, +0xe4,0x7a,0xb3,0x23,0x6a,0x74,0xaa,0x7a,0xb3,0x23,0x82,0x80,0xbe,0x6d,0x33,0x7a, +0x37,0x23,0x80,0x7e,0xb3,0x23,0x82,0xb4,0xaa,0xb1,0x74,0x55,0x7a,0xb3,0x23,0x82, +0x7e,0x34,0x3, 0xe8,0x7a,0x37,0x0, 0x19,0x7e,0x37,0x0, 0x19,0x7d,0x23,0x1b,0x24, +0x7a,0x27,0x0, 0x19,0x4d,0x33,0x78,0xf0,0x12,0x5c,0x3d,0x75,0xe9,0xff,0x80,0x8b, +0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x17,0x32,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x7d,0x1, 0x7d,0x12,0x7d,0x23,0xbe,0x24,0x0, 0x0, 0x50,0x2, 0x6d,0x22,0xbe,0x14, +0x0, 0x0, 0x50,0x2, 0x6d,0x11,0xbe,0x24,0x0, 0x3f,0x38,0x14,0x7d,0x32,0x3e,0x34, +0x9e,0x34,0x0, 0x3f,0xbe,0x34,0x0, 0x2, 0x58,0x2, 0x6d,0x33,0x7d,0x23,0x80,0x1a, +0xbe,0x24,0x4, 0xc0,0x40,0x14,0x7d,0x32,0x9e,0x34,0x4, 0xc0,0x2d,0x32,0xbe,0x34, +0x4, 0xfd,0x8, 0x4, 0x7e,0x34,0x4, 0xff,0x7d,0x23,0xbe,0x14,0x0, 0x3f,0x38,0x14, +0x7d,0x31,0x3e,0x34,0x9e,0x34,0x0, 0x3f,0xbe,0x34,0x0, 0x2, 0x58,0x2, 0x6d,0x33, +0x7d,0x13,0x80,0x1a,0xbe,0x14,0x7, 0xc0,0x40,0x14,0x7d,0x31,0x9e,0x34,0x7, 0xc0, +0x2d,0x31,0xbe,0x34,0x7, 0xfd,0x8, 0x4, 0x7e,0x34,0x7, 0xff,0x7d,0x13,0x1b,0x8, +0x20,0x7d,0x20,0xb, 0x25,0x7d,0x2, 0x1b,0x28,0x10,0x22,0xbe,0xb0,0x80,0x40,0xc, +0xbe,0xb0,0xbf,0x38,0x7, 0xa, 0x3b,0x9, 0xb3,0x29,0x48,0x22,0x7c,0xab,0xb, 0xa2, +0x68,0x9, 0x1b,0xa2,0x78,0xa, 0x7e,0xb3,0x29,0x15,0x22,0x7e,0xb3,0x29,0xef,0x22, +0xb4,0x3, 0x11,0x30,0x0, 0x6, 0x7e,0x34,0x28,0x89,0x80,0x4, 0x7e,0x34,0x28,0xcb, +0x7a,0x37,0x29,0x17,0xbe,0xb0,0x3, 0x40,0x10,0xbe,0xb0,0x3e,0x38,0xb, 0xa, 0x3b, +0x2e,0x37,0x29,0x17,0x9, 0xb3,0x0, 0x2, 0x22,0x1b,0xb1,0x68,0x1d,0x4, 0x78,0x34, +0x30,0x0, 0x6, 0x7e,0x34,0x28,0x89,0x80,0x4, 0x7e,0x34,0x28,0xcb,0x7a,0x37,0x29, +0x17,0x7e,0x37,0x29,0x17,0x9, 0xb3,0x0, 0x4, 0x22,0x30,0x0, 0x6, 0x7e,0x34,0x28, +0x89,0x80,0x4, 0x7e,0x34,0x28,0xcb,0x7a,0x37,0x29,0x17,0x7e,0x37,0x29,0x17,0x9, +0xb3,0x0, 0x3, 0x22,0xe4,0x22,0xca,0x3b,0x7d,0x62,0x7d,0x73,0x9, 0x77,0x0, 0x8e, +0x7a,0x73,0x22,0xae,0xe4,0x19,0xb7,0x0, 0x8e,0x7d,0x36,0x2e,0x34,0xd, 0x80,0x7a, +0x37,0x22,0xac,0x7a,0x67,0x22,0xaa,0x75,0x29,0x1, 0x12,0x5e,0x16,0x60,0xfb,0x7d, +0x37,0x7d,0x26,0x12,0x4d,0x35,0x12,0x5d,0xdf,0x6d,0x33,0x7a,0x35,0x2c,0x75,0x2a, +0x0, 0x75,0x2b,0x0, 0x7e,0x25,0x2c,0x3e,0x24,0x7d,0x32,0x2e,0x37,0x22,0xac,0xb, +0x38,0x10,0xe, 0x14,0xe, 0x14,0x2e,0x27,0x22,0xaa,0xb, 0x28,0x30,0x2d,0x31,0x1b, +0x28,0x30,0x7e,0x35,0x2c,0xb, 0x34,0x7a,0x35,0x2c,0x5, 0x2b,0xe5,0x2b,0xb4,0x24, +0xd3,0x5, 0x2a,0xe5,0x2a,0xb4,0x30,0xc9,0x5, 0x29,0xe5,0x29,0xbe,0xb0,0x4, 0x28, +0xa9,0x7e,0x73,0x22,0xae,0x19,0x77,0x0, 0x8e,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x72, +0x7d,0x63,0x75,0x2d,0x0, 0xe4,0x7e,0xa1,0x2d,0xa, 0x3a,0x2d,0x36,0x7e,0x39,0x70, +0x12,0x5c,0x58,0x7a,0x35,0x2b,0xe5,0x2d,0x70,0xa, 0x7e,0x35,0x2b,0x4e,0x34,0x20, +0x0, 0x7a,0x35,0x2b,0x7e,0x35,0x2b,0xa, 0x56,0x12,0x5a,0x14,0x5, 0x2d,0xe5,0x2d, +0xb4,0x24,0xd2,0x75,0x2d,0x24,0x80,0x9, 0x74,0xc0,0x6c,0x77,0x12,0x5a,0x14,0x5, +0x2d,0xe5,0x2d,0xbe,0xb0,0x24,0x40,0xf0,0x75,0x2d,0x0, 0xe5,0x2d,0xa, 0x3b,0x2d, +0x37,0x7e,0x39,0xb0,0x9, 0x73,0x0, 0x1, 0x12,0x5c,0xbf,0x7a,0x35,0x2b,0xa, 0x56, +0x12,0x5a,0x14,0x5, 0x2d,0x5, 0x2d,0xe5,0x2d,0xb4,0x24,0xdf,0x75,0x2d,0x12,0x74, +0xc0,0x6c,0x77,0x12,0x5a,0x14,0x5, 0x2d,0xe5,0x2d,0xbe,0xb0,0x13,0x40,0xf0,0xda, +0x3b,0x22,0xca,0x3b,0x7e,0x19,0xa0,0x9, 0x12,0x0, 0x96,0xbe,0x10,0x1, 0x38,0x4, +0x6d,0x33,0x80,0x69,0xa, 0xfa,0x6d,0xee,0x6c,0x0, 0x80,0x3c,0x7e,0x90,0x2, 0xac, +0x90,0x7d,0xd4,0x2d,0xd2,0x7e,0xd9,0x90,0x1e,0x90,0x9, 0x8d,0x0, 0x1, 0x1e,0x80, +0x7e,0xd0,0x48,0xac,0xd9,0x7e,0xf0,0x2, 0xac,0xf8,0x7d,0xb7,0x2d,0xb6,0x2d,0xb3, +0x49,0xdb,0xd, 0x80,0xbe,0xd4,0x0, 0x0, 0x8, 0xc, 0x7d,0x7d,0x1a,0x7e,0x1a,0xce, +0xbf,0x76,0x50,0x2, 0x7f,0x76,0xb, 0x0, 0xbc,0x10,0x38,0xc0,0x49,0x11,0x0, 0x1, +0x7f,0x17,0x12,0x4c,0x9, 0x7f,0x71,0x7c,0x76,0x7c,0x65,0xa, 0x24,0x7f,0x71,0xa, +0x3a,0x6d,0x22,0xbf,0x71,0x50,0x4, 0xa, 0xfa,0x6d,0xee,0x7d,0x3f,0x7a,0x37,0x0, +0x15,0xda,0x3b,0x22,0xca,0x69,0xca,0xf8,0x7c,0xfb,0x7e,0x34,0x24,0x47,0x7a,0x35, +0x27,0x7e,0x34,0x23,0x83,0x7a,0x35,0x29,0x7e,0x34,0x24,0x47,0x9e,0x35,0x29,0x7a, +0x35,0x29,0x6d,0x66,0xa, 0x3f,0x2d,0x36,0x2e,0x35,0x29,0x12,0x5e,0x43,0x7e,0x35, +0x27,0x7a,0x39,0xb0,0x7e,0x35,0x27,0xb, 0x34,0x7a,0x35,0x27,0xb, 0x64,0xbe,0x64, +0x0, 0x24,0x78,0xe0,0x7e,0x34,0x24,0x72,0x7a,0x35,0x27,0x7e,0x34,0x23,0x83,0x7a, +0x35,0x29,0x7e,0x34,0x24,0x72,0x9e,0x35,0x29,0x7a,0x35,0x29,0x6d,0x66,0xa, 0x3f, +0x2d,0x36,0x2e,0x35,0x29,0x12,0x5e,0x43,0x7e,0x35,0x27,0x7a,0x39,0xb0,0x7e,0x35, +0x27,0xb, 0x34,0x7a,0x35,0x27,0xb, 0x64,0xbe,0x64,0x2, 0x80,0x40,0xe0,0xda,0xf8, +0xda,0x69,0x22,0x7d,0x12,0x7d,0x3, 0x6d,0x44,0xe4,0x7a,0x39,0xb0,0xb, 0x34,0xb, +0x44,0xbe,0x44,0x0, 0x99,0x78,0xf2,0x7d,0x31,0x6d,0x44,0xe4,0x7a,0x39,0xb0,0xb, +0x34,0xb, 0x44,0xbe,0x44,0x0, 0x96,0x78,0xf2,0x6d,0x44,0x7e,0x34,0x0, 0x7, 0xad, +0x34,0x2d,0x30,0x2e,0x34,0x0, 0x50,0x12,0x0, 0x46,0x7e,0x34,0x0, 0x7, 0xad,0x34, +0x2d,0x31,0x12,0x0, 0x46,0x7e,0x34,0x0, 0x7, 0xad,0x34,0x2d,0x31,0x2e,0x34,0x0, +0x46,0x12,0x0, 0x46,0xb, 0x44,0xbe,0x44,0x0, 0xa, 0x40,0xcf,0x75,0xb, 0x0, 0x75, +0xc, 0x0, 0x75,0xa, 0x0, 0x75,0x9, 0x0, 0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34, +0x4, 0x8f,0x7a,0x37,0x23,0x68,0xe4,0x7a,0xb3,0x23,0x6a,0x7a,0xb3,0x23,0x82,0x22, +0xca,0x79,0x7c,0xab,0x6c,0x99,0x80,0x5c,0xe5,0x26,0xb4,0x87,0x11,0xa, 0xf9,0x2d, +0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0xa, 0xfb,0x2e,0xf4,0x4b,0x11,0x80,0x31,0xe5,0x26, +0xb4,0x8a,0x11,0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0xa, 0xfb,0x2e,0xf4, +0x4a,0xfd,0x80,0x1b,0xe5,0x26,0xbe,0xb0,0x88,0x68,0x5, 0xe5,0x26,0xb4,0x89,0x28, +0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0xa, 0xfb,0x2e,0xf4,0x4b,0x72,0x7d, +0x7f,0x7a,0xf1,0x82,0x7a,0xe1,0x83,0xe4,0x93,0xa, 0xf9,0x2d,0xf3,0x7d,0xe2,0x7a, +0x7b,0xb0,0xb, 0x90,0xbc,0xa9,0x38,0xa0,0xda,0x79,0x22,0xca,0x79,0x7c,0xab,0x6c, +0x99,0x80,0x5c,0xe5,0x27,0xb4,0x87,0x11,0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b, +0xb0,0xa, 0xfb,0x2e,0xf4,0x4b,0x4c,0x80,0x31,0xe5,0x27,0xb4,0x8a,0x11,0xa, 0xf9, +0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0xa, 0xfb,0x2e,0xf4,0x4b,0x2c,0x80,0x1b,0xe5, +0x27,0xbe,0xb0,0x88,0x68,0x5, 0xe5,0x27,0xb4,0x89,0x28,0xa, 0xf9,0x2d,0xf1,0x7d, +0xe0,0x7e,0x7b,0xb0,0xa, 0xfb,0x2e,0xf4,0x4b,0x96,0x7d,0x7f,0x7a,0xf1,0x82,0x7a, +0xe1,0x83,0xe4,0x93,0xa, 0xf9,0x2d,0xf3,0x7d,0xe2,0x7a,0x7b,0xb0,0xb, 0x90,0xbc, +0xa9,0x38,0xa0,0xda,0x79,0x22,0xca,0x79,0xbe,0xb0,0x80,0x40,0x9, 0xbe,0xb0,0xbf, +0x38,0x4, 0x24,0x80,0x80,0x52,0xb, 0xb2,0x68,0x4c,0x1b,0xb2,0x78,0x4d,0x7e,0x74, +0x29,0x15,0x7a,0x79,0x70,0x5e,0x70,0x70,0x7c,0xb7,0xc4,0x54,0xf, 0x7c,0x7b,0xbe, +0x70,0x4, 0x40,0x1a,0xbe,0x70,0x5, 0x68,0x15,0x7e,0xb3,0x29,0xef,0xb4,0x3, 0x7, +0x74,0x1, 0x7e,0x70,0x3, 0x80,0x13,0x74,0x27,0x7e,0x70,0x3, 0x80,0x1a,0x7e,0xb3, +0x29,0xef,0xb4,0x3, 0xa, 0x74,0x1, 0x7e,0x70,0x1, 0x12,0x56,0xf9,0x80,0xc, 0x74, +0x27,0x7e,0x70,0x1, 0x80,0x2, 0x74,0x27,0x12,0x59,0xba,0xda,0x79,0x22,0xca,0x3b, +0x7c,0xab,0x7d,0x72,0x7d,0x63,0xe5,0x11,0x70,0xd, 0x7e,0x37,0x2a,0xa, 0x4d,0x33, +0x78,0x5, 0x75,0x11,0x1, 0x80,0xa, 0xe5,0x11,0xbe,0xb0,0x1, 0x68,0x3, 0x75,0x11, +0x2, 0x7e,0x37,0x2a,0xa, 0x4d,0x33,0x78,0x36,0xbe,0xa0,0x0, 0x28,0x8, 0x7e,0x37, +0x2a,0x3e,0x4d,0x33,0x68,0x5, 0xe5,0x11,0xb4,0x2, 0x24,0x5, 0x12,0x7e,0x73,0x2a, +0x42,0xbe,0x71,0x12,0x50,0x1c,0x75,0x12,0x0, 0x7d,0x37,0x12,0x56,0xb0,0x7d,0x36, +0x7d,0x27,0x12,0x50,0x26,0xe5,0x11,0xb4,0x2, 0x8, 0x75,0x11,0x1, 0x80,0x3, 0x75, +0x12,0x0, 0xda,0x3b,0x22,0x6d,0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x4, 0x8f,0x7a, +0x37,0x23,0x68,0x53,0xdb,0xf0,0x7e,0x34,0x0, 0x3c,0x12,0x45,0xa2,0x7e,0x34,0x1f, +0x11,0x12,0x43,0x79,0x7e,0x34,0x1f,0x79,0x12,0x3a,0xe8,0x7e,0x34,0x1f,0x79,0x12, +0x2b,0xb3,0x12,0x5e,0x4a,0x12,0x5d,0xdf,0x7e,0x34,0x1, 0x2c,0x7a,0x37,0x24,0x70, +0x7e,0x34,0x23,0x83,0x7e,0x24,0x0, 0x3c,0x7e,0x14,0x0, 0xf2,0x7e,0x4, 0x1f,0x11, +0x12,0x29,0x89,0x12,0x5e,0x16,0x60,0xfb,0x74,0x1, 0x7a,0xb3,0x29,0xef,0x7e,0xb3, +0x29,0x15,0x54,0x8f,0x7a,0xb3,0x29,0x15,0x22,0xca,0xf8,0x6d,0x33,0x7a,0x37,0x29, +0x13,0xe4,0x7a,0xb3,0x29,0xd, 0x7e,0xb3,0x29,0x15,0xc4,0x54,0xf, 0x7c,0xfb,0x5e, +0xf0,0x7, 0x78,0xb, 0x7e,0xb3,0x29,0x19,0x12,0x4f,0x9b,0xf5,0x91,0x80,0x13,0xbe, +0xf0,0x4, 0x40,0xe, 0xbe,0xf0,0x5, 0x68,0x9, 0x7e,0xb3,0x29,0x19,0x12,0x22,0x58, +0xf5,0x91,0xe4,0x7a,0xb3,0x29,0xf, 0x7a,0xb3,0x29,0xe, 0x74,0xaa,0x7a,0xb3,0x28, +0x89,0x74,0xaa,0x7a,0xb3,0x28,0x8a,0x74,0xaa,0x7a,0xb3,0x28,0xcb,0x74,0xaa,0x7a, +0xb3,0x28,0xcc,0xda,0xf8,0x22,0x75,0x84,0x1, 0x7e,0x44,0x4, 0x1f,0xe4,0x7a,0x49, +0xb0,0x1b,0x44,0x78,0xf9,0x7e,0xf8,0x2a,0x44,0x75,0x13,0x0, 0x75,0x14,0x0, 0x75, +0x8, 0x0, 0xc2,0x0, 0x75,0xd, 0x0, 0x75,0xe, 0x0, 0xc2,0x1, 0x75,0x11,0x0, 0x75, +0x12,0x0, 0x7e,0x4, 0x0, 0xff,0x7e,0x14,0x5e,0x6d,0xb, 0xa, 0x40,0x5d,0x44,0x68, +0x1a,0x69,0x20,0x0, 0x2, 0xb, 0xe, 0xb, 0x44,0x80,0xa, 0x7e,0xb, 0xb0,0x7a,0x29, +0xb0,0xb, 0x24,0xb, 0xc, 0x1b,0x44,0x78,0xf2,0x80,0xdf,0x2, 0x4d,0xe0,0xca,0x3b, +0x7a,0x5, 0x23,0x7a,0x15,0x21,0x7d,0x72,0x7d,0x63,0x12,0x5a,0x66,0x9, 0x76,0x0, +0x96,0x19,0x77,0x0, 0x8e,0x7d,0x37,0x12,0x59,0x4a,0x7d,0x37,0x12,0x58,0xd, 0x9, +0x77,0x0, 0x8e,0x19,0x76,0x0, 0x96,0x7e,0x35,0x21,0x7e,0x25,0x23,0x59,0x32,0x0, +0x84,0x7e,0x35,0x23,0x7d,0x26,0x12,0x56,0x65,0x7e,0x35,0x23,0x59,0x37,0x0, 0x93, +0x9, 0x76,0x0, 0x96,0x19,0x77,0x0, 0x8e,0x7d,0x36,0x7e,0x25,0x21,0x7d,0x17,0x12, +0xd, 0xf9,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x60,0x7a,0x15,0x23,0x7a,0x25,0x21,0x7d, +0x73,0x12,0x5b,0xbe,0x53,0xdb,0xf0,0x12,0x3f,0xf9,0x7d,0x37,0x12,0x45,0xa2,0x7e, +0x35,0x21,0x12,0x43,0x79,0x74,0x21,0x19,0xb7,0x0, 0x90,0x7d,0x36,0x12,0x3a,0xe8, +0x12,0x2b,0xb3,0x12,0x5e,0x4a,0x12,0x5d,0xdf,0x7e,0x35,0x23,0x12,0x56,0xb0,0x6d, +0x33,0x7a,0x37,0x23,0x80,0x7e,0x34,0x4, 0x8f,0x7a,0x37,0x23,0x68,0x7d,0x37,0x7e, +0x25,0x23,0x12,0x50,0x26,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x71,0x7d,0x62,0x9, 0xb3, +0x0, 0x96,0x70,0x6, 0x74,0x1, 0x7a,0xb3,0x2a,0x9, 0x7e,0xb3,0x2a,0x9, 0x70,0x2c, +0x7e,0x37,0x2a,0x38,0x7d,0x23,0xb, 0x24,0x7a,0x27,0x2a,0x38,0xbe,0x37,0x2a,0x3a, +0x28,0x20,0x6d,0x33,0x7a,0x37,0x2a,0x38,0x74,0x1, 0x7a,0xb3,0x2a,0x9, 0x7d,0x37, +0x12,0x56,0xb0,0x7d,0x36,0x7d,0x27,0x12,0x50,0x26,0x80,0x6, 0x6d,0x33,0x7a,0x37, +0x2a,0x38,0xda,0x3b,0x22,0xca,0x3b,0x7d,0x72,0x7d,0x63,0x9, 0x77,0x0, 0x96,0x19, +0x76,0x0, 0x82,0x2e,0x24,0x0, 0x50,0x7d,0x36,0x7e,0x14,0x0, 0x46,0x12,0x5d,0x1b, +0x7d,0x36,0x12,0x13,0x5b,0x7d,0x36,0x49,0x26,0x0, 0x84,0x12,0x2f,0xcd,0x7d,0x26, +0x7d,0x37,0x2e,0x34,0x0, 0x50,0x7e,0x14,0x0, 0x46,0x12,0x5d,0x1b,0x9, 0x76,0x0, +0x82,0x19,0x76,0x0, 0x83,0x9, 0x76,0x0, 0x82,0x19,0x77,0x0, 0x96,0xda,0x3b,0x22, +0x7d,0x23,0x2e,0x24,0x1d,0x40,0x6d,0x11,0x7e,0xa0,0x30,0x6c,0x11,0x6d,0xff,0x7d, +0x41,0x3e,0x44,0x2d,0x43,0x1b,0x48,0xf0,0x7d,0x41,0x5e,0x44,0x0, 0x7, 0x2e,0x44, +0x5e,0x3b,0x7a,0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0x7d,0x41,0x1e,0x44,0x1e,0x44, +0x1e,0x44,0x2d,0x42,0x7e,0x49,0x0, 0x4c,0xb, 0x7a,0x49,0x0, 0xb, 0x14,0xb, 0x10, +0xa5,0xb9,0x24,0xc9,0x1b,0xa0,0x78,0xc3,0x22,0xca,0x79,0xbe,0xb0,0xa, 0x50,0x8, +0xa, 0x2b,0x19,0x72,0x29,0x67,0x80,0x35,0xa, 0x7b,0x9e,0x74,0x0, 0xa, 0xbe,0x74, +0x3, 0x6f,0x50,0x29,0xbe,0x74,0x0, 0x4f,0x78,0x5, 0x12,0x5c,0x8d,0x80,0x1e,0xbe, +0x74,0x0, 0x10,0x40,0x14,0xbe,0x74,0x0, 0x30,0x38,0xe, 0x7c,0xb7,0x7e,0x70,0x8a, +0x12,0x57,0x87,0x19,0xb7,0x23,0x83,0x80,0x4, 0x19,0x77,0x23,0x83,0xda,0x79,0x22, +0x7e,0x27,0x2a,0x2e,0x4d,0x22,0x78,0x1b,0xe4,0x7a,0xb3,0x2a,0x12,0x7a,0xb3,0x2a, +0x13,0x7a,0xb3,0x2a,0x14,0x7a,0xb3,0x2a,0x15,0x7a,0xb3,0x2a,0x16,0x6d,0x22,0x7a, +0x27,0x2a,0x30,0x7e,0x27,0x2a,0x30,0x4d,0x22,0x78,0x1b,0x7e,0x27,0x2a,0x2e,0xbe, +0x24,0x0, 0x1, 0x78,0x11,0x12,0x38,0x30,0x7e,0x34,0x0, 0x1, 0x7a,0x37,0x2a,0x30, +0x74,0x1, 0x7a,0xb3,0x2a,0x16,0x22,0x7c,0xab,0xa5,0xbf,0x87,0x15,0xbe,0xa0,0x1c, +0x40,0x5, 0x2e,0xa0,0xa, 0x80,0x8, 0xbe,0xa0,0x7, 0x40,0x3, 0x2e,0xa0,0x5, 0x7c, +0xba,0x22,0xa5,0xbf,0x8a,0x15,0xbe,0xa0,0x16,0x40,0x5, 0x2e,0xa0,0xf, 0x80,0x8, +0xbe,0xa0,0x6, 0x40,0x3, 0x2e,0xa0,0x8, 0x7c,0xba,0x22,0xbe,0x70,0x88,0x68,0x4, +0xa5,0xbf,0x89,0x3, 0x7c,0xba,0x22,0x74,0xff,0x22,0x7c,0xab,0xa5,0xbf,0x87,0x15, +0xbe,0xa0,0x26,0x40,0x5, 0x9e,0xa0,0xa, 0x80,0x8, 0xbe,0xa0,0xc, 0x40,0x3, 0x9e, +0xa0,0x5, 0x7c,0xba,0x22,0xa5,0xbf,0x8a,0x15,0xbe,0xa0,0x25,0x40,0x5, 0x9e,0xa0, +0xf, 0x80,0x8, 0xbe,0xa0,0xe, 0x40,0x3, 0x9e,0xa0,0x8, 0x7c,0xba,0x22,0xbe,0x70, +0x88,0x68,0x4, 0xa5,0xbf,0x89,0x3, 0x7c,0xba,0x22,0x74,0xff,0x22,0x9, 0xa3,0x0, +0x8f,0xbe,0xa0,0x0, 0x38,0x38,0x9, 0xb3,0x0, 0x8e,0xbc,0xba,0x28,0x19,0x9, 0xb3, +0x0, 0x95,0xbe,0xb3,0x0, 0x1b,0x28,0x14,0x7e,0xb3,0x0, 0x1b,0x4, 0x7a,0xb3,0x0, +0x1b,0x19,0xa3,0x0, 0x8e,0x80,0x5, 0xe4,0x7a,0xb3,0x0, 0x1b,0x9, 0xb3,0x0, 0x8e, +0x70,0xc, 0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xfe,0x7a,0x39,0xb0,0x22,0xc2, +0xaf,0x75,0xf3,0x0, 0xa, 0x56,0x1e,0x54,0x1e,0x54,0x3e,0x54,0x3e,0x54,0xf5,0xf1, +0x75,0xf2,0x0, 0x75,0xf9,0x0, 0x75,0xf9,0x10,0x75,0xf9,0x50,0x74,0xa, 0x12,0x5c, +0xa6,0x75,0xf9,0x51,0x74,0x32,0x12,0x5a,0x8d,0x75,0xf9,0x11,0x74,0xa, 0x12,0x5c, +0xa6,0x75,0xf9,0x10,0x75,0xf9,0x0, 0x74,0x1, 0x12,0x5c,0xa6,0xd2,0xaf,0x22,0xca, +0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0, +0x83,0xc0,0x82,0xe5,0xcc,0x54,0x3, 0xb4,0x3, 0x6, 0x53,0xcc,0xfc,0x43,0xcc,0x2, +0x12,0x47,0xa3,0x74,0x1, 0x7a,0xb3,0x29,0xe, 0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x6c,0xaa, +0x74,0x3, 0xa, 0x2a,0x2d,0x23,0x19,0xb2,0x0, 0x50,0x74,0x3, 0xa, 0x2a,0x2d,0x23, +0x19,0xb2,0x0, 0x46,0x7e,0x24,0x7f,0xff,0x7e,0x30,0x2, 0xac,0x3a,0x7d,0x1, 0x2d, +0x3, 0x59,0x20,0x0, 0x5a,0x2d,0x13,0x59,0x21,0x0, 0x6e,0xb, 0xa0,0xbe,0xa0,0xa, +0x40,0xce,0xe4,0x19,0xb3,0x0, 0x82,0x19,0xb3,0x0, 0x83,0x22,0x6c,0xaa,0x7e,0x14, +0x0, 0x1, 0x7e,0x53,0x2a,0x34,0x80,0x12,0x7e,0x10,0x4, 0xac,0x15,0x2d,0x3, 0xb, +0x8, 0x0, 0x4d,0x0, 0x78,0x2, 0xb, 0xa0,0xb, 0x50,0x7e,0x43,0x2a,0x35,0xbc,0x45, +0x38,0xe6,0x7e,0xb3,0x2a,0x11,0xa, 0x3b,0x7e,0x24,0x0, 0x3, 0x12,0x4b,0xc6,0xa, +0xa, 0xbd,0x3, 0x8, 0x2, 0x6d,0x11,0x7d,0x31,0x22,0x9, 0xb3,0x0, 0x8e,0x70,0x24, +0x9, 0xa3,0x0, 0x8f,0xbe,0xa0,0x0, 0x28,0x1b,0xe5,0x14,0x70,0x13,0x19,0xa3,0x0, +0x8e,0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x44,0x8, 0x7a,0x39,0xb0,0x5, 0x14,0x22, +0x75,0x14,0x0, 0x22,0x75,0x14,0x0, 0x2e,0x34,0x0, 0x92,0x7e,0x39,0xb0,0x54,0xf7, +0x7a,0x39,0xb0,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b, +0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x5e,0xc, 0x7e,0xb3,0x29,0x15,0x54, +0xfd,0x7a,0xb3,0x29,0x15,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda, +0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0xbe,0xb0,0x3f,0x38,0x27,0x7c, +0x6b,0x2e,0x60,0xdd,0x68,0x20,0x2e,0x60,0xfd,0x68,0x1b,0x1b,0x61,0x68,0x17,0x2e, +0x60,0xf9,0x68,0x12,0x80,0x0, 0xa, 0x2b,0x19,0x72,0x29,0xc8,0x7e,0xb3,0x2a,0x8, +0x44,0x1, 0x7a,0xb3,0x2a,0x8, 0x22,0x7c,0xab,0xc2,0xaf,0xa, 0x26,0x7c,0xb5,0xf5, +0xf1,0x7c,0xb7,0xf5,0xf2,0x75,0xf3,0x80,0x75,0xf4,0x0, 0x75,0xf5,0x0, 0x7a,0xa1, +0xf6,0xa9,0x37,0xf5,0xfc,0xa9,0x36,0xf5,0xfc,0x74,0xa, 0x12,0x5c,0xa6,0x43,0xfa, +0x80,0xd2,0xaf,0x22,0x53,0xd7,0x3, 0x53,0xdb,0xf3,0xf5,0xd6,0xe5,0xdb,0x30,0xe3, +0xfb,0xe5,0xd6,0xf5,0xf, 0x53,0xdb,0xf3,0x7a,0x71,0xd6,0xe5,0xdb,0x30,0xe3,0xfb, +0xe5,0xd6,0xf5,0x10,0x53,0xdb,0xf3,0x43,0xd7,0x4, 0x7e,0x35,0xf, 0x22,0xc2,0xaf, +0xa, 0x56,0xf5,0xf1,0x7c,0xb7,0xf5,0xf2,0x75,0xf3,0x80,0x75,0xf4,0x0, 0x75,0xf5, +0x1, 0xa9,0x37,0xf5,0xfc,0xa9,0x36,0xf5,0xfc,0x74,0x2, 0x12,0x5c,0xa6,0xe5,0xf6, +0x43,0xfa,0x80,0xd2,0xaf,0x22,0x7d,0x43,0x6c,0xaa,0x80,0x18,0x7e,0x30,0x7, 0xac, +0x3a,0x2d,0x14,0x49,0x31,0x0, 0x50,0x49,0x21,0x0, 0x52,0x2e,0x14,0x0, 0x50,0x12, +0x4f,0x10,0xb, 0xa0,0x9, 0xb4,0x0, 0x96,0xbc,0xba,0x38,0xe0,0x22,0x7c,0x6b,0x80, +0x19,0x74,0xfa,0x12,0x5c,0xa6,0x74,0xfa,0x12,0x5c,0xa6,0x74,0xfa,0x12,0x5c,0xa6, +0x74,0xfa,0x12,0x5c,0xa6,0x74,0xfa,0x12,0x5c,0xa6,0x7c,0x76,0x1b,0x60,0xa5,0xbf, +0x0, 0xdf,0x22,0xbe,0x34,0x0, 0x4, 0x40,0x4, 0x1b,0x36,0x80,0x2, 0x6d,0x33,0x7e, +0x24,0x0, 0xa2,0xad,0x32,0x7c,0x76,0x7c,0x65,0xa, 0x24,0xbe,0x18,0x5, 0x0, 0x40, +0x4, 0x7e,0x18,0x4, 0xff,0x22,0x74,0x1, 0x19,0xb3,0x1e,0x19,0x74,0x2, 0x19,0xb3, +0x1e,0x1a,0x74,0x2, 0x19,0xb3,0x1e,0x1b,0xe4,0x19,0xb3,0x1e,0x1c,0x19,0xb3,0x1e, +0x1d,0x74,0x20,0x19,0xb3,0x1e,0x1e,0x22,0x74,0x3c,0x7a,0x39,0xb0,0x74,0x7, 0x19, +0xb3,0x0, 0x3, 0x7e,0x24,0x0, 0x99,0x59,0x23,0x0, 0x1, 0x7e,0x24,0x0, 0x96,0x59, +0x23,0x0, 0x4, 0x74,0x5, 0x19,0xb3,0x0, 0x6, 0x22,0xa9,0xc6,0xdb,0x74,0x1, 0x12, +0x5b,0x9e,0xa9,0xc6,0xeb,0xa9,0xd6,0xac,0xa9,0xd6,0xec,0xd2,0x86,0x75,0x9a,0xd0, +0xa9,0xd1,0x99,0xd2,0x9c,0xa9,0xd6,0xdf,0xd2,0xaf,0x22,0xca,0x69,0xca,0xf8,0x7c, +0xfb,0x7d,0x63,0x74,0x1, 0x12,0x5c,0x73,0x7d,0x36,0x2e,0x34,0x78,0x0, 0x7c,0xbf, +0x12,0x59,0xe7,0xe4,0x12,0x5c,0x73,0xda,0xf8,0xda,0x69,0x22,0xbe,0x34,0x0, 0x0, +0x40,0x2, 0x80,0x2, 0x6d,0x33,0x7e,0x24,0x0, 0xa2,0xad,0x32,0x7c,0x76,0x7c,0x65, +0xa, 0x24,0xbe,0x18,0x3, 0x20,0x40,0x4, 0x7e,0x18,0x3, 0x1f,0x22,0x53,0xd7,0x3, +0x53,0xdb,0xf3,0x44,0x40,0xf5,0xd6,0xe5,0xdb,0x30,0xe3,0xfb,0x53,0xdb,0xf3,0x7a, +0x71,0xd6,0xe5,0xdb,0x30,0xe3,0xfb,0x53,0xdb,0xf3,0x43,0xd7,0x4, 0x22,0xd2,0xcf, +0x53,0xcc,0xfc,0x1b,0xb1,0x68,0xc, 0x14,0x68,0xe, 0xb, 0xb1,0x78,0xd, 0x43,0xcc, +0x2, 0x80,0x8, 0x43,0xcc,0x3, 0x80,0x3, 0x43,0xcc,0x1, 0xc2,0xca,0x22,0x6c,0x77, +0x6d,0x22,0x80,0xe, 0xb, 0x70,0xa5,0xbf,0xff,0x2, 0xb, 0x24,0xbe,0x24,0x3, 0xe8, +0x68,0x3, 0x30,0x1, 0xef,0x53,0xdb,0xfe,0x53,0xdb,0xfd,0xc2,0xeb,0x22,0x53,0xd7, +0x3, 0x53,0xdb,0xf3,0x44,0x80,0xf5,0xd6,0xe5,0xdb,0x30,0xe3,0xfb,0x53,0xdb,0xf3, +0x75,0xd6,0x0, 0xe5,0xdb,0x30,0xe3,0xfb,0xe5,0xd6,0x43,0xd7,0x4, 0x22,0x9, 0x73, +0x0, 0x96,0xbe,0x70,0x1, 0x38,0xa, 0x7e,0x37,0x2a,0xa, 0xbe,0x34,0x0, 0x2, 0x78, +0x4, 0x6d,0x33,0x80,0x4, 0x7e,0x34,0x0, 0x1, 0x7a,0x37,0x2a,0xe, 0x22,0xbe,0xb0, +0x3, 0x28,0x9, 0xbe,0xb0,0x20,0x50,0x4, 0x7c,0xab,0x80,0x2, 0x6c,0xaa,0xe5,0xdc, +0x54,0xe0,0xa, 0x2b,0xa, 0x3a,0x2d,0x32,0x7c,0xb7,0xf5,0xdc,0x22,0x74,0x1, 0x12, +0x5c,0x73,0x7e,0x34,0x6f,0xf8,0x74,0x66,0x12,0x59,0xe7,0x7e,0x34,0x6f,0xf9,0x74, +0xbb,0x12,0x59,0xe7,0xe4,0x2, 0x5c,0x73,0x7c,0xa7,0xa, 0x3b,0x3e,0x34,0x3e,0x34, +0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x2e,0x34,0xc0,0x0, 0xa, 0x2a, +0x2d,0x32,0x22,0x75,0xfd,0xd, 0xb4,0x1, 0xa, 0x75,0xfe,0x84,0x75,0xfd,0xf, 0x75, +0xfe,0x28,0x22,0x75,0xfe,0x0, 0x75,0xfd,0xf, 0x75,0xfe,0x0, 0x22,0x7e,0xb3,0x29, +0x77,0x60,0x8, 0x74,0x1, 0x12,0x5e,0x33,0xe4,0x80,0x6, 0xe4,0x12,0x5e,0x33,0x74, +0x1, 0x7a,0xb3,0x29,0x77,0x22,0x7c,0xab,0x80,0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c,0x7a,0x1b,0xa0,0xa5,0xbf,0x0, 0xec,0x22,0xa, +0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x2e,0x34,0xc0, +0x0, 0xa, 0x2b,0x2d,0x32,0x22,0x53,0xcb,0xe0,0x43,0xcb,0x6, 0x53,0xca,0xf0,0xa, +0x3b,0x3e,0x34,0xb, 0x34,0x7c,0xb7,0x42,0xca,0x75,0xea,0x7, 0x22,0x43,0xdb,0x10, +0xd2,0xd9,0xc2,0xdd,0xc2,0xdc,0xc2,0xdb,0xc2,0xda,0xd2,0xd8,0x75,0xd7,0x6, 0xc2, +0xea,0x2, 0x5d,0xa9,0x7c,0x67,0x7c,0xab,0x12,0x5b,0x7d,0x7c,0xba,0x12,0x5b,0xde, +0x7c,0x7b,0xbc,0x67,0x78,0x3, 0x74,0x1, 0x22,0xe4,0x22,0x7d,0x3, 0x80,0xa, 0x7e, +0x29,0xb0,0x7a,0x9, 0xb0,0xb, 0x24,0xb, 0x4, 0x7d,0x51,0x1b,0x14,0x4d,0x55,0x78, +0xee,0x22,0x7c,0xa6,0x7c,0x57,0xa, 0x3b,0xa, 0x25,0x12,0x5d,0x7a,0xa, 0x2a,0xbd, +0x32,0x38,0x3, 0x74,0x1, 0x22,0xe4,0x22,0x70,0x3, 0x43,0x87,0x1, 0xb4,0x1, 0x3, +0x43,0x87,0x2, 0xb4,0x2, 0x3, 0x43,0x87,0x2, 0x22,0xca,0xb8,0xc2,0x92,0xe4,0x7a, +0xb3,0x29,0xd, 0x7a,0xb3,0x29,0xf, 0xda,0xb8,0x32,0xc2,0x8e,0x43,0x89,0x10,0x75, +0x8d,0xe8,0x75,0x8b,0x8f,0xd2,0x8e,0xd2,0xab,0x22,0x7d,0x13,0xbd,0x21,0x50,0x5, +0x7d,0x31,0x9d,0x32,0x22,0x7d,0x32,0x9d,0x31,0x22,0x7d,0x23,0xbe,0x24,0x0, 0x0, +0x48,0x3, 0x7d,0x32,0x22,0x6d,0x33,0x9d,0x32,0x22,0x75,0x92,0x70,0xd2,0xad,0xd2, +0xe8,0xc2,0xc0,0xa9,0xd5,0xb7,0xc2,0xbd,0x22,0xc2,0x1, 0x53,0xdb,0xfd,0xd2,0xeb, +0xc2,0xc3,0xa9,0xd3,0xf7,0xd2,0xfb,0x22,0xe4,0x7e,0x70,0x3, 0x12,0x5d,0x4, 0x60, +0x3, 0x74,0x1, 0x22,0xe4,0x22,0xe4,0x6c,0x77,0x12,0x5d,0x4, 0x60,0x3, 0x74,0x1, +0x22,0xe4,0x22,0x6d,0x33,0x7a,0x37,0x29,0x71,0xe4,0x7a,0xb3,0x29,0x1a,0x22,0x53, +0xdb,0xfd,0xd2,0xeb,0x43,0xdb,0x1, 0x43,0xdb,0x20,0x22,0xe4,0x7a,0xb3,0x29,0x15, +0x12,0x5e,0x64,0x2, 0x54,0xb9,0xc2,0x8e,0x75,0x8d,0xe8,0x75,0x8b,0x8f,0xd2,0x8e, +0x22,0xd2,0x1, 0xa9,0xc1,0xdb,0xc2,0xc3,0x53,0xdb,0xbf,0x32,0xe5,0x9a,0x60,0x5, +0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0x30,0x1, 0x5, 0xc2,0x1, 0x74,0x1, 0x22,0xe4,0x22, +0x70,0x4, 0x53,0xdb,0xbf,0x22,0x43,0xdb,0x40,0x22,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x70,0x3, 0xd2,0x86,0x22,0xc2,0x86,0x22,0x1, 0x2, 0x4, 0x8, 0x10, +0x20,0x40,0x80,0x2e,0x34,0x78,0x0, 0x2, 0x5a,0x3e,0x75,0xd9,0x2, 0x75,0xda,0x7d, +0x22,0xa9,0xd0,0x99,0xa9,0xc6,0xdf,0x22,0x12,0x5b,0x1a,0x2, 0x0, 0x40,0xf5,0xd9, +0x7a,0x71,0xda,0x22,0x2, 0x5d,0x9a,0xc2,0xec,0x32,0x2, 0x5c,0xed,0x0, 0x1, 0x29, +0x77,0x1, 0x0, 0x1, 0x23,0x6b,0x0, 0x0, 0x2, 0x27,0x42,0x0, 0x0, 0x0, 0x1, 0x29, +0xd, 0x0, 0x0, 0x1, 0x29,0xf, 0x0, 0x0, 0x1, 0x29,0x12,0x0, 0x0, 0x2, 0x29,0x13, +0x0, 0x0, 0x0, 0x1, 0x29,0x16,0x0, 0x0, 0x1, 0x29,0x19,0x0, 0x0, 0xe1,0x27,0xa8, +0x0, 0x1, 0x2, 0x3, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x1, 0x0, 0x1, +0x2, 0x1, 0x3, 0x1, 0x4, 0x2, 0x0, 0x2, 0x1, 0x2, 0x3, 0x2, 0x4, 0x3, 0x0, 0x3, +0x1, 0x3, 0x2, 0x3, 0x4, 0x4, 0x0, 0x4, 0x1, 0x4, 0x2, 0x4, 0x3, 0x0, 0x1, 0x2, +0x0, 0x1, 0x3, 0x0, 0x1, 0x4, 0x0, 0x2, 0x1, 0x0, 0x2, 0x3, 0x0, 0x2, 0x4, 0x0, +0x3, 0x1, 0x0, 0x3, 0x2, 0x0, 0x3, 0x4, 0x0, 0x4, 0x1, 0x0, 0x4, 0x2, 0x0, 0x4, +0x3, 0x1, 0x0, 0x2, 0x1, 0x0, 0x3, 0x1, 0x0, 0x4, 0x1, 0x2, 0x0, 0x1, 0x2, 0x3, +0x1, 0x2, 0x4, 0x1, 0x3, 0x0, 0x1, 0x3, 0x2, 0x1, 0x3, 0x4, 0x1, 0x4, 0x0, 0x1, +0x4, 0x2, 0x1, 0x4, 0x3, 0x2, 0x0, 0x1, 0x2, 0x0, 0x3, 0x2, 0x0, 0x4, 0x2, 0x1, +0x0, 0x2, 0x1, 0x3, 0x2, 0x1, 0x4, 0x2, 0x3, 0x0, 0x2, 0x3, 0x1, 0x2, 0x3, 0x4, +0x2, 0x4, 0x0, 0x2, 0x4, 0x1, 0x2, 0x4, 0x3, 0x3, 0x0, 0x1, 0x3, 0x0, 0x2, 0x3, +0x0, 0x4, 0x3, 0x1, 0x0, 0x3, 0x1, 0x2, 0x3, 0x1, 0x4, 0x3, 0x2, 0x0, 0x3, 0x2, +0x1, 0x3, 0x2, 0x4, 0x3, 0x4, 0x0, 0x3, 0x4, 0x1, 0x3, 0x4, 0x2, 0x4, 0x0, 0x1, +0x4, 0x0, 0x2, 0x4, 0x0, 0x3, 0x4, 0x1, 0x0, 0x4, 0x1, 0x2, 0x4, 0x1, 0x3, 0x4, +0x2, 0x0, 0x4, 0x2, 0x1, 0x4, 0x2, 0x3, 0x4, 0x3, 0x0, 0x4, 0x3, 0x1, 0x4, 0x3, +0x2, 0x0, 0x1, 0x2a,0x9, 0x0, 0x0, 0x2, 0x2a,0x43,0x0, 0x0, 0x0, 0x2, 0x0, 0x17, +0x0, 0x0, 0x0, 0x0, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0xe8,0x90,0x17,0x87,0x78, +0x4, 0x5c, \ No newline at end of file diff --git a/drivers/input/touchscreen/ft5506_wgj.c b/drivers/input/touchscreen/ft5506_wgj.c new file mode 100644 index 000000000000..8be1ccfd3fbd --- /dev/null +++ b/drivers/input/touchscreen/ft5506_wgj.c @@ -0,0 +1,1172 @@ +/* + * drivers/input/touchscreen/ft5x0x_ts.c + * + * FocalTech ft5x0x TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * note: only support mulititouch Wenfs 2010-10-01 + */ + +#include +#include +#include +#include +#include +//#include "ft5x0x_i2c_ts.h" +#include "ft5506_wgj.h" +#include +#include +#include +#include +#include +#include +#include +#include + + +//#include "ft5x06_ex_fun.h" +/* +enum touchstate { + TOUCH_UP = 0, TOUCH_DOWN = 1, +}; +#define TOUCH_NUMBER 10 + +static int touch_state[TOUCH_NUMBER] = {TOUCH_UP,TOUCH_UP}; +*/ + +struct FTS_TS_DATA_T { + struct i2c_client *client; + struct input_dev *input_dev; + struct FTS_TS_EVENT_T event; + struct work_struct pen_event_work; + struct workqueue_struct *ts_workqueue; + struct early_suspend early_suspend; +}; + +/* -------------- global variable definition -----------*/ +static struct i2c_client *this_client; +static REPORT_FINGER_INFO_T _st_finger_infos[CFG_MAX_POINT_NUM]; +//static unsigned int _sui_irq_num= IRQ_EINT(6); +static int _si_touch_num = 0; + + + +int tsp_keycodes[CFG_NUMOFKEYS] ={ + + KEY_MENU, + KEY_HOME, + KEY_BACK, + KEY_SEARCH +}; + +char *tsp_keyname[CFG_NUMOFKEYS] ={ + + "Menu", + "Home", + "Back", + "Search" +}; + +static bool tsp_keystatus[CFG_NUMOFKEYS]; + + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void ft5x0x_ts_early_suspend(struct early_suspend *h); +static void ft5x0x_ts_late_resume(struct early_suspend *h); +#endif + + +/*********************************************************************** + [function]: +callback: read data from ctpm by i2c interface; +[parameters]: +buffer[in]: data buffer; +length[in]: the length of the data buffer; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static bool i2c_read_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + + ret=i2c_master_recv(this_client, pbt_buf, dw_lenth); + + if(ret<=0) + { + printk("[TSP]i2c_read_interface error\n"); + return FTS_FALSE; + } + + return FTS_TRUE; +} + + + +/*********************************************************************** + [function]: +callback: write data to ctpm by i2c interface; +[parameters]: +buffer[in]: data buffer; +length[in]: the length of the data buffer; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static bool i2c_write_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + ret=i2c_master_send(this_client, pbt_buf, dw_lenth); + if(ret<=0) + { + printk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret); + return FTS_FALSE; + } + + return FTS_TRUE; +} + + + +/*********************************************************************** + [function]: +callback: read register value ftom ctpm by i2c interface; +[parameters]: +reg_name[in]: the register which you want to read; +rx_buf[in]: data buffer which is used to store register value; +rx_length[in]: the length of the data buffer; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static bool fts_register_read(u8 reg_name, u8* rx_buf, int rx_length) +{ + u8 read_cmd[2]= {0}; + u8 cmd_len = 0; + + read_cmd[0] = reg_name; + cmd_len = 1; + + /*send register addr*/ + if(!i2c_write_interface(&read_cmd[0], cmd_len)) + { + return FTS_FALSE; + } + + /*call the read callback function to get the register value*/ + if(!i2c_read_interface(rx_buf, rx_length)) + { + return FTS_FALSE; + } + return FTS_TRUE; +} + + + + +/*********************************************************************** + [function]: +callback: read register value ftom ctpm by i2c interface; +[parameters]: +reg_name[in]: the register which you want to write; +tx_buf[in]: buffer which is contained of the writing value; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static bool fts_register_write(u8 reg_name, u8* tx_buf) +{ + u8 write_cmd[2] = {0}; + + write_cmd[0] = reg_name; + write_cmd[1] = *tx_buf; + + /*call the write callback function*/ + return i2c_write_interface(write_cmd, 2); +} + + + + +/*********************************************************************** + [function]: +callback: report to the input system that the finger is put up; +[parameters]: +null; +[return]: +null; + ************************************************************************/ +static void fts_ts_release(void) +{ + struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client); + int i; + int i_need_sync = 0; + for ( i= 0; iinput_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false); + +/* + input_report_abs(data->input_dev, ABS_MT_POSITION_X, _st_finger_infos[i].i2_x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, _st_finger_infos[i].i2_y); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, _st_finger_infos[i].u2_pressure); + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, _st_finger_infos[i].ui2_id); + input_mt_sync(data->input_dev); +*/ + i_need_sync = 1; + + if ( _st_finger_infos[i].u2_pressure == 0 ) + _st_finger_infos[i].u2_pressure= -1; + } + + if (i_need_sync) + { + printk("+++++++enter fts_ts_release++++++++\n"); + input_sync(data->input_dev); + } + + _si_touch_num = 0; +} + + + + + + +/*********************************************************************** + [function]: +callback: read touch data ftom ctpm by i2c interface; +[parameters]: +rxdata[in]: data buffer which is used to store touch data; +length[in]: the length of the data buffer; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static int fts_i2c_rxdata(u8 *rxdata, int length) +{ + int ret; + struct i2c_msg msg; + + + msg.addr = this_client->addr; + msg.flags = 0; + msg.len = 1; + msg.buf = rxdata; + msg.scl_rate = FT5X0X_I2C_SPEED; + + ret = i2c_transfer(this_client->adapter, &msg, 1); + + if(ret == 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return -EBUSY; + }else if(ret < 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return ret; + } + + msg.addr = this_client->addr; + msg.flags = I2C_M_RD; + msg.len = length; + msg.buf = rxdata; + msg.scl_rate = FT5X0X_I2C_SPEED; + ret = i2c_transfer(this_client->adapter, &msg, 1); + + if(ret == 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return -EBUSY; + }else if(ret < 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return ret; + } + + return ret; +} + + + + + +/*********************************************************************** + [function]: +callback: send data to ctpm by i2c interface; +[parameters]: +txdata[in]: data buffer which is used to send data; +length[in]: the length of the data buffer; +[return]: +FTS_TRUE: success; +FTS_FALSE: fail; + ************************************************************************/ +static int fts_i2c_txdata(u8 *txdata, int length) +{ + int ret; + + struct i2c_msg msg; + + msg.addr = this_client->addr; + msg.flags = 0; + msg.len = length; + msg.buf = txdata; + msg.scl_rate = FT5X0X_I2C_SPEED; + + ret = i2c_transfer(this_client->adapter, &msg, 1); + + if(ret == 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return -EBUSY; + }else if(ret < 0){ + pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret); + return ret; + } + + return ret; +} + + +static int ft5x0x_set_reg(u8 addr, u8 para) +{ + u8 buf[3]; + int ret = -1; + buf[0] = addr; + buf[1] = para; + ret = fts_i2c_txdata(buf, 2); + if (ret < 0) { + pr_err("write reg failed! %#x ret: %d", buf[0], ret); + return -1; + } + return 0; +} + + +/*********************************************************************** + [function]: +callback: gather the finger information and calculate the X,Y +coordinate then report them to the input system; +[parameters]: +null; +[return]: +null; + ************************************************************************/ +int fts_read_data(void) +{ + struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client); + u8 buf[64] = {0}; +// static int key_id=0x80; + + int id,i_count,ret = -1; + int touch_point_num = 0, touch_event, x, y; + int tmp, swap ,sync_flag = 0; +/* + buf[0] = 2;//ADDR + ret = fts_i2c_rxdata(buf, 1); + if (ret > 0) + touch_point_num = buf[0]&0xf; + else + printk(KERN_ERR "get fingers failed!\n"); +*/ + touch_point_num = 10; + + if(touch_point_num > CFG_MAX_POINT_NUM) + printk("[Warning],+++++Touch number[%d] readed is larger than max point number+++++++++++++\n",touch_point_num); + + i_count = 0; + + if(touch_point_num != 0) + { + buf[0] = 3;//ADDR + ret=fts_i2c_rxdata(buf, 6*touch_point_num); + if(ret >= 0) + { + do + { + id = buf[2+i_count*6]>>4; +// printk("Touch ID readed is id=%d\n",id); +// if(id <0 || id>CFG_MAX_POINT_NUM) +// printk("[ERROR] Touch ID readed is illegal!! id=%d\n",id); + + touch_event = buf[i_count*6]>>6; + x =((buf[i_count*6]& 0x0f)<<8) |buf[i_count*6+1]; + y =( (buf[i_count*6+2]& 0x0f)<<8) | buf[i_count*6+3]; + + //adjust value + //x = 768 - x; + //y = 1024 - y; +#if 0 + {//swap + swap = x; + x = y; + y = swap; + } +#endif + // y = (768-y); + if (touch_event == 0) //down + { + _st_finger_infos[i_count].u2_pressure= 1;//pressure; + _st_finger_infos[i_count].i2_x= (int16_t)x; + _st_finger_infos[i_count].i2_y= (int16_t)y; + } + else if (touch_event == 1) //up event + { + _st_finger_infos[i_count].u2_pressure= 0; + } + else if (touch_event == 2) //move + { + _st_finger_infos[i_count].u2_pressure= 1;//pressure; + _st_finger_infos[i_count].i2_x= (int16_t)x; + _st_finger_infos[i_count].i2_y= (int16_t)y; + } + else /*bad event, ignore*/ + { + //printk("Bad event, ignore!!!\n"); + i_count++; + continue; + } + + if(_st_finger_infos[i_count].u2_pressure == 1)//down + { + input_mt_slot(data->input_dev, id); + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, id); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, _st_finger_infos[i_count].i2_x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, _st_finger_infos[i_count].i2_y); +// printk("ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",_st_finger_infos[i_count].i2_x,_st_finger_infos[i_count].i2_y); + + sync_flag = 1; + } + + else if((_st_finger_infos[i_count].u2_pressure == 0)||(touch_event == 1))//up + { + input_mt_slot(data->input_dev, id); + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false); +// input_sync(data->input_dev); + sync_flag = 1; + } + + + if(_st_finger_infos[i_count].u2_pressure == 0 ) + { + _st_finger_infos[i_count].u2_pressure= -1; + } +// input_sync(data->input_dev); + + + i_count++; + }while(i_count < touch_point_num); + + if(sync_flag) + input_sync(data->input_dev); +// input_mt_sync(data->input_dev); + + } + else + { + printk("[LAIBAO] ERROR: in %s, line %d, ret = %d\n", + __FUNCTION__, __LINE__, ret); + } + } + + //If touch number is zero then release touch. + if(touch_point_num == 0 ) + { + fts_ts_release(); + } + + return 0; +} + + + +static void fts_work_func(struct work_struct *work) +{ + //disable_irq(this_client->irq); + fts_read_data(); + enable_irq(this_client->irq); +} + + + + +static irqreturn_t fts_ts_irq(int irq, void *dev_id) +{ + struct FTS_TS_DATA_T *ft5x0x_ts = dev_id; +// printk(KERN_ALERT "fts_tp_irq\n"); + if (!work_pending(&ft5x0x_ts->pen_event_work)) { + disable_irq_nosync(this_client->irq); + queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); + } + + return IRQ_HANDLED; +} + + + +/*********************************************************************** + [function]: +callback: send a command to ctpm. +[parameters]: +btcmd[in]: command code; +btPara1[in]: parameter 1; +btPara2[in]: parameter 2; +btPara3[in]: parameter 3; +num[in]: the valid input parameter numbers, +if only command code needed and no +parameters followed,then the num is 1; +[return]: +FTS_TRUE: success; +FTS_FALSE: io fail; + ************************************************************************/ +static bool cmd_write(u8 btcmd,u8 btPara1,u8 btPara2,u8 btPara3,u8 num) +{ + u8 write_cmd[4] = {0}; + + write_cmd[0] = btcmd; + write_cmd[1] = btPara1; + write_cmd[2] = btPara2; + write_cmd[3] = btPara3; + return i2c_write_interface(write_cmd, num); +} + + + + +/*********************************************************************** + [function]: +callback: write a byte data to ctpm; +[parameters]: +buffer[in]: write buffer; +length[in]: the size of write data; +[return]: +FTS_TRUE: success; +FTS_FALSE: io fail; + ************************************************************************/ +static bool byte_write(u8* buffer, int length) +{ + + return i2c_write_interface(buffer, length); +} + + + + +/*********************************************************************** + [function]: +callback: read a byte data from ctpm; +[parameters]: +buffer[in]: read buffer; +length[in]: the size of read data; +[return]: +FTS_TRUE: success; +FTS_FALSE: io fail; + ************************************************************************/ +static bool byte_read(u8* buffer, int length) +{ + return i2c_read_interface(buffer, length); +} + + + + + +#define FTS_PACKET_LENGTH 128 + +static unsigned char CTPM_FW[]= +{ + //#include "ft_app.i" + #include "ft5506_app.f" +}; + + + + +/*********************************************************************** + [function]: +callback: burn the FW to ctpm. +[parameters]: +pbt_buf[in]: point to Head+FW ; +dw_lenth[in]: the length of the FW + 6(the Head length); +[return]: +ERR_OK: no error; +ERR_MODE: fail to switch to UPDATE mode; +ERR_READID: read id fail; +ERR_ERASE: erase chip fail; +ERR_STATUS: status error; +ERR_ECC: ecc error. + ************************************************************************/ +E_UPGRADE_ERR_TYPE fts_ctpm_fw_upgrade(u8* pbt_buf, int dw_lenth) +{ + u8 cmd,reg_val[2] = {0}; + u8 packet_buf[FTS_PACKET_LENGTH + 6]; + u8 auc_i2c_write_buf[10]; + u8 bt_ecc; + + int j,temp,lenght,i_ret,packet_number, i = 0; + int i_is_new_protocol = 0; + + + /******write 0xaa to register 0xfc******/ + cmd=0xaa; + fts_register_write(0xfc,&cmd); + mdelay(50); + + /******write 0x55 to register 0xfc******/ + cmd=0x55; + fts_register_write(0xfc,&cmd); + printk("[TSP] Step 1: Reset CTPM test\n"); + + mdelay(30); + + + /*******Step 2:Enter upgrade mode ****/ + printk("\n[TSP] Step 2:enter new update mode\n"); + auc_i2c_write_buf[0] = 0x55; + auc_i2c_write_buf[1] = 0xaa; + do + { + i ++; + i_ret = fts_i2c_txdata(auc_i2c_write_buf, 2); + mdelay(5); + }while(i_ret <= 0 && i < 10 ); + + if (i > 1) + { + i_is_new_protocol = 1; + } + + mdelay(100); + /********Step 3:check READ-ID********/ + cmd_write(0x90,0x00,0x00,0x00,4); + msleep(500); + byte_read(reg_val,2); + + printk("=============CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + + //if (reg_val[0] == 0x79 && reg_val[1] == 0x3) + if (reg_val[0] == 0x79 && reg_val[1] == 0x6) + { + printk("[TSP] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + } + else + { + return ERR_READID; + //i_is_new_protocol = 1; + } + + + /*********Step 4:erase app**********/ + if (i_is_new_protocol) + { + cmd_write(0x61,0x00,0x00,0x00,1); + } + else + { + cmd_write(0x60,0x00,0x00,0x00,1); + } + mdelay(2000); + printk("[TSP] Step 4: erase. \n"); + + + + /*Step 5:write firmware(FW) to ctpm flash*/ + bt_ecc = 0; + printk("[TSP] Step 5: start upgrade. \n"); + dw_lenth = dw_lenth - 8; + packet_number = (dw_lenth) / FTS_PACKET_LENGTH; + packet_buf[0] = 0xbf; + packet_buf[1] = 0x00; + for (j=0;j>8); + packet_buf[3] = (FTS_BYTE)temp; + lenght = FTS_PACKET_LENGTH; + packet_buf[4] = (FTS_BYTE)(lenght>>8); + packet_buf[5] = (FTS_BYTE)lenght; + + for (i=0;i 0) + { + temp = packet_number * FTS_PACKET_LENGTH; + packet_buf[2] = (FTS_BYTE)(temp>>8); + packet_buf[3] = (FTS_BYTE)temp; + + temp = (dw_lenth) % FTS_PACKET_LENGTH; + packet_buf[4] = (FTS_BYTE)(temp>>8); + packet_buf[5] = (FTS_BYTE)temp; + + for (i=0;i>8); + packet_buf[3] = (FTS_BYTE)temp; + temp =1; + packet_buf[4] = (FTS_BYTE)(temp>>8); + packet_buf[5] = (FTS_BYTE)temp; + packet_buf[6] = pbt_buf[ dw_lenth + i]; + bt_ecc ^= packet_buf[6]; + + byte_write(&packet_buf[0],7); + mdelay(20); + } + + /********send the opration head************/ + cmd_write(0xcc,0x00,0x00,0x00,1); + byte_read(reg_val,1); + printk("[TSP] Step 6: ecc read 0x%x, new firmware 0x%x. \n", reg_val[0], bt_ecc); + if(reg_val[0] != bt_ecc) + { + return ERR_ECC; + } + + /*******Step 7: reset the new FW**********/ + cmd_write(0x07,0x00,0x00,0x00,1); + + return ERR_OK; +} + + + + +int fts_ctpm_fw_upgrade_with_i_file(void) +{ + u8* pbt_buf = FTS_NULL; + int i_ret; + + pbt_buf = CTPM_FW; + i_ret = fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW)); + + return i_ret; +} + +unsigned char fts_ctpm_get_upg_ver(void) +{ + unsigned int ui_sz; + + ui_sz = sizeof(CTPM_FW); + if (ui_sz > 2) + { + return CTPM_FW[ui_sz - 2]; + } + else + return 0xff; + +} + +void ft5x0x_ts_set_standby(struct i2c_client *client, int enable) +{ +/* + struct laibao_platform_data *mach_info = client->dev.platform_data; + unsigned pwr_pin = mach_info->pwr_pin; + unsigned pwr_on_value = mach_info->pwr_on_value; + unsigned reset_pin = mach_info->reset_pin; + unsigned reset_value = mach_info->reset_value; + + printk("%s : %s, enable = %d\n", __FILE__, __FUNCTION__,enable); + if(pwr_pin != INVALID_GPIO) + { + gpio_direction_output(pwr_pin, 0); + gpio_set_value(pwr_pin, enable ? pwr_on_value : !pwr_on_value); + } + if(reset_pin != INVALID_GPIO) + { + gpio_direction_output(reset_pin, enable ? reset_value : !reset_value); + gpio_set_value(reset_pin, enable ? reset_value : !reset_value); +*/ +} + +#ifdef CONFIG_HAS_EARLYSUSPEND + +static void ft5x0x_ts_early_suspend(struct early_suspend *h) +{ + int ret; + struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client); + printk("enter ft5x0x_ts_early_suspend\n"); + if(this_client->irq) + disable_irq_nosync(this_client->irq); + ret = cancel_work_sync(&data->pen_event_work); + if (ret && this_client->irq) // if work was pending disable-count is now 2 + enable_irq(this_client->irq); +// ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE); +// disable_irq(this_client->irq); +// ft5x0x_ts_set_standby(this_client,0); + return; +} + +/* +static void ft5x0x_ts_early_suspend(struct early_suspend *handler) +{ + int ret; + struct ft5x0x_ts_dev *ts; + ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend); + key_led_ctrl(0); + if(ts->irq) + disable_irq_nosync(ts->irq); + ret = cancel_work_sync(&ts->pen_event_work); + if (ret && ts->irq) // if work was pending disable-count is now 2 + enable_irq(ts->irq); + // ==set mode ==, + ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE); +} +*/ + +static void ft5x0x_ts_late_resume(struct early_suspend *h) +{ + struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client); + //ft5x0x_ts_set_standby(this_client,1); + input_sync(data->input_dev); + + gpio_direction_output(RK30_PIN4_PD0, 0); + msleep(5); + gpio_set_value(RK30_PIN4_PD0,GPIO_HIGH); + msleep(20); + if(this_client->irq) + enable_irq(this_client->irq); + printk("ft5x0x_ts_late_resume finish\n"); + return ; +} + +/* +static void ft5x0x_ts_resume(struct early_suspend *handler) +{ + struct ft5x0x_ts_dev *ts; + ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend); + struct ts_event *event = &ts->event; + // wake the mode + int i =0; + for(i=0; i<5; i++) + { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); + } + input_sync(ts->input_dev); + event->point[i].status == 0; + key_led_ctrl(0); + gpio_direction_output(RK29_PIN6_PC3, 0); + // gpio_set_value(RK29_PIN6_PC3,GPIO_LOW); + msleep(5); + gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH); + msleep(20); +#if USE_POINT + down_table = 0; + up_table = ~0; +#endif + if(ts->irq) + enable_irq(ts->irq); +} +*/ + +#else +#define ft5x0x_ts_early_suspend NULL +#define ft5x0x_ts_late_resume NULL +#endif + + +static int fts_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct FTS_TS_DATA_T *ft5x0x_ts; + struct input_dev *input_dev; + int err = 0; + int _sui_irq_num; + unsigned char reg_value; + unsigned char reg_version; + int i; + + struct ft5506_platform_data *pdata = client->dev.platform_data; + + printk("[LAIBAO] file(%s), function (%s), --probe start\n", __FILE__, __FUNCTION__); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; + goto exit_check_functionality_failed; + } + + if (pdata->init_platform_hw) { + err = pdata->init_platform_hw(); + if (err < 0) { + printk("[LAIBAO] init_platform_hw failed\n"); + goto exit_init_platform_hw_failed; + } + } + + msleep(200); + + this_client = client; + err = i2c_master_reg8_recv(this_client, FT5X0X_REG_FIRMID, ®_version, 1, 200*1000); + if (err < 0) { + printk("[LAIBAO] Device not found\n"); + goto exit_device_not_found; + } + + client->irq = gpio_to_irq(client->irq); + _sui_irq_num = client->irq; + + ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL); + if (!ft5x0x_ts) { + err = -ENOMEM; + goto exit_alloc_data_failed; + } + + //this_client = client; + ft5x0x_ts->client = client; + i2c_set_clientdata(client, ft5x0x_ts); + + INIT_WORK(&ft5x0x_ts->pen_event_work, fts_work_func); + + ft5x0x_ts->ts_workqueue = create_singlethread_workqueue(dev_name(&client->dev)); + if (!ft5x0x_ts->ts_workqueue) { + err = -ESRCH; + goto exit_create_singlethread; + } + + /***wait CTP to bootup normally***/ + //msleep(200); + + //fts_register_read(FT5X0X_REG_FIRMID, ®_version,1); + i2c_master_reg8_recv(this_client, FT5X0X_REG_FIRMID, ®_version, 1, 200*1000); + printk("[LAIBAO] firmware version = 0x%2x\n", reg_version); + //fts_register_read(FT5X0X_REG_REPORT_RATE, ®_value,1); + i2c_master_reg8_recv(this_client, FT5X0X_REG_REPORT_RATE, ®_value, 1, 200*1000); + printk("[LAIBAO] firmware report rate = %dHz\n", reg_value*10); + //fts_register_read(FT5X0X_REG_THRES, ®_value,1); + i2c_master_reg8_recv(this_client, FT5X0X_REG_THRES, ®_value, 1, 200*1000); + printk("[LAIBAO] firmware threshold = %d\n", reg_value * 4); + //fts_register_read(FT5X0X_REG_NOISE_MODE, ®_value,1); + i2c_master_reg8_recv(this_client, FT5X0X_REG_NOISE_MODE, ®_value, 1, 200*1000); + printk("[LAIBAO] nosie mode = 0x%2x\n", reg_value); + +#if 1 + if (fts_ctpm_get_upg_ver() != reg_version) + { + printk("[LAIBAO] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver()); + msleep(400); + err = fts_ctpm_fw_upgrade_with_i_file(); + if (err == 0) + { + printk("[LAIBAO] ugrade successfuly.\n"); + msleep(500); + fts_register_read(FT5X0X_REG_FIRMID, ®_value,1); + printk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value); + } + else + { + printk("[LAIBAO] ugrade fail err=%d, line = %d.\n", + err, __LINE__); + } + msleep(4000); + } +#endif + + + + + + + printk("[LAIBAO]=========================_sui_irq_num = %d ================\n",_sui_irq_num); + printk("[LAIBAO]=========================client->dev.driver->name = %s ================\n",client->dev.driver->name); + err = request_irq(_sui_irq_num, fts_ts_irq, GPIOEdgelFalling, client->dev.driver->name, ft5x0x_ts); + + if (err < 0) { + dev_err(&client->dev, "[LAIBAO] ft5x0x_probe: request irq failed\n"); + printk("[LAIBAO]=========================err = %d ================\n",err); + goto exit_irq_request_failed; + } + disable_irq(_sui_irq_num); + + + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + dev_err(&client->dev, "[LAIBAO]failed to allocate input device\n"); + goto exit_input_dev_alloc_failed; + } + + ft5x0x_ts->input_dev = input_dev; + + /***setup coordinate area******/ + //set_bit(EV_ABS, input_dev->evbit); + //set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit); + //set_bit(ABS_MT_POSITION_X, input_dev->absbit); + //set_bit(ABS_MT_POSITION_Y, input_dev->absbit); + //set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit); + +// input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + __set_bit(EV_ABS, input_dev->evbit); + + /****** for multi-touch *******/ + for (i=0; ievbit); + //set_bit(EV_KEY, input_dev->evbit); + //set_bit(BTN_TOUCH, input_dev->keybit); + //input_dev->keycode = tsp_keycodes; + //for(i = 0; i < CFG_NUMOFKEYS; i++) + //{ + // input_set_capability(input_dev, EV_KEY, ((int*)input_dev->keycode)[i]); + // tsp_keystatus[i] = KEY_RELEASE; + //} + + input_dev->name = FT5X0X_NAME; + input_dev->id.bustype = BUS_I2C; + input_dev->id.vendor = 0xdead; + input_dev->id.product = 0xbeef; + input_dev->id.version = 10427; + + err = input_register_device(input_dev); + if (err) { + dev_err(&client->dev, + "fts_ts_probe: failed to register input device: %s\n", + dev_name(&client->dev)); + goto exit_input_register_device_failed; + } + + +#ifdef CONFIG_HAS_EARLYSUSPEND + ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; + ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_early_suspend; + ft5x0x_ts->early_suspend.resume = ft5x0x_ts_late_resume; + register_early_suspend(&ft5x0x_ts->early_suspend); +#endif + + + enable_irq(_sui_irq_num); + printk("[LAIBAO] file(%s), function (%s), -- end\n", __FILE__, __FUNCTION__); + return 0; + +exit_input_register_device_failed: + input_free_device(input_dev); +exit_input_dev_alloc_failed: + free_irq(_sui_irq_num, ft5x0x_ts); +exit_irq_request_failed: + cancel_work_sync(&ft5x0x_ts->pen_event_work); + destroy_workqueue(ft5x0x_ts->ts_workqueue); +exit_create_singlethread: + i2c_set_clientdata(client, NULL); + kfree(ft5x0x_ts); +exit_alloc_data_failed: +exit_device_not_found: + //if (pdata->exit_platform_hw) + // pdata->exit_platform_hw(); + +exit_init_platform_hw_failed: +exit_check_functionality_failed: + return err; +} + + + +static int __devexit fts_ts_remove(struct i2c_client *client) +{ + struct FTS_TS_DATA_T *ft5x0x_ts; + int _sui_irq_num=client->irq; + + ft5x0x_ts = (struct FTS_TS_DATA_T *)i2c_get_clientdata(client); + free_irq(_sui_irq_num, ft5x0x_ts); + input_unregister_device(ft5x0x_ts->input_dev); + kfree(ft5x0x_ts); + cancel_work_sync(&ft5x0x_ts->pen_event_work); + destroy_workqueue(ft5x0x_ts->ts_workqueue); + i2c_set_clientdata(client, NULL); + + return 0; +} + +static const struct i2c_device_id ft5x0x_ts_id[] = { + {FT5X0X_NAME, 0}, + {} +}; + + +MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id); + +static struct i2c_driver fts_ts_driver = { + .probe = fts_ts_probe, + .remove = fts_ts_remove,//devexit_p(fts_ts_remove), + .id_table = ft5x0x_ts_id, + .driver = { + .name = FT5X0X_NAME, + }, +}; + +static void __init fts_ts_initasync(void *unused, async_cookie_t cookie) +{ + i2c_add_driver(&fts_ts_driver); +} + +static int __init fts_ts_init(void) +{ + async_schedule(fts_ts_initasync, NULL); + return 0; +} + +static void __exit fts_ts_exit(void) +{ + i2c_del_driver(&fts_ts_driver); +} + +module_init(fts_ts_init); +module_exit(fts_ts_exit); + +MODULE_AUTHOR(""); +MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/touchscreen/ft5506_wgj.h b/drivers/input/touchscreen/ft5506_wgj.h new file mode 100644 index 000000000000..66166b69b43e --- /dev/null +++ b/drivers/input/touchscreen/ft5506_wgj.h @@ -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 +//µ±ÊÖÖ¸´Ó±ß½ç»®Æðʱ,»á³öÏÖÎÞÏìÓ¦µÄÇé¿ö,Òò´ËÌí¼ÓÒ»¸öºê½«±ß½ç×î´óÖµÏòÍâÀ­Éì +#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 + + diff --git a/drivers/misc/3g_module/Kconfig b/drivers/misc/3g_module/Kconfig deleted file mode 100755 index 3640e3ccf89d..000000000000 --- a/drivers/misc/3g_module/Kconfig +++ /dev/null @@ -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 - diff --git a/drivers/misc/3g_module/Makefile b/drivers/misc/3g_module/Makefile deleted file mode 100755 index 81907e0d4d40..000000000000 --- a/drivers/misc/3g_module/Makefile +++ /dev/null @@ -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 \ No newline at end of file diff --git a/drivers/misc/3g_module/mi700.c b/drivers/misc/3g_module/mi700.c deleted file mode 100755 index 3b6ecb1c6ca4..000000000000 --- a/drivers/misc/3g_module/mi700.c +++ /dev/null @@ -1,352 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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); diff --git a/drivers/misc/3g_module/mt6229.c b/drivers/misc/3g_module/mt6229.c deleted file mode 100755 index 3335f43eed11..000000000000 --- a/drivers/misc/3g_module/mt6229.c +++ /dev/null @@ -1,358 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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); diff --git a/drivers/misc/3g_module/mu509.c b/drivers/misc/3g_module/mu509.c deleted file mode 100755 index d6ce5b46f722..000000000000 --- a/drivers/misc/3g_module/mu509.c +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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); diff --git a/drivers/misc/3g_module/mw100.c b/drivers/misc/3g_module/mw100.c deleted file mode 100644 index ca75f039c24d..000000000000 --- a/drivers/misc/3g_module/mw100.c +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -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); diff --git a/drivers/misc/3g_module/sc6610.c b/drivers/misc/3g_module/sc6610.c deleted file mode 100755 index 25953b611089..000000000000 --- a/drivers/misc/3g_module/sc6610.c +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -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); diff --git a/drivers/misc/3g_module/sew868.c b/drivers/misc/3g_module/sew868.c deleted file mode 100755 index ae786be7e6d7..000000000000 --- a/drivers/misc/3g_module/sew868.c +++ /dev/null @@ -1,228 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index bdbb18493632..dcadfb3cffc9 100755 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -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" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index e70fbdcd55af..9119f6910d65 100755 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -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/ diff --git a/drivers/misc/bp/Kconfig b/drivers/misc/bp/Kconfig index a3b8411163d7..112a2afdf50c 100755 --- a/drivers/misc/bp/Kconfig +++ b/drivers/misc/bp/Kconfig @@ -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 diff --git a/drivers/misc/bp/bp-auto.c b/drivers/misc/bp/bp-auto.c index c5cec24cab9a..5d79dbf7f17e 100755 --- a/drivers/misc/bp/bp-auto.c +++ b/drivers/misc/bp/bp-auto.c @@ -23,6 +23,7 @@ #include #include +#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¨®¡ä¨®451??¨°??a¨º?¦Ì?16bytes¡ê?¦Ì¨²¨°???byte?a3¡è?¨¨1¨¬?¡§?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); diff --git a/drivers/misc/bp/chips/Kconfig b/drivers/misc/bp/chips/Kconfig old mode 100644 new mode 100755 index 70db74d5e27c..4b095c214060 --- a/drivers/misc/bp/chips/Kconfig +++ b/drivers/misc/bp/chips/Kconfig @@ -4,4 +4,15 @@ bool "modem mt6229" config BP_AUTO_MU509 bool "modem mu509" - default n \ No newline at end of file + 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 + diff --git a/drivers/misc/bp/chips/Makefile b/drivers/misc/bp/chips/Makefile old mode 100644 new mode 100755 index 0f62417b82cf..87d0d739ea78 --- a/drivers/misc/bp/chips/Makefile +++ b/drivers/misc/bp/chips/Makefile @@ -1,2 +1,8 @@ -obj-$(CONFIG_BP_AUTO_MT6229) += mt6229.o -obj-$(CONFIG_BP_AUTO_MU509) += mu509.o \ No newline at end of file +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 diff --git a/drivers/misc/bp/chips/c66a.c b/drivers/misc/bp/chips/c66a.c new file mode 100644 index 000000000000..a5457516f6e8 --- /dev/null +++ b/drivers/misc/bp/chips/c66a.c @@ -0,0 +1,207 @@ +/* drivers/misc/bp/chips/c66a.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/misc/bp/chips/m51.c b/drivers/misc/bp/chips/m51.c new file mode 100755 index 000000000000..8e32bf0c8441 --- /dev/null +++ b/drivers/misc/bp/chips/m51.c @@ -0,0 +1,234 @@ +/* drivers/misc/bp/chips/m51.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/misc/bp/chips/mi700.c b/drivers/misc/bp/chips/mi700.c new file mode 100755 index 000000000000..876a550d3a16 --- /dev/null +++ b/drivers/misc/bp/chips/mi700.c @@ -0,0 +1,223 @@ +/* drivers/misc/bp/chips/mi700.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/misc/bp/chips/mt6229.c b/drivers/misc/bp/chips/mt6229.c index f3c877625154..20abc1dfeac2 100755 --- a/drivers/misc/bp/chips/mt6229.c +++ b/drivers/misc/bp/chips/mt6229.c @@ -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, }; diff --git a/drivers/misc/bp/chips/mtk6250.c b/drivers/misc/bp/chips/mtk6250.c new file mode 100644 index 000000000000..6cee50d51456 --- /dev/null +++ b/drivers/misc/bp/chips/mtk6250.c @@ -0,0 +1,231 @@ +/* drivers/misc/bp/chips/mt6250.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/misc/bp/chips/mu509.c b/drivers/misc/bp/chips/mu509.c index f4228e71a90d..fdc667c7c2ef 100755 --- a/drivers/misc/bp/chips/mu509.c +++ b/drivers/misc/bp/chips/mu509.c @@ -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, }; diff --git a/drivers/misc/bp/chips/mw100.c b/drivers/misc/bp/chips/mw100.c new file mode 100755 index 000000000000..39bf35ad7d44 --- /dev/null +++ b/drivers/misc/bp/chips/mw100.c @@ -0,0 +1,242 @@ +/* drivers/misc/bp/chips/mw100.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/misc/bp/chips/sc6610.c b/drivers/misc/bp/chips/sc6610.c new file mode 100755 index 000000000000..4bdcb2eed152 --- /dev/null +++ b/drivers/misc/bp/chips/sc6610.c @@ -0,0 +1,207 @@ +/* drivers/misc/bp/chips/sc6610.c + * + * Copyright (C) 2012-2015 ROCKCHIP. + * Author: luowei + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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); + diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index ebc243b1163c..988b84868a0b 100755 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -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 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 3d81549d5a6d..da73f4d6586e 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -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 + diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c new file mode 100644 index 000000000000..ce9918e4f970 --- /dev/null +++ b/drivers/power/smb347-charger.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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"); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c20bd51bf461..a3ea0ac197dd 100755 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -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 diff --git a/drivers/video/display/screen/lcd_hj101na.c b/drivers/video/display/screen/lcd_hj101na.c index eb8fea39fa0f..7c96027a89b7 100644 --- a/drivers/video/display/screen/lcd_hj101na.c +++ b/drivers/video/display/screen/lcd_hj101na.c @@ -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); diff --git a/include/linux/bp-auto.h b/include/linux/bp-auto.h index a2b0a898a808..d0a9eb245171 100644 --- a/include/linux/bp-auto.h +++ b/include/linux/bp-auto.h @@ -4,33 +4,38 @@ #include 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, diff --git a/include/linux/power/smb347-charger.h b/include/linux/power/smb347-charger.h new file mode 100644 index 000000000000..af0117992760 --- /dev/null +++ b/include/linux/power/smb347-charger.h @@ -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 -- 2.34.1