axolotl: input: initial bringup
This imports the current focaltech driver used by our
touchscreen.
Change-Id: I0a9305b90ae89996266b3bf39904c7b4fdf604ed
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
index 4d977a7..9700348 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
@@ -780,12 +780,12 @@
pmx_ts_int_active {
ts_int_active: ts_int_active {
mux {
- pins = "gpio122";
+ pins = "gpio125";
function = "gpio";
};
config {
- pins = "gpio122";
+ pins = "gpio125";
drive-strength = <8>;
bias-pull-up;
};
@@ -793,14 +793,14 @@
};
pmx_ts_int_suspend {
- ts_int_suspend1: ts_int_suspend1 {
+ ts_int_suspend: ts_int_suspend {
mux {
- pins = "gpio122";
+ pins = "gpio125";
function = "gpio";
};
config {
- pins = "gpio122";
+ pins = "gpio125";
drive-strength = <2>;
bias-pull-down;
};
@@ -823,7 +823,7 @@
};
pmx_ts_reset_suspend {
- ts_reset_suspend1: ts_reset_suspend1 {
+ ts_reset_suspend: ts_reset_suspend {
mux {
pins = "gpio99";
function = "gpio";
@@ -840,12 +840,12 @@
pmx_ts_release {
ts_release: ts_release {
mux {
- pins = "gpio122", "gpio99";
+ pins = "gpio125", "gpio99";
function = "gpio";
};
config {
- pins = "gpio122", "gpio99";
+ pins = "gpio125", "gpio99";
drive-strength = <2>;
bias-pull-down;
};
@@ -853,6 +853,7 @@
};
ts_mux {
+ /*
ts_active: ts_active {
mux {
pins = "gpio99", "gpio122";
@@ -891,6 +892,7 @@
bias-disable;
};
};
+ */
};
ext_bridge_mux {
@@ -2208,6 +2210,7 @@
};
};
+ /*
qupv3_se5_spi_pins: qupv3_se5_spi_pins {
qupv3_se5_spi_active: qupv3_se5_spi_active {
mux {
@@ -2239,6 +2242,7 @@
};
};
};
+ */
/* SE 6 pin mappings */
qupv3_se6_i2c_pins: qupv3_se6_i2c_pins {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
index 24b7b53..438d7c5 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
@@ -96,6 +96,36 @@
};
};
+&qupv3_se5_i2c {
+ status = "ok";
+ focaltech@38 {
+ compatible = "focaltech,fts";
+ reg = <0x38>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <125 0x2>;
+ vdd-supply = <&pm8998_l28>; // 2.8
+ vcc_i2c-supply = <&pm8998_l14>; // 1.8
+ pinctrl-names = "pmx_ts_active",
+ "pmx_ts_suspend","pmx_ts_release";
+ pinctrl-0 = <&ts_int_active &ts_reset_active>;
+ pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+ pinctrl-2 = <&ts_release>;
+ focaltech,name = "ft3518";
+ focaltech,reset-gpio = <&tlmm 99 0x0>;
+ focaltech,irq-gpio = <&tlmm 125 0x2008>;
+ focaltech,display-coords = <0 0 1080 2160>;
+ focaltech,max-touch-number = <5>;
+/*
+ focaltech,have-key;
+ focaltech,key-number = <3>;
+ focaltech,keys = <139 102 158>;
+ focaltech,key-y-coord = <2000>;
+ focaltech,key-x-coords = <200 600 800>;
+*/
+ };
+
+ };
+
&qupv3_se10_i2c {
status = "ok";
};
@@ -160,8 +190,6 @@
pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &storage_cd>;
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &storage_cd>;
- cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
-
status = "ok";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
index 097c3ac..a5c32f9 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
@@ -341,6 +341,7 @@
status = "disabled";
};
+/*
qupv3_se5_spi: spi@894000 {
compatible = "qcom,spi-geni";
#address-cells = <1>;
@@ -362,6 +363,7 @@
dma-names = "tx", "rx";
status = "disabled";
};
+*/
qupv3_se6_spi: spi@898000 {
compatible = "qcom,spi-geni";
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 9002c5f..75443c3 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -47,6 +47,7 @@
spi0 = &qupv3_se8_spi;
i2c0 = &qupv3_se10_i2c;
i2c1 = &qupv3_se3_i2c;
+ i2c5 = &qupv3_se5_i2c;
hsuart0 = &qupv3_se6_4uart;
};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c3a22b4..3c1eb70 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1410,6 +1410,13 @@
If unsure, say N.
+config TOUCHSCREEN_FTS
+ bool "Focaltech Touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have Focaltech touch panel.
+ If unsure, say N.
+
config TOUCHSCREEN_GT9XX_v28
bool "Goodix touchpanel GT9xx_v28 series"
depends on I2C
diff --git a/drivers/input/touchscreen/focaltech_touch/Kconfig b/drivers/input/touchscreen/focaltech_touch/Kconfig
index 00deec7..612ea63 100644
--- a/drivers/input/touchscreen/focaltech_touch/Kconfig
+++ b/drivers/input/touchscreen/focaltech_touch/Kconfig
@@ -1,18 +1,17 @@
#
# Focaltech Touchscreen driver configuration
#
-menuconfig TOUCHSCREEN_FTS
- bool "Focaltech Touchscreen"
- depends on I2C
- default n
- help
- Say Y here if you have Focaltech touch panel.
- If unsure, say N.
+
+config TOUCHSCREEN_FTS
+ bool "Focaltech Touchscreen"
+ depends on I2C
+ default n
+ help
+ Say Y here if you have Focaltech touch panel.
+ If unsure, say N.
config TOUCHSCREEN_FTS_DIRECTORY
- string "Focaltech ts directory name"
- default "focaltech_touch"
- depends on TOUCHSCREEN_FTS
- help
- Specify the path for the driver directory.
- Path should be relative to driver/input/touchscreen/.
+ string "Focaltech ts directory name"
+ default "focaltech_touch"
+ depends on TOUCHSCREEN_FTS
+
\ No newline at end of file
diff --git a/drivers/input/touchscreen/focaltech_touch/Makefile b/drivers/input/touchscreen/focaltech_touch/Makefile
index c582416..3d0737c 100644
--- a/drivers/input/touchscreen/focaltech_touch/Makefile
+++ b/drivers/input/touchscreen/focaltech_touch/Makefile
@@ -1,17 +1,14 @@
-#
# Makefile for the focaltech touchscreen drivers.
-#
-# Each configuration option enables a list of files.
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_core.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_ex_fun.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_ex_mode.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_flash.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_gesture.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_esdcheck.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_i2c.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_sensor.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_point_report_check.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_flash/
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_point_report_check.o
+
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_flash.o
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_flash/
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
index 209f0a9..d8f1d65 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
@@ -2,7 +2,7 @@
*
* FocalTech fts TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -15,18 +15,18 @@
*
*/
/*****************************************************************************
- *
- * File Name: focaltech_common.h
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-16
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_common.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-16
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
#ifndef __LINUX_FOCALTECH_COMMON_H__
#define __LINUX_FOCALTECH_COMMON_H__
@@ -34,184 +34,133 @@
#include "focaltech_config.h"
/*****************************************************************************
- * Macro definitions using #define
- *****************************************************************************/
-#define FTS_DRIVER_VERSION "Focaltech V1.3 20170306"
+* Macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_VERSION "Focaltech V3.1 20190807"
+#define BYTE_OFF_0(x) (u8)((x) & 0xFF)
+#define BYTE_OFF_8(x) (u8)(((x) >> 8) & 0xFF)
+#define BYTE_OFF_16(x) (u8)(((x) >> 16) & 0xFF)
+#define BYTE_OFF_24(x) (u8)(((x) >> 24) & 0xFF)
#define FLAGBIT(x) (0x00000001 << (x))
-#define FLAGBITS(x, y) ((0xFFFFFFFF >> (32 - (y) - 1)) << (x))
+#define FLAGBITS(x, y) ((0xFFFFFFFF >> (32 - (y) - 1)) & (0xFFFFFFFF << (x)))
-#define FLAG_ICSERIALS_LEN 5
+#define FLAG_ICSERIALS_LEN 8
+#define FLAG_HID_BIT 10
#define FLAG_IDC_BIT 11
-#define IC_SERIALS (FTS_CHIP_TYPE & \
- FLAGBITS(0, FLAG_ICSERIALS_LEN-1))
-#define FTS_CHIP_IDC ((FTS_CHIP_TYPE & FLAGBIT(FLAG_IDC_BIT)) \
- == FLAGBIT(FLAG_IDC_BIT))
+#define IC_SERIALS (FTS_CHIP_TYPE & FLAGBITS(0, FLAG_ICSERIALS_LEN-1))
+#define IC_TO_SERIALS(x) ((x) & FLAGBITS(0, FLAG_ICSERIALS_LEN-1))
+#define FTS_CHIP_IDC ((FTS_CHIP_TYPE & FLAGBIT(FLAG_IDC_BIT)) == FLAGBIT(FLAG_IDC_BIT))
+#define FTS_HID_SUPPORTTED ((FTS_CHIP_TYPE & FLAGBIT(FLAG_HID_BIT)) == FLAGBIT(FLAG_HID_BIT))
-#define FTS_CHIP_TYPE_MAPPING { \
- {0x01, 0x58, 0x22, 0x58, 0x22, 0x00, 0x00, 0x58, 0x2C}, \
- {0x02, 0x54, 0x22, 0x54, 0x22, 0x00, 0x00, 0x54, 0x2C}, \
- {0x03, 0x64, 0x26, 0x64, 0x26, 0x00, 0x00, 0x79, 0x1C}, \
- {0x04, 0x33, 0x67, 0x64, 0x26, 0x00, 0x00, 0x79, 0x1C}, \
- {0x05, 0x87, 0x16, 0x87, 0x16, 0x87, 0xA6, 0x00, 0x00}, \
- {0x06, 0x87, 0x36, 0x87, 0x36, 0x87, 0xC6, 0x00, 0x00}, \
- {0x07, 0x80, 0x06, 0x80, 0x06, 0x80, 0xC6, 0x80, 0xB6}, \
- {0x08, 0x86, 0x06, 0x86, 0x06, 0x86, 0xA6, 0x00, 0x00}, \
- {0x09, 0x86, 0x07, 0x86, 0x07, 0x86, 0xA7, 0x00, 0x00}, \
- {0x0A, 0xE7, 0x16, 0x87, 0x16, 0xE7, 0xA6, 0x87, 0xB6}, \
-}
+#define FTS_CHIP_TYPE_MAPPING {{0x81, 0x54, 0x52, 0x54, 0x52, 0x00, 0x00, 0x54, 0x5C}}
-#define I2C_BUFFER_LENGTH_MAXINUM 256
#define FILE_NAME_LENGTH 128
#define ENABLE 1
#define DISABLE 0
+#define VALID 1
+#define INVALID 0
+#define FTS_CMD_START1 0x55
+#define FTS_CMD_START2 0xAA
+#define FTS_CMD_START_DELAY 12
+#define FTS_CMD_READ_ID 0x90
+#define FTS_CMD_READ_ID_LEN 4
+#define FTS_CMD_READ_ID_LEN_INCELL 1
/*register address*/
#define FTS_REG_INT_CNT 0x8F
#define FTS_REG_FLOW_WORK_CNT 0x91
#define FTS_REG_WORKMODE 0x00
#define FTS_REG_WORKMODE_FACTORY_VALUE 0x40
#define FTS_REG_WORKMODE_WORK_VALUE 0x00
+#define FTS_REG_ESDCHECK_DISABLE 0x8D
#define FTS_REG_CHIP_ID 0xA3
#define FTS_REG_CHIP_ID2 0x9F
#define FTS_REG_POWER_MODE 0xA5
-#define FTS_REG_POWER_MODE_SLEEP_VALUE 0x03
+#define FTS_REG_POWER_MODE_SLEEP 0x03
#define FTS_REG_FW_VER 0xA6
#define FTS_REG_VENDOR_ID 0xA8
#define FTS_REG_LCD_BUSY_NUM 0xAB
#define FTS_REG_FACE_DEC_MODE_EN 0xB0
+#define FTS_REG_FACTORY_MODE_DETACH_FLAG 0xB4
+#define FTS_REG_FACE_DEC_MODE_STATUS 0x01
+#define FTS_REG_IDE_PARA_VER_ID 0xB5
+#define FTS_REG_IDE_PARA_STATUS 0xB6
#define FTS_REG_GLOVE_MODE_EN 0xC0
#define FTS_REG_COVER_MODE_EN 0xC1
#define FTS_REG_CHARGER_MODE_EN 0x8B
#define FTS_REG_GESTURE_EN 0xD0
#define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3
+#define FTS_REG_MODULE_ID 0xE3
+#define FTS_REG_LIC_VER 0xE4
#define FTS_REG_ESD_SATURATE 0xED
+#define FTS_SYSFS_ECHO_ON(buf) (buf[0] == '1')
+#define FTS_SYSFS_ECHO_OFF(buf) (buf[0] == '0')
+#define kfree_safe(pbuf) do {\
+ if (pbuf) {\
+ kfree(pbuf);\
+ pbuf = NULL;\
+ }\
+} while(0)
/*****************************************************************************
- * Alternative mode (When something goes wrong,
- * the modules may be able to solve the problem.)
- *****************************************************************************/
+* Alternative mode (When something goes wrong, the modules may be able to solve the problem.)
+*****************************************************************************/
/*
* point report check
* default: disable
*/
#define FTS_POINT_REPORT_CHECK_EN 0
-
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
+* Global variable or extern global variabls/functions
+*****************************************************************************/
struct ft_chip_t {
- unsigned long type;
- unsigned char chip_idh;
- unsigned char chip_idl;
- unsigned char rom_idh;
- unsigned char rom_idl;
- unsigned char pramboot_idh;
- unsigned char pramboot_idl;
- unsigned char bootloader_idh;
- unsigned char bootloader_idl;
+ u64 type;
+ u8 chip_idh;
+ u8 chip_idl;
+ u8 rom_idh;
+ u8 rom_idl;
+ u8 pb_idh;
+ u8 pb_idl;
+ u8 bl_idh;
+ u8 bl_idl;
};
-/* i2c communication*/
-int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue);
-int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue);
-int fts_i2c_read(struct i2c_client *client, char *writebuf, int writelen,
- char *readbuf, int readlen);
-int fts_i2c_write(struct i2c_client *client, char *writebuf, int writelen);
-int fts_i2c_init(void);
-int fts_i2c_exit(void);
-
-/* Gesture functions */
-#if FTS_GESTURE_EN
-int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client);
-int fts_gesture_exit(struct i2c_client *client);
-void fts_gesture_recovery(struct i2c_client *client);
-int fts_gesture_readdata(struct i2c_client *client);
-int fts_gesture_suspend(struct i2c_client *i2c_client);
-int fts_gesture_resume(struct i2c_client *client);
-#endif
-
-/* Apk and functions */
-#if FTS_APK_NODE_EN
-int fts_create_apk_debug_channel(struct i2c_client *client);
-void fts_release_apk_debug_channel(void);
-#endif
-
-/* ADB functions */
-#if FTS_SYSFS_NODE_EN
-int fts_create_sysfs(struct i2c_client *client);
-int fts_remove_sysfs(struct i2c_client *client);
-#endif
-
-/* ESD */
-#if FTS_ESDCHECK_EN
-int fts_esdcheck_init(void);
-int fts_esdcheck_exit(void);
-int fts_esdcheck_switch(bool enable);
-int fts_esdcheck_proc_busy(bool proc_debug);
-int fts_esdcheck_set_intr(bool intr);
-int fts_esdcheck_suspend(void);
-int fts_esdcheck_resume(void);
-int fts_esdcheck_get_status(void);
-#endif
-
-/* Production test */
-#if FTS_TEST_EN
-int fts_test_init(struct i2c_client *client);
-int fts_test_exit(struct i2c_client *client);
-#endif
-
-/* Point Report Check*/
-#if FTS_POINT_REPORT_CHECK_EN
-int fts_point_report_check_init(void);
-int fts_point_report_check_exit(void);
-void fts_point_report_check_queue_work(void);
-#endif
-
-/* Other */
-extern int g_show_log;
-int fts_reset_proc(int hdelayms);
-int fts_wait_tp_to_valid(struct i2c_client *client);
-void fts_tp_state_recovery(struct i2c_client *client);
-int fts_ex_mode_init(struct i2c_client *client);
-int fts_ex_mode_exit(struct i2c_client *client);
-int fts_ex_mode_recovery(struct i2c_client *client);
-
-void fts_irq_disable(void);
-void fts_irq_enable(void);
+struct ts_ic_info {
+ bool is_incell;
+ bool hid_supported;
+ struct ft_chip_t ids;
+};
/*****************************************************************************
- * DEBUG function define here
- *****************************************************************************/
+* DEBUG function define here
+*****************************************************************************/
#if FTS_DEBUG_EN
-#define FTS_DEBUG_LEVEL 1
+#define FTS_DEBUG(fmt, args...) do { \
+ printk("[FTS_TS]%s:"fmt"\n", __func__, ##args); \
+} while (0)
-#if (FTS_DEBUG_LEVEL == 2)
-#define FTS_DEBUG(fmt, args...) pr_err("[FTS][%s]"fmt"\n", __func__, ##args)
-#else
-#define FTS_DEBUG(fmt, args...) pr_err("[FTS]"fmt"\n", ##args)
-#endif
+#define FTS_FUNC_ENTER() do { \
+ printk("[FTS_TS]%s: Enter\n", __func__); \
+} while (0)
-#define FTS_FUNC_ENTER() pr_err("[FTS]%s: Enter\n", __func__)
-#define FTS_FUNC_EXIT() pr_err("[FTS]%s: Exit(%d)\n", __func__, __LINE__)
-#else
+#define FTS_FUNC_EXIT() do { \
+ printk("[FTS_TS]%s: Exit(%d)\n", __func__, __LINE__); \
+} while (0)
+#else /* #if FTS_DEBUG_EN*/
#define FTS_DEBUG(fmt, args...)
#define FTS_FUNC_ENTER()
#define FTS_FUNC_EXIT()
#endif
#define FTS_INFO(fmt, args...) do { \
- if (g_show_log) \
- pr_err("[FTS][Info]"fmt"\n", ##args); \
- } while (0)
+ printk(KERN_INFO "[FTS_TS/I]%s:"fmt"\n", __func__, ##args); \
+} while (0)
-#define FTS_ERROR(fmt, args...) do { \
- if (g_show_log) \
- pr_err("[FTS][Error]"fmt"\n", ##args); \
- } while (0)
-
-
+#define FTS_ERROR(fmt, args...) do { \
+ printk(KERN_ERR "[FTS_TS/E]%s:"fmt"\n", __func__, ##args); \
+} while (0)
#endif /* __LINUX_FOCALTECH_COMMON_H__ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
index 5ab6bda..76999fe 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (c) 2012-2018, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -15,77 +15,119 @@
*
*/
/************************************************************************
- *
- * File Name: focaltech_config.h
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-08
- *
- * Abstract: global configurations
- *
- * Version: v1.0
- *
- ************************************************************************/
+*
+* File Name: focaltech_config.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract: global configurations
+*
+* Version: v1.0
+*
+************************************************************************/
#ifndef _LINUX_FOCLATECH_CONFIG_H_
#define _LINUX_FOCLATECH_CONFIG_H_
/**************************************************/
/****** G: A, I: B, S: C, U: D ******************/
/****** chip type defines, do not modify *********/
-#define _FT8716 0x87160805
-#define _FT8736 0x87360806
-#define _FT8006 0x80060807
-#define _FT8606 0x86060808
-#define _FT8607 0x86070809
-#define _FTE716 0xE716080a
-
-#define _FT5416 0x54160002
-#define _FT5426 0x54260002
-#define _FT5435 0x54350002
-#define _FT5436 0x54360002
-#define _FT5526 0x55260002
-#define _FT5526I 0x5526B002
-#define _FT5446 0x54460002
-#define _FT5346 0x53460002
-#define _FT5446I 0x5446B002
-#define _FT5346I 0x5346B002
-#define _FT7661 0x76610002
-#define _FT7511 0x75110002
-#define _FT7421 0x74210002
-#define _FT7681 0x76810002
-#define _FT3C47U 0x3C47D002
-#define _FT3417 0x34170002
-#define _FT3517 0x35170002
-#define _FT3327 0x33270002
-#define _FT3427 0x34270002
-
-#define _FT5626 0x56260001
-#define _FT5726 0x57260001
-#define _FT5826B 0x5826B001
-#define _FT5826S 0x5826C001
-#define _FT7811 0x78110001
-#define _FT3D47 0x3D470001
-#define _FT3617 0x36170001
-#define _FT3717 0x37170001
-#define _FT3817B 0x3817B001
-
-#define _FT6236U 0x6236D003
-#define _FT6336G 0x6336A003
-#define _FT6336U 0x6336D003
-#define _FT6436U 0x6436D003
-
-#define _FT3267 0x32670004
-#define _FT3367 0x33670004
+#define _FT8716 0x87160805
+#define _FT8736 0x87360806
+#define _FT8006M 0x80060807
+#define _FT8607 0x86070809
+#define _FT8006U 0x8006D80B
+#define _FT8006S 0x8006A80B
+#define _FT8613 0x8613080C
+#define _FT8719 0x8719080D
+#define _FT8739 0x8739080E
+#define _FT8615 0x8615080F
+#define _FT8201 0x82010810
+#define _FT8006P 0x86220811
+#define _FT7251 0x72510812
+#define _FT7252 0x72520813
+#define _FT8613S 0x8613C814
+#define _FT8756 0x87560815
+#define _FT8302 0x83020816
+#define _FT8009 0x80090817
+#define _FT8656 0x86560818
+#define _FT8006S_AA 0x86320819
+#define _FT7250 0x7250081A
+#define _FT5416 0x54160402
+#define _FT5426 0x54260402
+#define _FT5435 0x54350402
+#define _FT5436 0x54360402
+#define _FT5526 0x55260402
+#define _FT5526I 0x5526B402
+#define _FT5446 0x54460402
+#define _FT5346 0x53460402
+#define _FT5446I 0x5446B402
+#define _FT5346I 0x5346B402
+#define _FT7661 0x76610402
+#define _FT7511 0x75110402
+#define _FT7421 0x74210402
+#define _FT7681 0x76810402
+#define _FT3C47U 0x3C47D402
+#define _FT3417 0x34170402
+#define _FT3517 0x35170402
+#define _FT3327 0x33270402
+#define _FT3427 0x34270402
+#define _FT7311 0x73110402
+
+#define _FT5626 0x56260401
+#define _FT5726 0x57260401
+#define _FT5826B 0x5826B401
+#define _FT5826S 0x5826C401
+#define _FT7811 0x78110401
+#define _FT3D47 0x3D470401
+#define _FT3617 0x36170401
+#define _FT3717 0x37170401
+#define _FT3817B 0x3817B401
+#define _FT3517U 0x3517D401
+
+#define _FT6236U 0x6236D003
+#define _FT6336G 0x6336A003
+#define _FT6336U 0x6336D003
+#define _FT6436U 0x6436D003
+
+#define _FT3267 0x32670004
+#define _FT3367 0x33670004
+
+#define _FT3327DQQ_XXX 0x3327D482
+#define _FT5446DQS_XXX 0x5446D482
+
+#define _FT3518 0x35180481
+#define _FT3558 0x35580481
+#define _FT3528 0x35280481
+#define _FT5536 0x55360481
+
+#define _FT5446U 0x5446D083
+#define _FT5456U 0x5456D083
+#define _FT3417U 0x3417D083
+#define _FT5426U 0x5426D083
+#define _FT3428 0x34280083
+#define _FT3437U 0x3437D083
+
+#define _FT7302 0x73020084
+#define _FT7202 0x72020084
+#define _FT3308 0x33080084
+
+#define _FT6346U 0x6346D085
+#define _FT6346G 0x6346A085
+#define _FT3067 0x30670085
+#define _FT3068 0x30680085
+#define _FT3168 0x31680085
+#define _FT3268 0x32680085
/*************************************************/
/*
* choose your ic chip type of focaltech
*/
-#define FTS_CHIP_TYPE _FT3267
+#define FTS_CHIP_TYPE _FT3518
/******************* Enables *********************/
/*********** 1 to enable, 0 to disable ***********/
@@ -102,22 +144,13 @@
*/
#define FTS_MT_PROTOCOL_B_EN 1
-
/*
* Report Pressure in multitouch
* 1:enable(default),0:disable
- */
+*/
#define FTS_REPORT_PRESSURE_EN 1
/*
- * Force touch support
- * different pressure for multitouch
- * 1: true pressure for force touch
- * 0: constant pressure(default)
- */
-#define FTS_FORCE_TOUCH_EN 0
-
-/*
* Gesture function enable
* default: disable
*/
@@ -129,39 +162,12 @@
*/
#define FTS_ESDCHECK_EN 0
-/*
- * Production test enable
- * 1: enable, 0:disable(default)
- */
-#define FTS_TEST_EN 0
/*
- * Glove mode enable
- * 1: enable, 0:disable(default)
- */
-#define FTS_GLOVE_EN 0
-/*
- * cover enable
- * 1: enable, 0:disable(default)
- */
-#define FTS_COVER_EN 0
-/*
- * Charger enable
- * 1: enable, 0:disable(default)
- */
-#define FTS_CHARGER_EN 0
-
-/*
- * Proximity sensor
+ * Pinctrl enable
* default: disable
*/
-#define FTS_PSENSOR_EN 0
-
-/*
- * Nodes for tools, please keep enable
- */
-#define FTS_SYSFS_NODE_EN 1
-#define FTS_APK_NODE_EN 1
+#define FTS_PINCTRL_EN 1
/*
* Customer power enable
@@ -174,74 +180,61 @@
/********************** Upgrade ****************************/
/*
- * auto upgrade, please keep enable
+ * auto upgrade
*/
#define FTS_AUTO_UPGRADE_EN 1
/*
* auto upgrade for lcd cfg
- * default: 0
*/
-#define FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN 0
-
-/* auto cb check
- * default: disable
- */
-#define FTS_AUTO_CLB_EN 0
+#define FTS_AUTO_LIC_UPGRADE_EN 0
/*
- * Check vendor_id number
- * 0:No check vendor_id (default)
- * 1/2/3: Check vendor_id for vendor compatibility
+ * Numbers of modules support
*/
-#define FTS_GET_VENDOR_ID_NUM 0
+#define FTS_GET_MODULE_NUM 0
/*
- * vendor_id(s) for vendor(s) to be compatible with.
- * a confirmation of vendor_id(s) is recommended.
- * FTS_GET_VENDOR_ID_NUM == 0, no check vendor id, you may ignore them
- * FTS_GET_VENDOR_ID_NUM >= 1, compatible with FTS_VENDOR_1_ID
- * FTS_GET_VENDOR_ID_NUM >= 2, compatible with FTS_VENDOR_2_ID
- * FTS_GET_VENDOR_ID_NUM == 3, compatible with FTS_VENDOR_3_ID
+ * module_id: mean vendor_id generally, also maybe gpio or lcm_id...
+ * If means vendor_id, the FTS_MODULE_ID = PANEL_ID << 8 + VENDOR_ID
+ * FTS_GET_MODULE_NUM == 0/1, no check module id, you may ignore them
+ * FTS_GET_MODULE_NUM >= 2, compatible with FTS_MODULE2_ID
+ * FTS_GET_MODULE_NUM >= 3, compatible with FTS_MODULE3_ID
*/
-#define FTS_VENDOR_1_ID 0x00
-#define FTS_VENDOR_2_ID 0x00
-#define FTS_VENDOR_3_ID 0x00
+#define FTS_MODULE_ID 0x0000
+#define FTS_MODULE2_ID 0x0000
+#define FTS_MODULE3_ID 0x0000
/*
- * FW_APP.i file for auto upgrade, you must replace it with your own
- * define your own fw_app, the sample one to be replaced is invalid
- * NOTE: if FTS_GET_VENDOR_ID_NUM >= 1,
- * it's the fw corresponding with FTS_VENDOR_1_ID
+ * Need set the following when get firmware via firmware_request()
+ * For example: if module'vendor is tianma,
+ * #define FTS_MODULE_NAME "tianma"
+ * then file_name will be "focaltech_ts_fw_tianma"
+ * You should rename fw to "focaltech_ts_fw_tianma", and push it into
+ * etc/firmware or by customers
*/
-#define FTS_UPGRADE_FW_APP "include/firmware/FT8716_app_sample.i"
+#define FTS_MODULE_NAME ""
+#define FTS_MODULE2_NAME ""
+#define FTS_MODULE3_NAME ""
/*
- * if FTS_GET_VENDOR_ID_NUM >= 2, fw corrsponding with FTS_VENDOR_2_ID
- * define your own fw_app, the sample one is invalid
+ * FW.i file for auto upgrade, you must replace it with your own
+ * define your own fw_file, the sample one to be replaced is invalid
+ * NOTE: if FTS_GET_MODULE_NUM > 1, it's the fw corresponding with FTS_VENDOR_ID
*/
-#define FTS_UPGRADE_FW2_APP "include/firmware/FT8716_app_sample.i"
+#define FTS_UPGRADE_FW_FILE "include/firmware/FT3518_Ref_firmware.i"
/*
- * if FTS_GET_VENDOR_ID_NUM == 3, fw corrsponding with FTS_VENDOR_3_ID
- * define your own fw_app, the sample one is invalid
+ * if FTS_GET_MODULE_NUM >= 2, fw corrsponding with FTS_VENDOR_ID2
+ * define your own fw_file, the sample one is invalid
*/
-#define FTS_UPGRADE_FW3_APP "include/firmware/FT8716_app_sample.i"
+#define FTS_UPGRADE_FW2_FILE "include/firmware/fw_sample.i"
/*
- * lcd_cfg.i file for lcd cfg upgrade
- * define your own lcd_cfg.i, the sample one is invalid
+ * if FTS_GET_MODULE_NUM >= 3, fw corrsponding with FTS_VENDOR_ID3
+ * define your own fw_file, the sample one is invalid
*/
-#define FTS_UPGRADE_LCD_CFG "include/firmware/lcd_cfg.i"
-
-/*
- * upgrade stress test for debug
- * enable it for upgrade debug if needed
- * default: disable
- */
-#define FTS_UPGRADE_STRESS_TEST 0
-/* stress test times, default: 1000 */
-#define FTS_UPGRADE_TEST_NUMBER 1000
+#define FTS_UPGRADE_FW3_FILE "include/firmware/fw_sample.i"
/*********************************************************/
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
index 7639c9f..0e314fc 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (c) 2012-2018, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -15,1462 +15,1741 @@
*
*/
/*****************************************************************************
- *
- * File Name: focaltech_core.c
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-08
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_core.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract: entrance for focaltech ts driver
+*
+* Version: V1.0
+*
+*****************************************************************************/
/*****************************************************************************
- * Included header files
- *****************************************************************************/
-#include "focaltech_core.h"
-
-
-#if defined(CONFIG_FB)
+* Included header files
+*****************************************************************************/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#ifdef CONFIG_DRM
#include <linux/notifier.h>
#include <linux/fb.h>
+#include <linux/msm_drm_notify.h>
#elif defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
-#define FTS_SUSPEND_LEVEL 1 /* Early-suspend level */
+#define FTS_SUSPEND_LEVEL 1 /* Early-suspend level */
#endif
+#include "focaltech_core.h"
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-#define FTS_DRIVER_NAME "fts_ts"
-#define INTERVAL_READ_REG 20 /* interval time per read reg unit:ms */
-#define TIMEOUT_READ_REG 300 /* timeout of read reg unit:ms */
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_NAME "fts_ts"
+#define INTERVAL_READ_REG 200 /* unit:ms */
+#define TIMEOUT_READ_REG 1000 /* unit:ms */
#if FTS_POWER_SOURCE_CUST_EN
-#define FTS_VTG_MIN_UV 2600000
-#define FTS_VTG_MAX_UV 3300000
-#define FTS_I2C_VTG_MIN_UV 1800000
-#define FTS_I2C_VTG_MAX_UV 1800000
-#endif
-#define FTS_READ_TOUCH_BUFFER_DIVIDED 0
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- ******************************************************************************/
-struct i2c_client *fts_i2c_client;
-struct fts_ts_data *fts_wq_data;
-struct input_dev *fts_input_dev;
-
-#if FTS_DEBUG_EN
-int g_show_log = 1;
-#else
-int g_show_log;
-#endif
-
-#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
-char g_sz_debug[1024] = {0};
+#define FTS_VTG_MIN_UV 2800000
+#define FTS_VTG_MAX_UV 3300000
+#define FTS_I2C_VTG_MIN_UV 1800000
+#define FTS_I2C_VTG_MAX_UV 1800000
#endif
/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-static void fts_release_all_finger(void);
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+struct fts_ts_data *fts_data;
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
static int fts_ts_suspend(struct device *dev);
static int fts_ts_resume(struct device *dev);
-
/*****************************************************************************
- * Name: fts_wait_tp_to_valid
- * Brief: Read chip id until TP FW become valid,
- * need call when reset/power on/resume...
- * 1. Read Chip ID per INTERVAL_READ_REG(20ms)
- * 2. Timeout: TIMEOUT_READ_REG(300ms)
- * Input:
- * Output:
- * Return: 0 - Get correct Device ID
- *****************************************************************************/
-int fts_wait_tp_to_valid(struct i2c_client *client)
+* Name: fts_wait_tp_to_valid
+* Brief: Read chip id until TP FW become valid(Timeout: TIMEOUT_READ_REG),
+* need call when reset/power on/resume...
+* Input:
+* Output:
+* Return: return 0 if tp valid, otherwise return error code
+*****************************************************************************/
+int fts_wait_tp_to_valid(void)
{
- int ret = 0;
- int cnt = 0;
- u8 reg_value = 0;
+ int ret = 0;
+ int cnt = 0;
+ u8 idh = 0;
+ u8 idl = 0;
+ u8 chip_idh = fts_data->ic_info.ids.chip_idh;
+ u8 chip_idl = fts_data->ic_info.ids.chip_idl;
- do {
- ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, ®_value);
- if ((ret < 0) || (reg_value != chip_types.chip_idh)) {
- FTS_INFO("TP Not Ready, ReadData = 0x%x", reg_value);
- } else if (reg_value == chip_types.chip_idh) {
- FTS_INFO("TP Ready, Device ID = 0x%x", reg_value);
- return 0;
- }
- cnt++;
- msleep(INTERVAL_READ_REG);
- } while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
+ do {
+ ret = fts_read_reg(FTS_REG_CHIP_ID, &idh);
+ ret = fts_read_reg(FTS_REG_CHIP_ID2, &idl);
+ if ((ret < 0) || (idh != chip_idh) || (idl != chip_idl)) {
+ FTS_DEBUG("TP Not Ready,ReadData:0x%02x%02x", idh, idl);
+ } else if ((idh == chip_idh) && (idl == chip_idl)) {
+ FTS_INFO("TP Ready,Device ID:0x%02x%02x", idh, idl);
+ return 0;
+ }
+ cnt++;
+ msleep(INTERVAL_READ_REG);
+ } while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
- /* error: not get correct reg data */
- return -EINVAL;
+ return -EIO;
}
/*****************************************************************************
- * Name: fts_recover_state
- * Brief: Need execute this function when reset
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-void fts_tp_state_recovery(struct i2c_client *client)
+* Name: fts_tp_state_recovery
+* Brief: Need execute this function when reset
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+void fts_tp_state_recovery(struct fts_ts_data *ts_data)
{
- /* wait tp stable */
- fts_wait_tp_to_valid(client);
- /* recover TP charger state 0x8B */
- /* recover TP glove state 0xC0 */
- /* recover TP cover state 0xC1 */
- fts_ex_mode_recovery(client);
- /* recover TP gesture state 0xD0 */
-#if FTS_GESTURE_EN
- fts_gesture_recovery(client);
-#endif
+ FTS_FUNC_ENTER();
+ /* wait tp stable */
+ fts_wait_tp_to_valid();
+ /* recover TP charger state 0x8B */
+ /* recover TP glove state 0xC0 */
+ /* recover TP cover state 0xC1 */
+ fts_ex_mode_recovery(ts_data);
+ /* recover TP gesture state 0xD0 */
+ fts_gesture_recovery(ts_data);
+ FTS_FUNC_EXIT();
}
-
-/*****************************************************************************
- * Name: fts_reset_proc
- * Brief: Execute reset operation
- * Input: hdelayms - delay time unit:ms
- * Output:
- * Return:
- *****************************************************************************/
int fts_reset_proc(int hdelayms)
{
- gpio_direction_output(fts_wq_data->pdata->reset_gpio, 0);
- msleep(20);
- gpio_direction_output(fts_wq_data->pdata->reset_gpio, 1);
- msleep(hdelayms);
+ FTS_DEBUG("tp reset");
+ gpio_direction_output(fts_data->pdata->reset_gpio, 0);
+ msleep(1);
+ gpio_direction_output(fts_data->pdata->reset_gpio, 1);
+ if (hdelayms) {
+ msleep(hdelayms);
+ }
- return 0;
+ return 0;
}
-/*****************************************************************************
- * Name: fts_irq_disable
- * Brief: disable irq
- * Input:
- * sync:
- * Output:
- * Return:
- *****************************************************************************/
void fts_irq_disable(void)
{
- unsigned long irqflags;
+ unsigned long irqflags;
- spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+ FTS_FUNC_ENTER();
+ spin_lock_irqsave(&fts_data->irq_lock, irqflags);
- if (!fts_wq_data->irq_disable) {
- disable_irq_nosync(fts_wq_data->client->irq);
- fts_wq_data->irq_disable = 1;
- }
+ if (!fts_data->irq_disabled) {
+ disable_irq_nosync(fts_data->irq);
+ fts_data->irq_disabled = true;
+ }
- spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+ spin_unlock_irqrestore(&fts_data->irq_lock, irqflags);
+ FTS_FUNC_EXIT();
}
-/*****************************************************************************
- * Name: fts_irq_enable
- * Brief: enable irq
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
void fts_irq_enable(void)
{
- unsigned long irqflags = 0;
+ unsigned long irqflags = 0;
- spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+ FTS_FUNC_ENTER();
+ spin_lock_irqsave(&fts_data->irq_lock, irqflags);
- if (fts_wq_data->irq_disable) {
- enable_irq(fts_wq_data->client->irq);
- fts_wq_data->irq_disable = 0;
- }
+ if (fts_data->irq_disabled) {
+ enable_irq(fts_data->irq);
+ fts_data->irq_disabled = false;
+ }
- spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+ spin_unlock_irqrestore(&fts_data->irq_lock, irqflags);
+ FTS_FUNC_EXIT();
+}
+
+void fts_hid2std(void)
+{
+ int ret = 0;
+ u8 buf[3] = {0xEB, 0xAA, 0x09};
+
+ ret = fts_write(buf, 3);
+ if (ret < 0) {
+ FTS_ERROR("hid2std cmd write fail");
+ } else {
+ msleep(10);
+ buf[0] = buf[1] = buf[2] = 0;
+ ret = fts_read(NULL, 0, buf, 3);
+ if (ret < 0) {
+ FTS_ERROR("hid2std cmd read fail");
+ } else if ((0xEB == buf[0]) && (0xAA == buf[1]) && (0x08 == buf[2])) {
+ FTS_DEBUG("hidi2c change to stdi2c successful");
+ } else {
+ FTS_DEBUG("hidi2c change to stdi2c not support or fail");
+ }
+ }
+}
+
+static int fts_get_chip_types(
+ struct fts_ts_data *ts_data,
+ u8 id_h, u8 id_l, bool fw_valid)
+{
+ int i = 0;
+ struct ft_chip_t ctype[] = FTS_CHIP_TYPE_MAPPING;
+ u32 ctype_entries = sizeof(ctype) / sizeof(struct ft_chip_t);
+
+ if ((0x0 == id_h) || (0x0 == id_l)) {
+ FTS_ERROR("id_h/id_l is 0");
+ return -EINVAL;
+ }
+
+ FTS_DEBUG("verify id:0x%02x%02x", id_h, id_l);
+ for (i = 0; i < ctype_entries; i++) {
+ if (VALID == fw_valid) {
+ if ((id_h == ctype[i].chip_idh) && (id_l == ctype[i].chip_idl))
+ break;
+ } else {
+ if (((id_h == ctype[i].rom_idh) && (id_l == ctype[i].rom_idl))
+ || ((id_h == ctype[i].pb_idh) && (id_l == ctype[i].pb_idl))
+ || ((id_h == ctype[i].bl_idh) && (id_l == ctype[i].bl_idl)))
+ break;
+ }
+ }
+
+ if (i >= ctype_entries) {
+ return -ENODATA;
+ }
+
+ ts_data->ic_info.ids = ctype[i];
+ return 0;
+}
+
+static int fts_read_bootid(struct fts_ts_data *ts_data, u8 *id)
+{
+ int ret = 0;
+ u8 chip_id[2] = { 0 };
+ u8 id_cmd[4] = { 0 };
+ u32 id_cmd_len = 0;
+
+ id_cmd[0] = FTS_CMD_START1;
+ id_cmd[1] = FTS_CMD_START2;
+ ret = fts_write(id_cmd, 2);
+ if (ret < 0) {
+ FTS_ERROR("start cmd write fail");
+ return ret;
+ }
+
+ msleep(FTS_CMD_START_DELAY);
+ id_cmd[0] = FTS_CMD_READ_ID;
+ id_cmd[1] = id_cmd[2] = id_cmd[3] = 0x00;
+ if (ts_data->ic_info.is_incell)
+ id_cmd_len = FTS_CMD_READ_ID_LEN_INCELL;
+ else
+ id_cmd_len = FTS_CMD_READ_ID_LEN;
+ ret = fts_read(id_cmd, id_cmd_len, chip_id, 2);
+ if ((ret < 0) || (0x0 == chip_id[0]) || (0x0 == chip_id[1])) {
+ FTS_ERROR("read boot id fail,read:0x%02x%02x", chip_id[0], chip_id[1]);
+ return -EIO;
+ }
+
+ id[0] = chip_id[0];
+ id[1] = chip_id[1];
+ return 0;
}
/*****************************************************************************
- * Name: fts_input_dev_init
- * Brief: input dev init
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_input_dev_init(struct i2c_client *client,
- struct fts_ts_data *data, struct input_dev *input_dev,
- struct fts_ts_platform_data *pdata)
+* Name: fts_get_ic_information
+* Brief: read chip id to get ic information, after run the function, driver w-
+* ill know which IC is it.
+* If cant get the ic information, maybe not focaltech's touch IC, need
+* unregister the driver
+* Input:
+* Output:
+* Return: return 0 if get correct ic information, otherwise return error code
+*****************************************************************************/
+static int fts_get_ic_information(struct fts_ts_data *ts_data)
{
- int err, len;
+ int ret = 0;
+ int cnt = 0;
+ u8 chip_id[2] = { 0 };
- FTS_FUNC_ENTER();
+ ts_data->ic_info.is_incell = FTS_CHIP_IDC;
+ ts_data->ic_info.hid_supported = FTS_HID_SUPPORTTED;
- /* Init and register Input device */
- input_dev->name = FTS_DRIVER_NAME;
- input_dev->id.bustype = BUS_I2C;
- input_dev->dev.parent = &client->dev;
- input_set_drvdata(input_dev, data);
- i2c_set_clientdata(client, data);
+ do {
+ ret = fts_read_reg(FTS_REG_CHIP_ID, &chip_id[0]);
+ ret = fts_read_reg(FTS_REG_CHIP_ID2, &chip_id[1]);
+ if ((ret < 0) || (0x0 == chip_id[0]) || (0x0 == chip_id[1])) {
+ FTS_DEBUG("i2c read invalid, read:0x%02x%02x",
+ chip_id[0], chip_id[1]);
+ } else {
+ ret = fts_get_chip_types(ts_data, chip_id[0], chip_id[1], VALID);
+ if (!ret)
+ break;
+ else
+ FTS_DEBUG("TP not ready, read:0x%02x%02x",
+ chip_id[0], chip_id[1]);
+ }
- __set_bit(EV_KEY, input_dev->evbit);
- if (data->pdata->have_key) {
- FTS_DEBUG("set key capabilities");
- for (len = 0; len < data->pdata->key_number; len++)
- input_set_capability(input_dev, EV_KEY,
- data->pdata->keys[len]);
- }
- __set_bit(EV_ABS, input_dev->evbit);
- __set_bit(BTN_TOUCH, input_dev->keybit);
- __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+ cnt++;
+ msleep(INTERVAL_READ_REG);
+ } while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
+ if ((cnt * INTERVAL_READ_REG) >= TIMEOUT_READ_REG) {
+ FTS_INFO("fw is invalid, need read boot id");
+ if (ts_data->ic_info.hid_supported) {
+ fts_hid2std();
+ }
+
+ ret = fts_read_bootid(ts_data, &chip_id[0]);
+ if (ret < 0) {
+ FTS_ERROR("read boot id fail");
+ return ret;
+ }
+
+ ret = fts_get_chip_types(ts_data, chip_id[0], chip_id[1], INVALID);
+ if (ret < 0) {
+ FTS_ERROR("can't get ic informaton");
+ return ret;
+ }
+ }
+
+ FTS_INFO("get ic information, chip id = 0x%02x%02x",
+ ts_data->ic_info.ids.chip_idh, ts_data->ic_info.ids.chip_idl);
+
+ return 0;
+}
+
+/*****************************************************************************
+* Reprot related
+*****************************************************************************/
+static void fts_show_touch_buffer(u8 *data, int datalen)
+{
+ int i = 0;
+ int count = 0;
+ char *tmpbuf = NULL;
+
+ tmpbuf = kzalloc(1024, GFP_KERNEL);
+ if (!tmpbuf) {
+ FTS_ERROR("tmpbuf zalloc fail");
+ return;
+ }
+
+ for (i = 0; i < datalen; i++) {
+ count += snprintf(tmpbuf + count, 1024 - count, "%02X,", data[i]);
+ if (count >= 1024)
+ break;
+ }
+ FTS_DEBUG("point buffer:%s", tmpbuf);
+
+ if (tmpbuf) {
+ kfree(tmpbuf);
+ tmpbuf = NULL;
+ }
+}
+
+void fts_release_all_finger(void)
+{
+ struct input_dev *input_dev = fts_data->input_dev;
#if FTS_MT_PROTOCOL_B_EN
- input_mt_init_slots(input_dev, pdata->max_touch_number,
- INPUT_MT_DIRECT);
+ u32 finger_count = 0;
+ u32 max_touches = fts_data->pdata->max_touch_number;
+#endif
+
+ FTS_FUNC_ENTER();
+ mutex_lock(&fts_data->report_mutex);
+#if FTS_MT_PROTOCOL_B_EN
+ for (finger_count = 0; finger_count < max_touches; finger_count++) {
+ input_mt_slot(input_dev, finger_count);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+ }
#else
- input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 0x0f, 0, 0);
+ input_mt_sync(input_dev);
#endif
- input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min,
- pdata->x_max, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min,
- pdata->y_max, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);
-#if FTS_REPORT_PRESSURE_EN
- input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
-#endif
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_sync(input_dev);
- err = input_register_device(input_dev);
- if (err) {
- FTS_ERROR("Input device registration failed");
- goto free_inputdev;
- }
-
- FTS_FUNC_EXIT();
-
- return 0;
-
-free_inputdev:
- input_free_device(input_dev);
- FTS_FUNC_EXIT();
- return err;
-
+ fts_data->touchs = 0;
+ fts_data->key_state = 0;
+ mutex_unlock(&fts_data->report_mutex);
+ FTS_FUNC_EXIT();
}
/*****************************************************************************
- * Power Control
- *****************************************************************************/
-#if FTS_POWER_SOURCE_CUST_EN
-static int fts_power_source_init(struct fts_ts_data *data)
+* Name: fts_input_report_key
+* Brief: process key events,need report key-event if key enable.
+* if point's coordinate is in (x_dim-50,y_dim-50) ~ (x_dim+50,y_dim+50),
+* need report it to key event.
+* x_dim: parse from dts, means key x_coordinate, dimension:+-50
+* y_dim: parse from dts, means key y_coordinate, dimension:+-50
+* Input:
+* Output:
+* Return: return 0 if it's key event, otherwise return error code
+*****************************************************************************/
+static int fts_input_report_key(struct fts_ts_data *data, int index)
{
- int rc;
+ int i = 0;
+ int x = data->events[index].x;
+ int y = data->events[index].y;
+ int *x_dim = &data->pdata->key_x_coords[0];
+ int *y_dim = &data->pdata->key_y_coords[0];
- FTS_FUNC_ENTER();
-
- data->vdd = regulator_get(&data->client->dev, "vdd");
- if (IS_ERR(data->vdd)) {
- rc = PTR_ERR(data->vdd);
- FTS_ERROR("Regulator get failed vdd rc=%d", rc);
- }
-
- if (regulator_count_voltages(data->vdd) > 0) {
- rc = regulator_set_voltage(data->vdd, FTS_VTG_MIN_UV,
- FTS_VTG_MAX_UV);
- if (rc) {
- FTS_ERROR("Regulator set_vtg failed vdd rc=%d", rc);
- goto reg_vdd_put;
- }
- }
-
- data->vcc_i2c = regulator_get(&data->client->dev, "vcc-i2c");
- if (IS_ERR(data->vcc_i2c)) {
- rc = PTR_ERR(data->vcc_i2c);
- FTS_ERROR("Regulator get failed vcc-i2c rc=%d", rc);
- goto reg_vdd_set_vtg;
- }
-
- if (regulator_count_voltages(data->vcc_i2c) > 0) {
- rc = regulator_set_voltage(data->vcc_i2c, FTS_I2C_VTG_MIN_UV,
- FTS_I2C_VTG_MAX_UV);
- if (rc) {
- FTS_ERROR("Regulator set_vtg failed vcc-i2c rc=%d",
- rc);
- goto reg_vcc_i2c_put;
- }
- }
-
- FTS_FUNC_EXIT();
- return 0;
-
-reg_vcc_i2c_put:
- regulator_put(data->vcc_i2c);
-reg_vdd_set_vtg:
- if (regulator_count_voltages(data->vdd) > 0)
- regulator_set_voltage(data->vdd, 0, FTS_VTG_MAX_UV);
-reg_vdd_put:
- regulator_put(data->vdd);
- FTS_FUNC_EXIT();
- return rc;
-}
-
-static int fts_power_source_ctrl(struct fts_ts_data *data, int enable)
-{
- int rc;
-
- FTS_FUNC_ENTER();
- if (enable) {
- rc = regulator_enable(data->vdd);
- if (rc)
- FTS_ERROR("Regulator vdd enable failed rc=%d", rc);
-
- rc = regulator_enable(data->vcc_i2c);
- if (rc)
- FTS_ERROR("Regulator vcc_i2c enable failed rc=%d", rc);
- } else {
- rc = regulator_disable(data->vdd);
- if (rc)
- FTS_ERROR("Regulator vdd disable failed rc=%d", rc);
-
- rc = regulator_disable(data->vcc_i2c);
- if (rc)
- FTS_ERROR("Regulator vcc_i2c disable failed rc=%d",
- rc);
- }
- FTS_FUNC_EXIT();
- return 0;
-}
-
-#endif
-
-
-/*****************************************************************************
- * Reprot related
- *****************************************************************************/
-/*****************************************************************************
- * Name: fts_release_all_finger
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_release_all_finger(void)
-{
-#if FTS_MT_PROTOCOL_B_EN
- unsigned int finger_count = 0;
-#endif
-
- mutex_lock(&fts_wq_data->report_mutex);
-#if FTS_MT_PROTOCOL_B_EN
- for (finger_count = 0;
- finger_count < fts_wq_data->pdata->max_touch_number;
- finger_count++) {
- input_mt_slot(fts_input_dev, finger_count);
- input_mt_report_slot_state(fts_input_dev, MT_TOOL_FINGER,
- false);
- }
-#else
- input_mt_sync(fts_input_dev);
-#endif
- input_report_key(fts_input_dev, BTN_TOUCH, 0);
- input_sync(fts_input_dev);
- mutex_unlock(&fts_wq_data->report_mutex);
-}
-
-
-#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
-static void fts_show_touch_buffer(u8 *buf, int point_num)
-{
- int len = point_num * FTS_ONE_TCH_LEN;
- int count = 0;
- int i;
-
- memset(g_sz_debug, 0, 1024);
- if (len > (POINT_READ_BUF-3))
- len = POINT_READ_BUF-3;
- else if (len == 0) {
- len += FTS_ONE_TCH_LEN;
-
- count += snprintf(g_sz_debug, 1024, "%02X,%02X,%02X",
- buf[0], buf[1], buf[2]);
- for (i = 0; i < len; i++)
- count += snprintf(g_sz_debug+count, 1024-count,
- ",%02X", buf[i+3]);
-
- FTS_DEBUG("buffer: %s", g_sz_debug);
-}
-#endif
-
-static int fts_input_dev_report_key_event(struct ts_event *event,
- struct fts_ts_data *data)
-{
- int i;
-
- if (!data->pdata->have_key)
- return -EINVAL;
-
- if ((1 == event->touch_point || 1 == event->point_num) &&
- (event->au16_y[0] == data->pdata->key_y_coord)) {
-
- if (event->point_num == 0) {
- FTS_DEBUG("Keys All Up!");
- for (i = 0; i < data->pdata->key_number; i++) {
- input_report_key(data->input_dev,
- data->pdata->keys[i], 0);
- }
-
- input_sync(data->input_dev);
- return 0;
- }
- for (i = 0; i < data->pdata->key_number; i++) {
- if (event->au16_x[0] > (data->pdata->key_x_coords[i]
- - FTS_KEY_WIDTH) && (event->au16_x[0] <
- (data->pdata->key_x_coords[i]
- + FTS_KEY_WIDTH))) {
- if (event->au8_touch_event[i] == 0 ||
- event->au8_touch_event[i] == 2) {
- input_report_key(data->input_dev,
- data->pdata->keys[i], 1);
- FTS_DEBUG("Key%d(%d, %d) DOWN!",
- i, event->au16_x[0],
- event->au16_y[0]);
- } else {
- input_report_key(data->input_dev,
- data->pdata->keys[i], 0);
- FTS_DEBUG("Key%d(%d, %d) Up!",
- i, event->au16_x[0],
- event->au16_y[0]);
- }
- break;
- }
- }
- input_sync(data->input_dev);
- return 0;
- }
-
- return -EINVAL;
+ if (!data->pdata->have_key) {
+ return -EINVAL;
+ }
+ for (i = 0; i < data->pdata->key_number; i++) {
+ if ((x >= x_dim[i] - FTS_KEY_DIM) && (x <= x_dim[i] + FTS_KEY_DIM) &&
+ (y >= y_dim[i] - FTS_KEY_DIM) && (y <= y_dim[i] + FTS_KEY_DIM)) {
+ if (EVENT_DOWN(data->events[index].flag)
+ && !(data->key_state & (1 << i))) {
+ input_report_key(data->input_dev, data->pdata->keys[i], 1);
+ data->key_state |= (1 << i);
+ FTS_DEBUG("Key%d(%d,%d) DOWN!", i, x, y);
+ } else if (EVENT_UP(data->events[index].flag)
+ && (data->key_state & (1 << i))) {
+ input_report_key(data->input_dev, data->pdata->keys[i], 0);
+ data->key_state &= ~(1 << i);
+ FTS_DEBUG("Key%d(%d,%d) Up!", i, x, y);
+ }
+ return 0;
+ }
+ }
+ return -EINVAL;
}
#if FTS_MT_PROTOCOL_B_EN
-static int fts_input_dev_report_b(struct ts_event *event,
- struct fts_ts_data *data)
+static int fts_input_report_b(struct fts_ts_data *data)
{
- int i = 0;
- int uppoint = 0;
- int touchs = 0;
+ int i = 0;
+ int uppoint = 0;
+ int touchs = 0;
+ bool va_reported = false;
+ u32 max_touch_num = data->pdata->max_touch_number;
+ struct ts_event *events = data->events;
- for (i = 0; i < event->touch_point; i++) {
- if (event->au8_finger_id[i] >= data->pdata->max_touch_number)
- break;
+ for (i = 0; i < data->touch_point; i++) {
+ if (fts_input_report_key(data, i) == 0) {
+ continue;
+ }
- input_mt_slot(data->input_dev, event->au8_finger_id[i]);
+ va_reported = true;
+ input_mt_slot(data->input_dev, events[i].id);
- if (event->au8_touch_event[i] == FTS_TOUCH_DOWN ||
- event->au8_touch_event[i] == FTS_TOUCH_CONTACT) {
- input_mt_report_slot_state(data->input_dev,
- MT_TOOL_FINGER, true);
+ if (EVENT_DOWN(events[i].flag)) {
+ input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true);
#if FTS_REPORT_PRESSURE_EN
-#if FTS_FORCE_TOUCH_EN
- if (event->pressure[i] <= 0) {
- FTS_ERROR("[B]Illegal pressure: %d",
- event->pressure[i]);
- event->pressure[i] = 1;
- }
-#else
- event->pressure[i] = 0x3f;
+ if (events[i].p <= 0) {
+ events[i].p = 0x3f;
+ }
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE, events[i].p);
#endif
- input_report_abs(data->input_dev, ABS_MT_PRESSURE,
- event->pressure[i]);
-#endif
+ if (events[i].area <= 0) {
+ events[i].area = 0x09;
+ }
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, events[i].area);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X, events[i].x);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y, events[i].y);
- if (event->area[i] <= 0) {
- FTS_ERROR("[B]Illegal touch-major: %d",
- event->area[i]);
- event->area[i] = 1;
- }
- input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
- event->area[i]);
+ touchs |= BIT(events[i].id);
+ data->touchs |= BIT(events[i].id);
- input_report_abs(data->input_dev, ABS_MT_POSITION_X,
- event->au16_x[i]);
- input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
- event->au16_y[i]);
- touchs |= BIT(event->au8_finger_id[i]);
- data->touchs |= BIT(event->au8_finger_id[i]);
+ if ((data->log_level >= 2) ||
+ ((1 == data->log_level) && (FTS_TOUCH_DOWN == events[i].flag))) {
+ FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
+ events[i].id,
+ events[i].x, events[i].y,
+ events[i].p, events[i].area);
+ }
+ } else {
+ uppoint++;
+ input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);
+ data->touchs &= ~BIT(events[i].id);
+ if (data->log_level >= 1) {
+ FTS_DEBUG("[B]P%d UP!", events[i].id);
+ }
+ }
+ }
-#if FTS_REPORT_PRESSURE_EN
- FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
- event->au8_finger_id[i],
- event->au16_x[i], event->au16_y[i],
- event->pressure[i], event->area[i]);
-#else
- FTS_DEBUG("[B]P%d(%d, %d)[tm:%d] DOWN!",
- event->au8_finger_id[i],
- event->au16_x[i], event->au16_y[i],
- event->area[i]);
-#endif
- } else {
- uppoint++;
-#if FTS_REPORT_PRESSURE_EN
- input_report_abs(data->input_dev, ABS_MT_PRESSURE, 0);
-#endif
- input_mt_report_slot_state(data->input_dev,
- MT_TOOL_FINGER, false);
- data->touchs &= ~BIT(event->au8_finger_id[i]);
- FTS_DEBUG("[B]P%d UP!", event->au8_finger_id[i]);
- }
- }
+ if (unlikely(data->touchs ^ touchs)) {
+ for (i = 0; i < max_touch_num; i++) {
+ if (BIT(i) & (data->touchs ^ touchs)) {
+ if (data->log_level >= 1) {
+ FTS_DEBUG("[B]P%d UP!", i);
+ }
+ va_reported = true;
+ input_mt_slot(data->input_dev, i);
+ input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);
+ }
+ }
+ }
+ data->touchs = touchs;
- if (unlikely(data->touchs ^ touchs)) {
- for (i = 0; i < data->pdata->max_touch_number; i++) {
- if (BIT(i) & (data->touchs ^ touchs)) {
- FTS_DEBUG("[B]P%d UP!", i);
- input_mt_slot(data->input_dev, i);
- input_mt_report_slot_state(data->input_dev,
- MT_TOOL_FINGER, false);
-#if FTS_REPORT_PRESSURE_EN
- input_report_abs(data->input_dev,
- ABS_MT_PRESSURE, 0);
-#endif
- }
- }
- }
+ if (va_reported) {
+ /* touchs==0, there's no point but key */
+ if (EVENT_NO_DOWN(data) || (!touchs)) {
+ if (data->log_level >= 1) {
+ FTS_DEBUG("[B]Points All Up!");
+ }
+ input_report_key(data->input_dev, BTN_TOUCH, 0);
+ } else {
+ input_report_key(data->input_dev, BTN_TOUCH, 1);
+ }
+ }
- data->touchs = touchs;
- if (event->touch_point == uppoint) {
- FTS_DEBUG("Points All Up!");
- input_report_key(data->input_dev, BTN_TOUCH, 0);
- } else {
- input_report_key(data->input_dev, BTN_TOUCH,
- event->touch_point > 0);
- }
-
- input_sync(data->input_dev);
-
- return 0;
-
+ input_sync(data->input_dev);
+ return 0;
}
#else
-static int fts_input_dev_report_a(struct ts_event *event,
- struct fts_ts_data *data)
+static int fts_input_report_a(struct fts_ts_data *data)
{
- int i = 0;
- int uppoint = 0;
- int touchs = 0;
+ int i = 0;
+ int touchs = 0;
+ bool va_reported = false;
+ struct ts_event *events = data->events;
- for (i = 0; i < event->touch_point; i++) {
+ for (i = 0; i < data->touch_point; i++) {
+ if (fts_input_report_key(data, i) == 0) {
+ continue;
+ }
- if (event->au8_touch_event[i] == FTS_TOUCH_DOWN ||
- event->au8_touch_event[i] == FTS_TOUCH_CONTACT) {
- input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
- event->au8_finger_id[i]);
+ va_reported = true;
+ if (EVENT_DOWN(events[i].flag)) {
+ input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, events[i].id);
#if FTS_REPORT_PRESSURE_EN
-#if FTS_FORCE_TOUCH_EN
- if (event->pressure[i] <= 0) {
- FTS_ERROR("[B]Illegal pressure: %d",
- event->pressure[i]);
- event->pressure[i] = 1;
- }
-#else
- event->pressure[i] = 0x3f;
+ if (events[i].p <= 0) {
+ events[i].p = 0x3f;
+ }
+ input_report_abs(data->input_dev, ABS_MT_PRESSURE, events[i].p);
#endif
- input_report_abs(data->input_dev, ABS_MT_PRESSURE,
- event->pressure[i]);
-#endif
+ if (events[i].area <= 0) {
+ events[i].area = 0x09;
+ }
+ input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, events[i].area);
- if (event->area[i] <= 0) {
- FTS_ERROR("[B]Illegal touch-major: %d",
- event->area[i]);
- event->area[i] = 1;
- }
+ input_report_abs(data->input_dev, ABS_MT_POSITION_X, events[i].x);
+ input_report_abs(data->input_dev, ABS_MT_POSITION_Y, events[i].y);
- input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
- event->area[i]);
+ input_mt_sync(data->input_dev);
- input_report_abs(data->input_dev, ABS_MT_POSITION_X,
- event->au16_x[i]);
- input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
- event->au16_y[i]);
+ if ((data->log_level >= 2) ||
+ ((1 == data->log_level) && (FTS_TOUCH_DOWN == events[i].flag))) {
+ FTS_DEBUG("[A]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
+ events[i].id,
+ events[i].x, events[i].y,
+ events[i].p, events[i].area);
+ }
+ touchs++;
+ }
+ }
- input_mt_sync(data->input_dev);
+ /* last point down, current no point but key */
+ if (data->touchs && !touchs) {
+ va_reported = true;
+ }
+ data->touchs = touchs;
-#if FTS_REPORT_PRESSURE_EN
- FTS_DEBUG("[B]P%d(%d, %d)[p:%d,tm:%d] DOWN!",
- event->au8_finger_id[i],
- event->au16_x[i], event->au16_y[i],
- event->pressure[i], event->area[i]);
-#else
- FTS_DEBUG("[B]P%d(%d, %d)[tm:%d] DOWN!",
- event->au8_finger_id[i],
- event->au16_x[i], event->au16_y[i],
- event->area[i]);
-#endif
- } else {
- uppoint++;
- }
- }
+ if (va_reported) {
+ if (EVENT_NO_DOWN(data)) {
+ if (data->log_level >= 1) {
+ FTS_DEBUG("[A]Points All Up!");
+ }
+ input_report_key(data->input_dev, BTN_TOUCH, 0);
+ input_mt_sync(data->input_dev);
+ } else {
+ input_report_key(data->input_dev, BTN_TOUCH, 1);
+ }
+ }
- data->touchs = touchs;
- if (event->touch_point == uppoint) {
- FTS_DEBUG("Points All Up!");
- input_report_key(data->input_dev, BTN_TOUCH, 0);
- input_mt_sync(data->input_dev);
- } else {
- input_report_key(data->input_dev, BTN_TOUCH,
- event->touch_point > 0);
- }
-
- input_sync(data->input_dev);
-
- return 0;
+ input_sync(data->input_dev);
+ return 0;
}
#endif
-/*****************************************************************************
- * Name: fts_read_touchdata
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
static int fts_read_touchdata(struct fts_ts_data *data)
{
- u8 buf[POINT_READ_BUF] = { 0 };
- u8 pointid = FTS_MAX_ID;
- int ret = -1;
- int i;
- struct ts_event *event = &(data->event);
+ int ret = 0;
+ u8 *buf = data->point_buf;
-#if FTS_GESTURE_EN
- u8 state;
-
- if (data->suspended && data->pdata->wakeup_gestures_en) {
- fts_i2c_read_reg(data->client, FTS_REG_GESTURE_EN, &state);
- if (state == 1) {
- fts_gesture_readdata(data->client);
- return 1;
- }
- }
-#endif
-
-#if FTS_PSENSOR_EN
- if ((fts_sensor_read_data(data) != 0) && (data->suspended == 1))
- return 1;
-#endif
+ memset(buf, 0xFF, data->pnt_buf_size);
+ buf[0] = 0x01;
-#if FTS_READ_TOUCH_BUFFER_DIVIDED
- memset(buf, 0xFF, POINT_READ_BUF);
- memset(event, 0, sizeof(struct ts_event));
+ if (data->gesture_mode) {
+ if (0 == fts_gesture_readdata(data, NULL)) {
+ FTS_DEBUG("succuss to get gesture data in irq handler");
+ return 1;
+ }
+ }
- buf[0] = 0x00;
- ret = fts_i2c_read(data->client, buf, 1, buf, (3 + FTS_ONE_TCH_LEN));
- if (ret < 0) {
- FTS_ERROR("%s read touchdata failed.", __func__);
- return ret;
- }
- event->touch_point = 0;
- event->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
- if (event->point_num > data->pdata->max_touch_number)
- event->point_num = data->pdata->max_touch_number;
+ ret = fts_read(buf, 1, buf + 1, data->pnt_buf_size - 1);
+ if (ret < 0) {
+ FTS_ERROR("read touchdata failed, ret:%d", ret);
+ return ret;
+ }
- if (event->point_num > 1) {
- buf[9] = 0x09;
- fts_i2c_read(data->client, buf+9, 1, buf+9,
- (event->point_num - 1) * FTS_ONE_TCH_LEN);
- }
-#else
- ret = fts_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
- if (ret < 0) {
- FTS_ERROR("[B]Read touchdata failed, ret: %d", ret);
- return ret;
- }
+ if (data->log_level >= 3) {
+ fts_show_touch_buffer(buf, data->pnt_buf_size);
+ }
-#if FTS_POINT_REPORT_CHECK_EN
- fts_point_report_check_queue_work();
-#endif
-
- memset(event, 0, sizeof(struct ts_event));
- event->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
- if (event->point_num > data->pdata->max_touch_number)
- event->point_num = data->pdata->max_touch_number;
- event->touch_point = 0;
-#endif
-
-#if (FTS_DEBUG_EN && (FTS_DEBUG_LEVEL == 2))
- fts_show_touch_buffer(buf, event->point_num);
-#endif
-
- for (i = 0; i < data->pdata->max_touch_number; i++) {
- pointid = (buf[FTS_TOUCH_ID_POS + FTS_ONE_TCH_LEN * i]) >> 4;
- if (pointid >= FTS_MAX_ID)
- break;
-
- event->touch_point++;
-
- event->au16_x[i] =
- (s16) (buf[FTS_TOUCH_X_H_POS + FTS_ONE_TCH_LEN * i]
- & 0x0F) << 8 | (s16) buf[FTS_TOUCH_X_L_POS +
- FTS_ONE_TCH_LEN * i];
- event->au16_y[i] =
- (s16) (buf[FTS_TOUCH_Y_H_POS + FTS_ONE_TCH_LEN * i]
- & 0x0F) << 8 | (s16) buf[FTS_TOUCH_Y_L_POS +
- FTS_ONE_TCH_LEN * i];
- event->au8_touch_event[i] =
- buf[FTS_TOUCH_EVENT_POS + FTS_ONE_TCH_LEN * i] >> 6;
- event->au8_finger_id[i] =
- (buf[FTS_TOUCH_ID_POS + FTS_ONE_TCH_LEN * i]) >> 4;
- event->area[i] =
- (buf[FTS_TOUCH_AREA_POS + FTS_ONE_TCH_LEN * i]) >> 4;
- event->pressure[i] =
- (s16) buf[FTS_TOUCH_PRE_POS + FTS_ONE_TCH_LEN * i];
-
- if (event->area[i] == 0)
- event->area[i] = 0x09;
-
- if (event->pressure[i] == 0)
- event->pressure[i] = 0x3f;
-
- if ((event->au8_touch_event[i] == 0 ||
- event->au8_touch_event[i] == 2) &&
- (event->point_num == 0)) {
- FTS_DEBUG("abnormal touch data from fw");
- return -EINVAL;
- }
- }
-
- if (event->touch_point == 0)
- return -EINVAL;
-
- return 0;
+ return 0;
}
-/*****************************************************************************
- * Name: fts_report_value
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_report_value(struct fts_ts_data *data)
+static int fts_read_parse_touchdata(struct fts_ts_data *data)
{
- struct ts_event *event = &data->event;
+ int ret = 0;
+ int i = 0;
+ u8 pointid = 0;
+ int base = 0;
+ struct ts_event *events = data->events;
+ int max_touch_num = data->pdata->max_touch_number;
+ u8 *buf = data->point_buf;
+ ret = fts_read_touchdata(data);
+ if (ret) {
+ return ret;
+ }
- FTS_DEBUG("point number: %d, touch point: %d", event->point_num,
- event->touch_point);
+ data->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
+ data->touch_point = 0;
- if (fts_input_dev_report_key_event(event, data) == 0)
- return;
+ if (data->ic_info.is_incell) {
+ if ((data->point_num == 0x0F) && (buf[2] == 0xFF) && (buf[3] == 0xFF)
+ && (buf[4] == 0xFF) && (buf[5] == 0xFF) && (buf[6] == 0xFF)) {
+ FTS_DEBUG("touch buff is 0xff, need recovery state");
+ fts_release_all_finger();
+ fts_tp_state_recovery(data);
+ return -EIO;
+ }
+ }
+
+ if (data->point_num > max_touch_num) {
+ FTS_DEBUG("invalid point_num(%d)", data->point_num);
+ return -EIO;
+ }
+
+ for (i = 0; i < max_touch_num; i++) {
+ base = FTS_ONE_TCH_LEN * i;
+ pointid = (buf[FTS_TOUCH_ID_POS + base]) >> 4;
+ if (pointid >= FTS_MAX_ID)
+ break;
+ else if (pointid >= max_touch_num) {
+ FTS_ERROR("ID(%d) beyond max_touch_number", pointid);
+ return -EINVAL;
+ }
+
+ data->touch_point++;
+ events[i].x = ((buf[FTS_TOUCH_X_H_POS + base] & 0x0F) << 8) +
+ (buf[FTS_TOUCH_X_L_POS + base] & 0xFF);
+ events[i].y = ((buf[FTS_TOUCH_Y_H_POS + base] & 0x0F) << 8) +
+ (buf[FTS_TOUCH_Y_L_POS + base] & 0xFF);
+ events[i].flag = buf[FTS_TOUCH_EVENT_POS + base] >> 6;
+ events[i].id = buf[FTS_TOUCH_ID_POS + base] >> 4;
+ events[i].area = buf[FTS_TOUCH_AREA_POS + base] >> 4;
+ events[i].p = buf[FTS_TOUCH_PRE_POS + base];
+
+ if (EVENT_DOWN(events[i].flag) && (data->point_num == 0)) {
+ FTS_INFO("abnormal touch data from fw");
+ return -EIO;
+ }
+ }
+
+ if (data->touch_point == 0) {
+ FTS_INFO("no touch point information");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void fts_irq_read_report(void)
+{
+ int ret = 0;
+ struct fts_ts_data *ts_data = fts_data;
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_set_intr(1);
+#endif
+
+#if FTS_POINT_REPORT_CHECK_EN
+ fts_prc_queue_work(ts_data);
+#endif
+
+ ret = fts_read_parse_touchdata(ts_data);
+ if (ret == 0) {
+ mutex_lock(&ts_data->report_mutex);
+#if FTS_MT_PROTOCOL_B_EN
+ fts_input_report_b(ts_data);
+#else
+ fts_input_report_a(ts_data);
+#endif
+ mutex_unlock(&ts_data->report_mutex);
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_set_intr(0);
+#endif
+}
+
+static irqreturn_t fts_irq_handler(int irq, void *data)
+{
+ fts_irq_read_report();
+ return IRQ_HANDLED;
+}
+
+static int fts_irq_registration(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+ struct fts_ts_platform_data *pdata = ts_data->pdata;
+
+ ts_data->irq = gpio_to_irq(pdata->irq_gpio);
+ pdata->irq_gpio_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+ FTS_INFO("irq:%d, flag:%x", ts_data->irq, pdata->irq_gpio_flags);
+ ret = request_threaded_irq(ts_data->irq, NULL, fts_irq_handler,
+ pdata->irq_gpio_flags,
+ FTS_DRIVER_NAME, ts_data);
+
+ return ret;
+}
+
+static int fts_input_init(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+ int key_num = 0;
+ struct fts_ts_platform_data *pdata = ts_data->pdata;
+ struct input_dev *input_dev;
+
+ FTS_FUNC_ENTER();
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ FTS_ERROR("Failed to allocate memory for input device");
+ return -ENOMEM;
+ }
+
+ /* Init and register Input device */
+ input_dev->name = FTS_DRIVER_NAME;
+
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->dev.parent = ts_data->dev;
+
+ input_set_drvdata(input_dev, ts_data);
+
+ __set_bit(EV_SYN, input_dev->evbit);
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+ __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+ if (pdata->have_key) {
+ FTS_INFO("set key capabilities");
+ for (key_num = 0; key_num < pdata->key_number; key_num++)
+ input_set_capability(input_dev, EV_KEY, pdata->keys[key_num]);
+ }
#if FTS_MT_PROTOCOL_B_EN
- fts_input_dev_report_b(event, data);
+ input_mt_init_slots(input_dev, pdata->max_touch_number, INPUT_MT_DIRECT);
#else
- fts_input_dev_report_a(event, data);
+ input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 0x0F, 0, 0);
+#endif
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min, pdata->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min, pdata->y_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);
+#if FTS_REPORT_PRESSURE_EN
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
#endif
+ ret = input_register_device(input_dev);
+ if (ret) {
+ FTS_ERROR("Input device registration failed");
+ input_set_drvdata(input_dev, NULL);
+ input_free_device(input_dev);
+ input_dev = NULL;
+ return ret;
+ }
- return;
+ ts_data->input_dev = input_dev;
+ FTS_FUNC_EXIT();
+ return 0;
}
-/*****************************************************************************
- * Name: fts_ts_interrupt
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static irqreturn_t fts_ts_interrupt(int irq, void *dev_id)
+static int fts_report_buffer_init(struct fts_ts_data *ts_data)
{
- struct fts_ts_data *fts_ts = dev_id;
- int ret = -1;
+ int point_num = 0;
+ int events_num = 0;
- if (!fts_ts) {
- FTS_ERROR("[INTR]: Invalid fts_ts");
- return IRQ_HANDLED;
- }
-#if FTS_ESDCHECK_EN
- fts_esdcheck_set_intr(1);
-#endif
+ point_num = ts_data->pdata->max_touch_number;
+ ts_data->pnt_buf_size = point_num * FTS_ONE_TCH_LEN + 3;
+ ts_data->point_buf = (u8 *)kzalloc(ts_data->pnt_buf_size + 1, GFP_KERNEL);
+ if (!ts_data->point_buf) {
+ FTS_ERROR("failed to alloc memory for point buf");
+ return -ENOMEM;
+ }
- ret = fts_read_touchdata(fts_wq_data);
+ events_num = point_num * sizeof(struct ts_event);
+ ts_data->events = (struct ts_event *)kzalloc(events_num, GFP_KERNEL);
+ if (!ts_data->events) {
+ FTS_ERROR("failed to alloc memory for point events");
+ kfree_safe(ts_data->point_buf);
+ return -ENOMEM;
+ }
- if (ret == 0) {
- mutex_lock(&fts_wq_data->report_mutex);
- fts_report_value(fts_wq_data);
- mutex_unlock(&fts_wq_data->report_mutex);
- }
-
-#if FTS_ESDCHECK_EN
- fts_esdcheck_set_intr(0);
-#endif
-
- return IRQ_HANDLED;
+ return 0;
}
-/*****************************************************************************
- * Name: fts_gpio_configure
- * Brief: Configure IRQ&RESET GPIO
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_gpio_configure(struct fts_ts_data *data)
-{
- int err = 0;
-
- FTS_FUNC_ENTER();
- /* request irq gpio */
- if (gpio_is_valid(data->pdata->irq_gpio)) {
- err = gpio_request(data->pdata->irq_gpio, "fts_irq_gpio");
- if (err) {
- FTS_ERROR("[GPIO]irq gpio request failed");
- goto err_irq_gpio_req;
- }
-
- err = gpio_direction_input(data->pdata->irq_gpio);
- if (err) {
- FTS_ERROR("[GPIO]set_direction for irq gpio failed");
- goto err_irq_gpio_dir;
- }
- }
- /* request reset gpio */
- if (gpio_is_valid(data->pdata->reset_gpio)) {
- err = gpio_request(data->pdata->reset_gpio, "fts_reset_gpio");
- if (err) {
- FTS_ERROR("[GPIO]reset gpio request failed");
- goto err_irq_gpio_dir;
- }
-
- err = gpio_direction_output(data->pdata->reset_gpio, 1);
- if (err) {
- FTS_ERROR("[GPIO]set_direction for reset gpio failed");
- goto err_reset_gpio_dir;
- }
- }
-
- FTS_FUNC_EXIT();
- return 0;
-
-err_reset_gpio_dir:
- if (gpio_is_valid(data->pdata->reset_gpio))
- gpio_free(data->pdata->reset_gpio);
-err_irq_gpio_dir:
- if (gpio_is_valid(data->pdata->irq_gpio))
- gpio_free(data->pdata->irq_gpio);
-err_irq_gpio_req:
- FTS_FUNC_EXIT();
- return err;
-}
-
-
-/*****************************************************************************
- * Name: fts_get_dt_coords
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_get_dt_coords(struct device *dev, char *name,
- struct fts_ts_platform_data *pdata)
-{
- u32 coords[FTS_COORDS_ARR_SIZE];
- struct property *prop;
- struct device_node *np = dev->of_node;
- int coords_size, rc;
-
- prop = of_find_property(np, name, NULL);
- if (!prop)
- return -EINVAL;
- if (!prop->value)
- return -ENODATA;
-
-
- coords_size = prop->length / sizeof(u32);
- if (coords_size != FTS_COORDS_ARR_SIZE) {
- FTS_ERROR("invalid %s", name);
- return -EINVAL;
- }
-
- rc = of_property_read_u32_array(np, name, coords, coords_size);
- if (rc && (rc != -EINVAL)) {
- FTS_ERROR("Unable to read %s", name);
- return rc;
- }
-
- if (!strcmp(name, "focaltech,display-coords")) {
- pdata->x_min = coords[0];
- pdata->y_min = coords[1];
- pdata->x_max = coords[2];
- pdata->y_max = coords[3];
- } else {
- FTS_ERROR("unsupported property %s", name);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*****************************************************************************
- * Name: fts_parse_dt
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_parse_dt(struct device *dev, struct fts_ts_platform_data *pdata)
-{
- int rc;
- struct device_node *np = dev->of_node;
- u32 temp_val;
-
- FTS_FUNC_ENTER();
-
- rc = fts_get_dt_coords(dev, "focaltech,display-coords", pdata);
- if (rc)
- FTS_ERROR("Unable to get display-coords");
-
- /* key */
- pdata->have_key = of_property_read_bool(np, "focaltech,have-key");
- if (pdata->have_key) {
- rc = of_property_read_u32(np, "focaltech,key-number",
- &pdata->key_number);
- if (rc)
- FTS_ERROR("Key number undefined!");
-
- rc = of_property_read_u32_array(np, "focaltech,keys",
- pdata->keys, pdata->key_number);
- if (rc)
- FTS_ERROR("Keys undefined!");
-
- rc = of_property_read_u32(np, "focaltech,key-y-coord",
- &pdata->key_y_coord);
- if (rc)
- FTS_ERROR("Key Y Coord undefined!");
-
- rc = of_property_read_u32_array(np, "focaltech,key-x-coords",
- pdata->key_x_coords, pdata->key_number);
- if (rc)
- FTS_ERROR("Key X Coords undefined!");
-
- FTS_DEBUG("%d: (%d, %d, %d), [%d, %d, %d][%d]",
- pdata->key_number, pdata->keys[0],
- pdata->keys[1], pdata->keys[2],
- pdata->key_x_coords[0],
- pdata->key_x_coords[1],
- pdata->key_x_coords[2],
- pdata->key_y_coord);
- }
-
- /* reset, irq gpio info */
- pdata->reset_gpio = of_get_named_gpio_flags(np,
- "focaltech,reset-gpio", 0,
- &pdata->reset_gpio_flags);
- if (pdata->reset_gpio < 0)
- FTS_ERROR("Unable to get reset_gpio");
-
- pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio",
- 0, &pdata->irq_gpio_flags);
- if (pdata->irq_gpio < 0)
- FTS_ERROR("Unable to get irq_gpio");
-
- rc = of_property_read_u32(np, "focaltech,max-touch-number", &temp_val);
- if (!rc) {
- pdata->max_touch_number = temp_val;
- FTS_DEBUG("max_touch_number=%d", pdata->max_touch_number);
- } else {
- FTS_ERROR("Unable to get max-touch-number");
- pdata->max_touch_number = FTS_MAX_POINTS;
- }
-
- pdata->wakeup_gestures_en = of_property_read_bool(np,
- "focaltech,wakeup-gestures-en");
-
- FTS_FUNC_EXIT();
- return 0;
-}
-
-#if defined(CONFIG_FB)
-/*****************************************************************************
- * Name: fb_notifier_callback
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fb_notifier_callback(struct notifier_block *self,
- unsigned long event, void *data)
-{
- struct fb_event *evdata = data;
- int *blank;
- struct fts_ts_data *fts_data =
- container_of(self, struct fts_ts_data, fb_notif);
-
- if (evdata && evdata->data && event == FB_EVENT_BLANK &&
- fts_data && fts_data->client) {
- blank = evdata->data;
- if (*blank == FB_BLANK_UNBLANK)
- fts_ts_resume(&fts_data->client->dev);
- else if (*blank == FB_BLANK_POWERDOWN ||
- *blank == FB_BLANK_VSYNC_SUSPEND)
- fts_ts_suspend(&fts_data->client->dev);
- }
-
- return 0;
-}
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
-/*****************************************************************************
- * Name: fts_ts_early_suspend
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_ts_early_suspend(struct early_suspend *handler)
-{
- struct fts_ts_data *data = container_of(handler,
- struct fts_ts_data,
- early_suspend);
-
- fts_ts_suspend(&data->client->dev);
-}
-
-/*****************************************************************************
- * Name: fts_ts_late_resume
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_ts_late_resume(struct early_suspend *handler)
-{
- struct fts_ts_data *data = container_of(handler,
- struct fts_ts_data,
- early_suspend);
-
- fts_ts_resume(&data->client->dev);
-}
-#endif
-
-/*****************************************************************************
- * Name: fts_ts_probe
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct fts_ts_platform_data *pdata;
- struct fts_ts_data *data;
- struct input_dev *input_dev;
- int err;
-
- FTS_FUNC_ENTER();
- /* 1. Get Platform data */
- if (client->dev.of_node) {
- pdata = devm_kzalloc(&client->dev,
- sizeof(struct fts_ts_platform_data),
- GFP_KERNEL);
- if (!pdata) {
- FTS_ERROR("[MEMORY]Failed to allocate memory");
- FTS_FUNC_EXIT();
- return -ENOMEM;
- }
-
- err = fts_parse_dt(&client->dev, pdata);
- if (err)
- FTS_ERROR("[DTS]DT parsing failed");
- } else {
- pdata = client->dev.platform_data;
- }
-
- if (!pdata) {
- FTS_ERROR("Invalid pdata");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- FTS_ERROR("I2C not supported");
- FTS_FUNC_EXIT();
- return -ENODEV;
- }
-
- data = devm_kzalloc(&client->dev, sizeof(struct fts_ts_data),
- GFP_KERNEL);
- if (!data) {
- FTS_ERROR("[MEMORY]Failed to allocate memory");
- FTS_FUNC_EXIT();
- return -ENOMEM;
- }
-
- input_dev = input_allocate_device();
- if (!input_dev) {
- FTS_ERROR("[INPUT]Failed to allocate input device");
- FTS_FUNC_EXIT();
- return -ENOMEM;
- }
-
- data->input_dev = input_dev;
- data->client = client;
- data->pdata = pdata;
-
- fts_wq_data = data;
- fts_i2c_client = client;
- fts_input_dev = input_dev;
-
- spin_lock_init(&fts_wq_data->irq_lock);
- mutex_init(&fts_wq_data->report_mutex);
-
- fts_input_dev_init(client, data, input_dev, pdata);
-
#if FTS_POWER_SOURCE_CUST_EN
- fts_power_source_init(data);
- fts_power_source_ctrl(data, 1);
+/*****************************************************************************
+* Power Control
+*****************************************************************************/
+#if FTS_PINCTRL_EN
+static int fts_pinctrl_init(struct fts_ts_data *ts)
+{
+ int ret = 0;
+
+ ts->pinctrl = devm_pinctrl_get(ts->dev);
+ if (IS_ERR_OR_NULL(ts->pinctrl)) {
+ FTS_ERROR("Failed to get pinctrl, please check dts");
+ ret = PTR_ERR(ts->pinctrl);
+ goto err_pinctrl_get;
+ }
+
+ ts->pins_active = pinctrl_lookup_state(ts->pinctrl, "pmx_ts_active");
+ if (IS_ERR_OR_NULL(ts->pins_active)) {
+ FTS_ERROR("Pin state[active] not found");
+ ret = PTR_ERR(ts->pins_active);
+ goto err_pinctrl_lookup;
+ }
+
+ ts->pins_suspend = pinctrl_lookup_state(ts->pinctrl, "pmx_ts_suspend");
+ if (IS_ERR_OR_NULL(ts->pins_suspend)) {
+ FTS_ERROR("Pin state[suspend] not found");
+ ret = PTR_ERR(ts->pins_suspend);
+ goto err_pinctrl_lookup;
+ }
+
+ ts->pins_release = pinctrl_lookup_state(ts->pinctrl, "pmx_ts_release");
+ if (IS_ERR_OR_NULL(ts->pins_release)) {
+ FTS_ERROR("Pin state[release] not found");
+ ret = PTR_ERR(ts->pins_release);
+ }
+
+ return 0;
+err_pinctrl_lookup:
+ if (ts->pinctrl) {
+ devm_pinctrl_put(ts->pinctrl);
+ }
+err_pinctrl_get:
+ ts->pinctrl = NULL;
+ ts->pins_release = NULL;
+ ts->pins_suspend = NULL;
+ ts->pins_active = NULL;
+ return ret;
+}
+
+static int fts_pinctrl_select_normal(struct fts_ts_data *ts)
+{
+ int ret = 0;
+
+ if (ts->pinctrl && ts->pins_active) {
+ ret = pinctrl_select_state(ts->pinctrl, ts->pins_active);
+ if (ret < 0) {
+ FTS_ERROR("Set normal pin state error:%d", ret);
+ }
+ }
+
+ return ret;
+}
+
+static int fts_pinctrl_select_suspend(struct fts_ts_data *ts)
+{
+ int ret = 0;
+
+ if (ts->pinctrl && ts->pins_suspend) {
+ ret = pinctrl_select_state(ts->pinctrl, ts->pins_suspend);
+ if (ret < 0) {
+ FTS_ERROR("Set suspend pin state error:%d", ret);
+ }
+ }
+
+ return ret;
+}
+
+static int fts_pinctrl_select_release(struct fts_ts_data *ts)
+{
+ int ret = 0;
+
+ if (ts->pinctrl) {
+ if (IS_ERR_OR_NULL(ts->pins_release)) {
+ devm_pinctrl_put(ts->pinctrl);
+ ts->pinctrl = NULL;
+ } else {
+ ret = pinctrl_select_state(ts->pinctrl, ts->pins_release);
+ if (ret < 0)
+ FTS_ERROR("Set gesture pin state error:%d", ret);
+ }
+ }
+
+ return ret;
+}
+#endif /* FTS_PINCTRL_EN */
+
+static int fts_power_source_ctrl(struct fts_ts_data *ts_data, int enable)
+{
+ int ret = 0;
+
+ if (IS_ERR_OR_NULL(ts_data->vdd)) {
+ FTS_ERROR("vdd is invalid");
+ return -EINVAL;
+ }
+
+ FTS_FUNC_ENTER();
+ if (enable) {
+ if (ts_data->power_disabled) {
+ FTS_DEBUG("regulator enable !");
+ gpio_direction_output(ts_data->pdata->reset_gpio, 0);
+ msleep(1);
+ ret = regulator_enable(ts_data->vdd);
+ if (ret) {
+ FTS_ERROR("enable vdd regulator failed,ret=%d", ret);
+ }
+
+ if (!IS_ERR_OR_NULL(ts_data->vcc_i2c)) {
+ ret = regulator_enable(ts_data->vcc_i2c);
+ if (ret) {
+ FTS_ERROR("enable vcc_i2c regulator failed,ret=%d", ret);
+ }
+ }
+ ts_data->power_disabled = false;
+ }
+ } else {
+ if (!ts_data->power_disabled) {
+ FTS_DEBUG("regulator disable !");
+ gpio_direction_output(ts_data->pdata->reset_gpio, 0);
+ msleep(1);
+ ret = regulator_disable(ts_data->vdd);
+ if (ret) {
+ FTS_ERROR("disable vdd regulator failed,ret=%d", ret);
+ }
+ if (!IS_ERR_OR_NULL(ts_data->vcc_i2c)) {
+ ret = regulator_disable(ts_data->vcc_i2c);
+ if (ret) {
+ FTS_ERROR("disable vcc_i2c regulator failed,ret=%d", ret);
+ }
+ }
+ ts_data->power_disabled = true;
+ }
+ }
+
+ FTS_FUNC_EXIT();
+ return ret;
+}
+
+/*****************************************************************************
+* Name: fts_power_source_init
+* Brief: Init regulator power:vdd/vcc_io(if have), generally, no vcc_io
+* vdd---->vdd-supply in dts, kernel will auto add "-supply" to parse
+* Must be call after fts_gpio_configure() execute,because this function
+* will operate reset-gpio which request gpio in fts_gpio_configure()
+* Input:
+* Output:
+* Return: return 0 if init power successfully, otherwise return error code
+*****************************************************************************/
+static int fts_power_source_init(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+
+ FTS_FUNC_ENTER();
+ ts_data->vdd = regulator_get(ts_data->dev, "vdd");
+ if (IS_ERR_OR_NULL(ts_data->vdd)) {
+ ret = PTR_ERR(ts_data->vdd);
+ FTS_ERROR("get vdd regulator failed,ret=%d", ret);
+ return ret;
+ }
+
+ if (regulator_count_voltages(ts_data->vdd) > 0) {
+ ret = regulator_set_voltage(ts_data->vdd, FTS_VTG_MIN_UV,
+ FTS_VTG_MAX_UV);
+ if (ret) {
+ FTS_ERROR("vdd regulator set_vtg failed ret=%d", ret);
+ regulator_put(ts_data->vdd);
+ return ret;
+ }
+ }
+
+ ts_data->vcc_i2c = regulator_get(ts_data->dev, "vcc_i2c");
+ if (!IS_ERR_OR_NULL(ts_data->vcc_i2c)) {
+ if (regulator_count_voltages(ts_data->vcc_i2c) > 0) {
+ ret = regulator_set_voltage(ts_data->vcc_i2c,
+ FTS_I2C_VTG_MIN_UV,
+ FTS_I2C_VTG_MAX_UV);
+ if (ret) {
+ FTS_ERROR("vcc_i2c regulator set_vtg failed,ret=%d", ret);
+ regulator_put(ts_data->vcc_i2c);
+ }
+ }
+ }
+
+#if FTS_PINCTRL_EN
+ fts_pinctrl_init(ts_data);
+ fts_pinctrl_select_normal(ts_data);
#endif
- fts_ctpm_get_upgrade_array();
+ ts_data->power_disabled = true;
+ ret = fts_power_source_ctrl(ts_data, ENABLE);
+ if (ret) {
+ FTS_ERROR("fail to enable power(regulator)");
+ }
- err = fts_gpio_configure(data);
- if (err < 0) {
- FTS_ERROR("[GPIO]Failed to configure the gpios");
- goto free_gpio;
- }
+ FTS_FUNC_EXIT();
+ return ret;
+}
- fts_reset_proc(200);
- fts_wait_tp_to_valid(client);
-
- err = request_threaded_irq(client->irq, NULL, fts_ts_interrupt,
- pdata->irq_gpio_flags | IRQF_ONESHOT |
- IRQF_TRIGGER_FALLING,
- client->dev.driver->name, data);
- if (err) {
- FTS_ERROR("Request irq failed!");
- goto free_gpio;
- }
-
- fts_irq_disable();
-
-#if FTS_PSENSOR_EN
- if (fts_sensor_init(data) != 0) {
- FTS_ERROR("fts_sensor_init failed!");
- FTS_FUNC_EXIT();
- return 0;
- }
+static int fts_power_source_exit(struct fts_ts_data *ts_data)
+{
+#if FTS_PINCTRL_EN
+ fts_pinctrl_select_release(ts_data);
#endif
-#if FTS_APK_NODE_EN
- fts_create_apk_debug_channel(client);
+ fts_power_source_ctrl(ts_data, DISABLE);
+
+ if (!IS_ERR_OR_NULL(ts_data->vdd)) {
+ if (regulator_count_voltages(ts_data->vdd) > 0)
+ regulator_set_voltage(ts_data->vdd, 0, FTS_VTG_MAX_UV);
+ regulator_put(ts_data->vdd);
+ }
+
+ if (!IS_ERR_OR_NULL(ts_data->vcc_i2c)) {
+ if (regulator_count_voltages(ts_data->vcc_i2c) > 0)
+ regulator_set_voltage(ts_data->vcc_i2c, 0, FTS_I2C_VTG_MAX_UV);
+ regulator_put(ts_data->vcc_i2c);
+ }
+
+ return 0;
+}
+
+static int fts_power_source_suspend(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+
+#if FTS_PINCTRL_EN
+ fts_pinctrl_select_suspend(ts_data);
#endif
-#if FTS_SYSFS_NODE_EN
- fts_create_sysfs(client);
+ ret = fts_power_source_ctrl(ts_data, DISABLE);
+ if (ret < 0) {
+ FTS_ERROR("power off fail, ret=%d", ret);
+ }
+
+ return ret;
+}
+
+static int fts_power_source_resume(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+
+#if FTS_PINCTRL_EN
+ fts_pinctrl_select_normal(ts_data);
#endif
-#if FTS_POINT_REPORT_CHECK_EN
- fts_point_report_check_init();
-#endif
+ ret = fts_power_source_ctrl(ts_data, ENABLE);
+ if (ret < 0) {
+ FTS_ERROR("power on fail, ret=%d", ret);
+ }
- fts_ex_mode_init(client);
+ return ret;
+}
+#endif /* FTS_POWER_SOURCE_CUST_EN */
-#if FTS_GESTURE_EN
- fts_gesture_init(input_dev, client);
-#endif
+static int fts_gpio_configure(struct fts_ts_data *data)
+{
+ int ret = 0;
-#if FTS_ESDCHECK_EN
- fts_esdcheck_init();
-#endif
+ FTS_FUNC_ENTER();
+ /* request irq gpio */
+ if (gpio_is_valid(data->pdata->irq_gpio)) {
+ ret = gpio_request(data->pdata->irq_gpio, "fts_irq_gpio");
+ if (ret) {
+ FTS_ERROR("[GPIO]irq gpio request failed");
+ goto err_irq_gpio_req;
+ }
- fts_irq_enable();
+ ret = gpio_direction_input(data->pdata->irq_gpio);
+ if (ret) {
+ FTS_ERROR("[GPIO]set_direction for irq gpio failed");
+ goto err_irq_gpio_dir;
+ }
+ }
-#if FTS_AUTO_UPGRADE_EN
- fts_ctpm_upgrade_init();
-#endif
+ /* request reset gpio */
+ if (gpio_is_valid(data->pdata->reset_gpio)) {
+ ret = gpio_request(data->pdata->reset_gpio, "fts_reset_gpio");
+ if (ret) {
+ FTS_ERROR("[GPIO]reset gpio request failed");
+ goto err_irq_gpio_dir;
+ }
-#if FTS_TEST_EN
- fts_test_init(client);
-#endif
+ ret = gpio_direction_output(data->pdata->reset_gpio, 1);
+ if (ret) {
+ FTS_ERROR("[GPIO]set_direction for reset gpio failed");
+ goto err_reset_gpio_dir;
+ }
+ }
-#if defined(CONFIG_FB)
- data->fb_notif.notifier_call = fb_notifier_callback;
- err = fb_register_client(&data->fb_notif);
- if (err)
- FTS_ERROR("[FB]Unable to register fb_notifier: %d", err);
+ FTS_FUNC_EXIT();
+ return 0;
+
+err_reset_gpio_dir:
+ if (gpio_is_valid(data->pdata->reset_gpio))
+ gpio_free(data->pdata->reset_gpio);
+err_irq_gpio_dir:
+ if (gpio_is_valid(data->pdata->irq_gpio))
+ gpio_free(data->pdata->irq_gpio);
+err_irq_gpio_req:
+ FTS_FUNC_EXIT();
+ return ret;
+}
+
+static int fts_get_dt_coords(struct device *dev, char *name,
+ struct fts_ts_platform_data *pdata)
+{
+ int ret = 0;
+ u32 coords[FTS_COORDS_ARR_SIZE] = { 0 };
+ struct property *prop;
+ struct device_node *np = dev->of_node;
+ int coords_size;
+
+ prop = of_find_property(np, name, NULL);
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != FTS_COORDS_ARR_SIZE) {
+ FTS_ERROR("invalid:%s, size:%d", name, coords_size);
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_array(np, name, coords, coords_size);
+ if (ret < 0) {
+ FTS_ERROR("Unable to read %s, please check dts", name);
+ pdata->x_min = FTS_X_MIN_DISPLAY_DEFAULT;
+ pdata->y_min = FTS_Y_MIN_DISPLAY_DEFAULT;
+ pdata->x_max = FTS_X_MAX_DISPLAY_DEFAULT;
+ pdata->y_max = FTS_Y_MAX_DISPLAY_DEFAULT;
+ return -ENODATA;
+ } else {
+ pdata->x_min = coords[0];
+ pdata->y_min = coords[1];
+ pdata->x_max = coords[2];
+ pdata->y_max = coords[3];
+ }
+
+ FTS_INFO("display x(%d %d) y(%d %d)", pdata->x_min, pdata->x_max,
+ pdata->y_min, pdata->y_max);
+ return 0;
+}
+
+static int fts_parse_dt(struct device *dev, struct fts_ts_platform_data *pdata)
+{
+ int ret = 0;
+ struct device_node *np = dev->of_node;
+ u32 temp_val = 0;
+
+ FTS_FUNC_ENTER();
+
+ ret = fts_get_dt_coords(dev, "focaltech,display-coords", pdata);
+ if (ret < 0)
+ FTS_ERROR("Unable to get display-coords");
+
+ /* key */
+ pdata->have_key = of_property_read_bool(np, "focaltech,have-key");
+ if (pdata->have_key) {
+ ret = of_property_read_u32(np, "focaltech,key-number", &pdata->key_number);
+ if (ret < 0)
+ FTS_ERROR("Key number undefined!");
+
+ ret = of_property_read_u32_array(np, "focaltech,keys",
+ pdata->keys, pdata->key_number);
+ if (ret < 0)
+ FTS_ERROR("Keys undefined!");
+ else if (pdata->key_number > FTS_MAX_KEYS)
+ pdata->key_number = FTS_MAX_KEYS;
+
+ ret = of_property_read_u32_array(np, "focaltech,key-x-coords",
+ pdata->key_x_coords,
+ pdata->key_number);
+ if (ret < 0)
+ FTS_ERROR("Key Y Coords undefined!");
+
+ ret = of_property_read_u32_array(np, "focaltech,key-y-coords",
+ pdata->key_y_coords,
+ pdata->key_number);
+ if (ret < 0)
+ FTS_ERROR("Key X Coords undefined!");
+
+ FTS_INFO("VK Number:%d, key:(%d,%d,%d), "
+ "coords:(%d,%d),(%d,%d),(%d,%d)",
+ pdata->key_number,
+ pdata->keys[0], pdata->keys[1], pdata->keys[2],
+ pdata->key_x_coords[0], pdata->key_y_coords[0],
+ pdata->key_x_coords[1], pdata->key_y_coords[1],
+ pdata->key_x_coords[2], pdata->key_y_coords[2]);
+ }
+
+ /* reset, irq gpio info */
+ pdata->reset_gpio = of_get_named_gpio_flags(np, "focaltech,reset-gpio",
+ 0, &pdata->reset_gpio_flags);
+ if (pdata->reset_gpio < 0)
+ FTS_ERROR("Unable to get reset_gpio");
+
+ pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio",
+ 0, &pdata->irq_gpio_flags);
+ if (pdata->irq_gpio < 0)
+ FTS_ERROR("Unable to get irq_gpio");
+
+ ret = of_property_read_u32(np, "focaltech,max-touch-number", &temp_val);
+ if (ret < 0) {
+ FTS_ERROR("Unable to get max-touch-number, please check dts");
+ pdata->max_touch_number = FTS_MAX_POINTS_SUPPORT;
+ } else {
+ if (temp_val < 2)
+ pdata->max_touch_number = 2; /* max_touch_number must >= 2 */
+ else if (temp_val > FTS_MAX_POINTS_SUPPORT)
+ pdata->max_touch_number = FTS_MAX_POINTS_SUPPORT;
+ else
+ pdata->max_touch_number = temp_val;
+ }
+
+ FTS_INFO("max touch number:%d, irq gpio:%d, reset gpio:%d",
+ pdata->max_touch_number, pdata->irq_gpio, pdata->reset_gpio);
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+#ifdef CONFIG_DRM
+/*****************************************************************************
+* Name: fts_resume_work
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_resume_work(struct work_struct *work)
+{
+ struct fts_ts_data *ts_data = container_of(work, struct fts_ts_data,
+ resume_work);
+
+ fts_ts_resume(ts_data->dev);
+}
+
+/*****************************************************************************
+* Name: fb_notifier_callback
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct msm_drm_notifier *evdata = data;
+ struct fts_ts_data *fts_data =
+ container_of(self, struct fts_ts_data, fb_notif);
+ int *blank;
+
+ if (!evdata || !evdata->data || (evdata->id != 0))
+ return 0;
+
+ if (!fts_data || !fts_data->client)
+ return 0;
+
+ if (event == MSM_DRM_EVENT_BLANK) {
+ blank = evdata->data;
+
+ if (*blank == MSM_DRM_BLANK_UNBLANK)
+ queue_work(fts_data->ts_workqueue, &fts_data->resume_work);
+ else if (*blank == MSM_DRM_BLANK_POWERDOWN)
+ fts_ts_suspend(&fts_data->client->dev);
+ }
+
+ return 0;
+}
+
#elif defined(CONFIG_HAS_EARLYSUSPEND)
- data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
- FTS_SUSPEND_LEVEL;
- data->early_suspend.suspend = fts_ts_early_suspend;
- data->early_suspend.resume = fts_ts_late_resume;
- register_early_suspend(&data->early_suspend);
-#endif
+/*****************************************************************************
+* Name: fts_ts_early_suspend
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_ts_early_suspend(struct early_suspend *handler)
+{
+ struct fts_ts_data *ts_data = container_of(handler, struct fts_ts_data,
+ early_suspend);
- FTS_FUNC_EXIT();
- return 0;
-
-free_gpio:
- if (gpio_is_valid(pdata->reset_gpio))
- gpio_free(pdata->reset_gpio);
- if (gpio_is_valid(pdata->irq_gpio))
- gpio_free(pdata->irq_gpio);
- return err;
-
+ fts_ts_suspend(ts_data->dev);
}
/*****************************************************************************
- * Name: fts_ts_remove
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_ts_remove(struct i2c_client *client)
+* Name: fts_ts_late_resume
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_ts_late_resume(struct early_suspend *handler)
{
- struct fts_ts_data *data = i2c_get_clientdata(client);
+ struct fts_ts_data *ts_data = container_of(handler, struct fts_ts_data,
+ early_suspend);
- FTS_FUNC_ENTER();
- cancel_work_sync(&data->touch_event_work);
-
-#if FTS_PSENSOR_EN
- fts_sensor_remove(data);
-#endif
-
-#if FTS_POINT_REPORT_CHECK_EN
- fts_point_report_check_exit();
-#endif
-
-#if FTS_APK_NODE_EN
- fts_release_apk_debug_channel();
-#endif
-
-#if FTS_SYSFS_NODE_EN
- fts_remove_sysfs(client);
-#endif
-
- fts_ex_mode_exit(client);
-
-#if FTS_AUTO_UPGRADE_EN
- cancel_work_sync(&fw_update_work);
-#endif
-
-#if defined(CONFIG_FB)
- if (fb_unregister_client(&data->fb_notif))
- FTS_ERROR("Error occurred while unregistering fb_notifier.");
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
- unregister_early_suspend(&data->early_suspend);
-#endif
- free_irq(client->irq, data);
-
- if (gpio_is_valid(data->pdata->reset_gpio))
- gpio_free(data->pdata->reset_gpio);
-
- if (gpio_is_valid(data->pdata->irq_gpio))
- gpio_free(data->pdata->irq_gpio);
-
- input_unregister_device(data->input_dev);
-
-#if FTS_TEST_EN
- fts_test_exit(client);
-#endif
-
-#if FTS_ESDCHECK_EN
- fts_esdcheck_exit();
-#endif
-
- FTS_FUNC_EXIT();
- return 0;
+ fts_ts_resume(ts_data->dev);
}
+#endif
/*****************************************************************************
- * Name: fts_ts_suspend
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_ts_suspend(struct device *dev)
+* Name: fts_ts_probe
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_probe_entry(struct fts_ts_data *ts_data)
{
- struct fts_ts_data *data = dev_get_drvdata(dev);
- int retval = 0;
+ int ret = 0;
+ int pdata_size = sizeof(struct fts_ts_platform_data);
- FTS_FUNC_ENTER();
- if (data->suspended) {
- FTS_INFO("Already in suspend state");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
+ FTS_FUNC_ENTER();
+ FTS_INFO("%s", FTS_DRIVER_VERSION);
+ ts_data->pdata = kzalloc(pdata_size, GFP_KERNEL);
+ if (!ts_data->pdata) {
+ FTS_ERROR("allocate memory for platform_data fail");
+ return -ENOMEM;
+ }
-#if FTS_ESDCHECK_EN
- fts_esdcheck_suspend();
+ if (ts_data->dev->of_node) {
+ ret = fts_parse_dt(ts_data->dev, ts_data->pdata);
+ if (ret)
+ FTS_ERROR("device-tree parse fail");
+ } else {
+ if (ts_data->dev->platform_data) {
+ memcpy(ts_data->pdata, ts_data->dev->platform_data, pdata_size);
+ } else {
+ FTS_ERROR("platform_data is null");
+ return -ENODEV;
+ }
+ }
+
+ ts_data->ts_workqueue = create_singlethread_workqueue("fts_wq");
+ if (!ts_data->ts_workqueue) {
+ FTS_ERROR("create fts workqueue fail");
+ }
+
+ spin_lock_init(&ts_data->irq_lock);
+ mutex_init(&ts_data->report_mutex);
+ mutex_init(&ts_data->bus_lock);
+
+ /* Init communication interface */
+ ret = fts_bus_init(ts_data);
+ if (ret) {
+ FTS_ERROR("bus initialize fail");
+ goto err_bus_init;
+ }
+
+ ret = fts_input_init(ts_data);
+ if (ret) {
+ FTS_ERROR("input initialize fail");
+ goto err_input_init;
+ }
+
+ ret = fts_report_buffer_init(ts_data);
+ if (ret) {
+ FTS_ERROR("report buffer init fail");
+ goto err_report_buffer;
+ }
+
+ ret = fts_gpio_configure(ts_data);
+ if (ret) {
+ FTS_ERROR("configure the gpios fail");
+ goto err_gpio_config;
+ }
+
+#if FTS_POWER_SOURCE_CUST_EN
+ ret = fts_power_source_init(ts_data);
+ if (ret) {
+ FTS_ERROR("fail to get power(regulator)");
+ goto err_power_init;
+ }
#endif
-#if FTS_GESTURE_EN
- if (data->pdata->wakeup_gestures_en) {
- retval = fts_gesture_suspend(data->client);
- if (retval == 0) {
- /* Enter into gesture mode(suspend) */
- retval = enable_irq_wake(fts_wq_data->client->irq);
- if (retval)
- FTS_ERROR("%s: set_irq_wake failed", __func__);
- data->suspended = true;
- FTS_FUNC_EXIT();
- return 0;
- }
- }
-#endif
-
-#if FTS_PSENSOR_EN
- if (fts_sensor_suspend(data) != 0) {
- enable_irq_wake(data->client->irq);
- data->suspended = true;
- return 0;
- }
-#endif
-
- fts_irq_disable();
-
- /* TP enter sleep mode */
- retval = fts_i2c_write_reg(data->client, FTS_REG_POWER_MODE,
- FTS_REG_POWER_MODE_SLEEP_VALUE);
- if (retval < 0)
- FTS_ERROR("Set TP to sleep mode fail, ret=%d!", retval);
-
- data->suspended = true;
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/*****************************************************************************
- * Name: fts_ts_resume
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_ts_resume(struct device *dev)
-{
- struct fts_ts_data *data = dev_get_drvdata(dev);
-
- FTS_FUNC_ENTER();
- if (!data->suspended) {
- FTS_DEBUG("Already in awake state");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
-
- fts_release_all_finger();
-
#if (!FTS_CHIP_IDC)
- fts_reset_proc(200);
+ fts_reset_proc(200);
#endif
- fts_tp_state_recovery(data->client);
+ ret = fts_get_ic_information(ts_data);
+ if (ret) {
+ FTS_ERROR("not focal IC, unregister driver");
+ goto err_irq_req;
+ }
+
+ ret = fts_create_apk_debug_channel(ts_data);
+ if (ret) {
+ FTS_ERROR("create apk debug node fail");
+ }
+
+ ret = fts_create_sysfs(ts_data);
+ if (ret) {
+ FTS_ERROR("create sysfs node fail");
+ }
+
+#if FTS_POINT_REPORT_CHECK_EN
+ ret = fts_point_report_check_init(ts_data);
+ if (ret) {
+ FTS_ERROR("init point report check fail");
+ }
+#endif
+
+ ret = fts_ex_mode_init(ts_data);
+ if (ret) {
+ FTS_ERROR("init glove/cover/charger fail");
+ }
+
+ ret = fts_gesture_init(ts_data);
+ if (ret) {
+ FTS_ERROR("init gesture fail");
+ }
+
#if FTS_ESDCHECK_EN
- fts_esdcheck_resume();
+ ret = fts_esdcheck_init(ts_data);
+ if (ret) {
+ FTS_ERROR("init esd check fail");
+ }
#endif
-#if FTS_GESTURE_EN
- if (data->pdata->wakeup_gestures_en) {
- if (fts_gesture_resume(data->client) == 0) {
- int err;
+ ret = fts_irq_registration(ts_data);
+ if (ret) {
+ FTS_ERROR("request irq failed");
+ goto err_irq_req;
+ }
- err = disable_irq_wake(data->client->irq);
- if (err)
- FTS_ERROR("%s: disable_irq_wake failed",
- __func__);
- data->suspended = false;
- FTS_FUNC_EXIT();
- return 0;
- }
- }
+ ret = fts_fwupg_init(ts_data);
+ if (ret) {
+ FTS_ERROR("init fw upgrade fail");
+ }
+
+#ifdef CONFIG_DRM
+ if (ts_data->ts_workqueue) {
+ INIT_WORK(&ts_data->resume_work, fts_resume_work);
+ }
+ ts_data->fb_notif.notifier_call = fb_notifier_callback;
+ ret = msm_drm_register_client(&ts_data->fb_notif);
+ if (ret) {
+ FTS_ERROR("[FB]Unable to register fb_notifier: %d", ret);
+ }
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ ts_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + FTS_SUSPEND_LEVEL;
+ ts_data->early_suspend.suspend = fts_ts_early_suspend;
+ ts_data->early_suspend.resume = fts_ts_late_resume;
+ register_early_suspend(&ts_data->early_suspend);
#endif
-#if FTS_PSENSOR_EN
- if (fts_sensor_resume(data) != 0) {
- disable_irq_wake(data->client->irq);
- data->suspended = false;
- FTS_FUNC_EXIT();
- return 0;
- }
+ FTS_FUNC_EXIT();
+ return 0;
+
+err_irq_req:
+#if FTS_POWER_SOURCE_CUST_EN
+err_power_init:
+ fts_power_source_exit(ts_data);
#endif
+ if (gpio_is_valid(ts_data->pdata->reset_gpio))
+ gpio_free(ts_data->pdata->reset_gpio);
+ if (gpio_is_valid(ts_data->pdata->irq_gpio))
+ gpio_free(ts_data->pdata->irq_gpio);
+err_gpio_config:
+ kfree_safe(ts_data->point_buf);
+ kfree_safe(ts_data->events);
+err_report_buffer:
+ input_unregister_device(ts_data->input_dev);
+err_input_init:
+ if (ts_data->ts_workqueue)
+ destroy_workqueue(ts_data->ts_workqueue);
+err_bus_init:
+ kfree_safe(ts_data->bus_tx_buf);
+ kfree_safe(ts_data->bus_rx_buf);
+ kfree_safe(ts_data->pdata);
- data->suspended = false;
-
- fts_irq_enable();
-
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_EXIT();
+ return ret;
}
/*****************************************************************************
- * I2C Driver
- *****************************************************************************/
-static const struct i2c_device_id fts_ts_id[] = {
- {FTS_DRIVER_NAME, 0},
- {},
-};
-MODULE_DEVICE_TABLE(i2c, fts_ts_id);
+* Name: fts_ts_remove
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_remove_entry(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
-static const struct of_device_id fts_match_table[] = {
- { .compatible = "focaltech,fts", },
- { },
+#if FTS_POINT_REPORT_CHECK_EN
+ fts_point_report_check_exit(ts_data);
+#endif
+
+ fts_release_apk_debug_channel(ts_data);
+ fts_remove_sysfs(ts_data);
+ fts_ex_mode_exit(ts_data);
+
+ fts_fwupg_exit(ts_data);
+
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_exit(ts_data);
+#endif
+
+ fts_gesture_exit(ts_data);
+ fts_bus_exit(ts_data);
+
+ free_irq(ts_data->irq, ts_data);
+ input_unregister_device(ts_data->input_dev);
+
+ if (ts_data->ts_workqueue)
+ destroy_workqueue(ts_data->ts_workqueue);
+
+#ifdef CONFIG_DRM
+ if (msm_drm_unregister_client(&ts_data->fb_notif))
+ FTS_ERROR("Error occurred while unregistering fb_notifier.");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ unregister_early_suspend(&ts_data->early_suspend);
+#endif
+
+ if (gpio_is_valid(ts_data->pdata->reset_gpio))
+ gpio_free(ts_data->pdata->reset_gpio);
+
+ if (gpio_is_valid(ts_data->pdata->irq_gpio))
+ gpio_free(ts_data->pdata->irq_gpio);
+
+#if FTS_POWER_SOURCE_CUST_EN
+ fts_power_source_exit(ts_data);
+#endif
+
+ kfree_safe(ts_data->point_buf);
+ kfree_safe(ts_data->events);
+
+ kfree_safe(ts_data->pdata);
+ kfree_safe(ts_data);
+
+ FTS_FUNC_EXIT();
+
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_ts_suspend
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_suspend(struct device *dev)
+{
+ int ret = 0;
+ struct fts_ts_data *ts_data = fts_data;
+
+ FTS_FUNC_ENTER();
+ if (ts_data->suspended) {
+ FTS_INFO("Already in suspend state");
+ return 0;
+ }
+
+ if (ts_data->fw_loading) {
+ FTS_INFO("fw upgrade in process, can't suspend");
+ return 0;
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_suspend();
+#endif
+
+ if (ts_data->gesture_mode) {
+ fts_gesture_suspend(ts_data);
+ } else {
+ fts_irq_disable();
+
+ FTS_INFO("make TP enter into sleep mode");
+ ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_SLEEP);
+ if (ret < 0)
+ FTS_ERROR("set TP to sleep mode fail, ret=%d", ret);
+
+ if (!ts_data->ic_info.is_incell) {
+#if FTS_POWER_SOURCE_CUST_EN
+ ret = fts_power_source_suspend(ts_data);
+ if (ret < 0) {
+ FTS_ERROR("power enter suspend fail");
+ }
+#endif
+ }
+ }
+
+ fts_release_all_finger();
+ ts_data->suspended = true;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_ts_resume
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static int fts_ts_resume(struct device *dev)
+{
+ struct fts_ts_data *ts_data = fts_data;
+
+ FTS_FUNC_ENTER();
+ if (!ts_data->suspended) {
+ FTS_DEBUG("Already in awake state");
+ return 0;
+ }
+
+ fts_release_all_finger();
+
+ if (!ts_data->ic_info.is_incell) {
+#if FTS_POWER_SOURCE_CUST_EN
+ fts_power_source_resume(ts_data);
+#endif
+ fts_reset_proc(200);
+ }
+
+ fts_wait_tp_to_valid();
+ fts_ex_mode_recovery(ts_data);
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_resume();
+#endif
+
+ if (ts_data->gesture_mode) {
+ fts_gesture_resume(ts_data);
+ } else {
+ fts_irq_enable();
+ }
+
+ ts_data->suspended = false;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* TP Driver
+*****************************************************************************/
+
+static int fts_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct fts_ts_data *ts_data = NULL;
+
+ FTS_INFO("Touch Screen(I2C BUS) driver prboe...");
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ FTS_ERROR("I2C not supported");
+ return -ENODEV;
+ }
+
+ /* malloc memory for global struct variable */
+ ts_data = (struct fts_ts_data *)kzalloc(sizeof(*ts_data), GFP_KERNEL);
+ if (!ts_data) {
+ FTS_ERROR("allocate memory for fts_data fail");
+ return -ENOMEM;
+ }
+
+ fts_data = ts_data;
+ ts_data->client = client;
+ ts_data->dev = &client->dev;
+ ts_data->log_level = 1;
+ ts_data->fw_is_running = 0;
+ i2c_set_clientdata(client, ts_data);
+
+ ret = fts_ts_probe_entry(ts_data);
+ if (ret) {
+ FTS_ERROR("Touch Screen(I2C BUS) driver probe fail");
+ kfree_safe(ts_data);
+ return ret;
+ }
+
+ FTS_INFO("Touch Screen(I2C BUS) driver prboe successfully");
+ return 0;
+}
+
+static int fts_ts_remove(struct i2c_client *client)
+{
+ return fts_ts_remove_entry(i2c_get_clientdata(client));
+}
+
+static const struct i2c_device_id fts_ts_id[] = {
+ {FTS_DRIVER_NAME, 0},
+ {},
};
+static const struct of_device_id fts_dt_match[] = {
+ {.compatible = "focaltech,fts", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, fts_dt_match);
static struct i2c_driver fts_ts_driver = {
- .probe = fts_ts_probe,
- .remove = fts_ts_remove,
- .driver = {
- .name = FTS_DRIVER_NAME,
- .owner = THIS_MODULE,
- .of_match_table = fts_match_table,
- },
- .id_table = fts_ts_id,
+ .probe = fts_ts_probe,
+ .remove = fts_ts_remove,
+ .driver = {
+ .name = FTS_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(fts_dt_match),
+ },
+ .id_table = fts_ts_id,
};
/*****************************************************************************
- * Name: fts_ts_init
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
+* Name: fts_ts_init
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
static int __init fts_ts_init(void)
{
- int ret = 0;
+ int ret = 0;
- FTS_FUNC_ENTER();
- ret = i2c_add_driver(&fts_ts_driver);
- if (ret != 0)
- FTS_ERROR("Focaltech touch screen driver init failed!");
-
- FTS_FUNC_EXIT();
- return ret;
+ FTS_FUNC_ENTER();
+ ret = i2c_add_driver(&fts_ts_driver);
+ if ( ret != 0 ) {
+ FTS_ERROR("Focaltech touch screen driver init failed!");
+ }
+ FTS_FUNC_EXIT();
+ return ret;
}
/*****************************************************************************
- * Name: fts_ts_exit
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
+* Name: fts_ts_exit
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
static void __exit fts_ts_exit(void)
{
- i2c_del_driver(&fts_ts_driver);
+ i2c_del_driver(&fts_ts_driver);
}
module_init(fts_ts_init);
module_exit(fts_ts_exit);
+MODULE_AUTHOR("FocalTech Driver Team");
MODULE_DESCRIPTION("FocalTech Touchscreen Driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
index a3c64f9..669561a 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -15,73 +15,67 @@
*
*/
/*****************************************************************************
- *
- * File Name: focaltech_core.h
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-08
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_core.h
+
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
#ifndef __LINUX_FOCALTECH_CORE_H__
#define __LINUX_FOCALTECH_CORE_H__
/*****************************************************************************
- * Included header files
- *****************************************************************************/
+* Included header files
+*****************************************************************************/
+#include <linux/kernel.h>
+#include <linux/device.h>
#include <linux/i2c.h>
+#include <linux/spi/spi.h>
#include <linux/input.h>
#include <linux/input/mt.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <linux/gpio.h>
-#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
+#include <asm/uaccess.h>
#include <linux/firmware.h>
#include <linux/debugfs.h>
#include <linux/mutex.h>
+#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/time.h>
-#include <linux/workqueue.h>
+#include <linux/jiffies.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
-#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kthread.h>
-#include <linux/init.h>
-#include <linux/cdev.h>
-#include <linux/device.h>
-#include <linux/mount.h>
-#include <linux/netdevice.h>
-#include <linux/unistd.h>
-#include <linux/ioctl.h>
+#include <linux/dma-mapping.h>
#include "focaltech_common.h"
-#include "focaltech_flash.h"
-#if FTS_PSENSOR_EN
-#include <linux/sensors.h>
-#endif
+
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-#define LEN_FLASH_ECC_MAX 0xFFFE
-
-#define FTS_WORKQUEUE_NAME "fts_wq"
-
-#define FTS_MAX_POINTS 10
-#define FTS_KEY_WIDTH 50
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_MAX_POINTS_SUPPORT 10 /* constant value, can't be changed */
+#define FTS_MAX_KEYS 4
+#define FTS_KEY_DIM 10
#define FTS_ONE_TCH_LEN 6
-#define POINT_READ_BUF (3 + FTS_ONE_TCH_LEN * FTS_MAX_POINTS)
+#define FTS_TOUCH_DATA_LEN (FTS_MAX_POINTS_SUPPORT * FTS_ONE_TCH_LEN + 3)
-#define FTS_MAX_ID 0x0F
+#define FTS_GESTURE_POINTS_MAX 6
+#define FTS_GESTURE_DATA_LEN (FTS_GESTURE_POINTS_MAX * 4 + 4)
+
+#define FTS_MAX_ID 0x0A
#define FTS_TOUCH_X_H_POS 3
#define FTS_TOUCH_X_L_POS 4
#define FTS_TOUCH_Y_H_POS 5
@@ -92,104 +86,175 @@
#define FTS_TOUCH_EVENT_POS 3
#define FTS_TOUCH_ID_POS 5
#define FTS_COORDS_ARR_SIZE 4
+#define FTS_X_MIN_DISPLAY_DEFAULT 0
+#define FTS_Y_MIN_DISPLAY_DEFAULT 0
+#define FTS_X_MAX_DISPLAY_DEFAULT 720
+#define FTS_Y_MAX_DISPLAY_DEFAULT 1280
-#define FTS_TOUCH_DOWN 0
-#define FTS_TOUCH_UP 1
-#define FTS_TOUCH_CONTACT 2
+#define FTS_TOUCH_DOWN 0
+#define FTS_TOUCH_UP 1
+#define FTS_TOUCH_CONTACT 2
+#define EVENT_DOWN(flag) ((FTS_TOUCH_DOWN == flag) || (FTS_TOUCH_CONTACT == flag))
+#define EVENT_UP(flag) (FTS_TOUCH_UP == flag)
+#define EVENT_NO_DOWN(data) (!data->point_num)
-#define FTS_SYSFS_ECHO_ON(buf) ((strncasecmp(buf, "1", 1) == 0) || \
- (strncasecmp(buf, "on", 2) == 0))
-#define FTS_SYSFS_ECHO_OFF(buf) ((strncasecmp(buf, "0", 1) == 0) || \
- (strncasecmp(buf, "off", 3) == 0))
+#define FTX_MAX_COMPATIBLE_TYPE 4
+#define FTX_MAX_COMMMAND_LENGTH 16
+
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
-
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+struct ftxxxx_proc {
+ struct proc_dir_entry *proc_entry;
+ u8 opmode;
+ u8 cmd_len;
+ u8 cmd[FTX_MAX_COMMMAND_LENGTH];
+};
struct fts_ts_platform_data {
- int irq_gpio;
- u32 irq_gpio_flags;
- int reset_gpio;
- u32 reset_gpio_flags;
- bool have_key;
- u32 key_number;
- u32 keys[4];
- u32 key_y_coord;
- u32 key_x_coords[4];
- u32 x_max;
- u32 y_max;
- u32 x_min;
- u32 y_min;
- u32 max_touch_number;
- bool wakeup_gestures_en;
+ u32 irq_gpio;
+ u32 irq_gpio_flags;
+ u32 reset_gpio;
+ u32 reset_gpio_flags;
+ bool have_key;
+ u32 key_number;
+ u32 keys[FTS_MAX_KEYS];
+ u32 key_y_coords[FTS_MAX_KEYS];
+ u32 key_x_coords[FTS_MAX_KEYS];
+ u32 x_max;
+ u32 y_max;
+ u32 x_min;
+ u32 y_min;
+ u32 max_touch_number;
};
struct ts_event {
- u16 au16_x[FTS_MAX_POINTS]; /*x coordinate */
- u16 au16_y[FTS_MAX_POINTS]; /*y coordinate */
- u16 pressure[FTS_MAX_POINTS];
- u8 au8_touch_event[FTS_MAX_POINTS]; /* touch event:
- * 0 -- down;
- * 1 -- up;
- * 2 -- contact
- */
- u8 au8_finger_id[FTS_MAX_POINTS]; /* touch ID */
- u8 area[FTS_MAX_POINTS];
- u8 touch_point;
- u8 point_num;
+ int x; /*x coordinate */
+ int y; /*y coordinate */
+ int p; /* pressure */
+ int flag; /* touch event flag: 0 -- down; 1-- up; 2 -- contact */
+ int id; /*touch ID */
+ int area;
};
struct fts_ts_data {
- struct i2c_client *client;
- struct input_dev *input_dev;
- struct ts_event event;
- const struct fts_ts_platform_data *pdata;
-#if FTS_PSENSOR_EN
- struct fts_psensor_platform_data *psensor_pdata;
+ struct i2c_client *client;
+ struct spi_device *spi;
+ struct device *dev;
+ struct input_dev *input_dev;
+ struct fts_ts_platform_data *pdata;
+ struct ts_ic_info ic_info;
+ struct workqueue_struct *ts_workqueue;
+ struct work_struct fwupg_work;
+ struct delayed_work esdcheck_work;
+ struct delayed_work prc_work;
+ struct work_struct resume_work;
+ struct ftxxxx_proc proc;
+ spinlock_t irq_lock;
+ struct mutex report_mutex;
+ struct mutex bus_lock;
+ int irq;
+ int log_level;
+ int fw_is_running; /* confirm fw is running when using spi:default 0 */
+ int dummy_byte;
+ bool suspended;
+ bool fw_loading;
+ bool irq_disabled;
+ bool power_disabled;
+ bool glove_mode;
+ bool cover_mode;
+ bool charger_mode;
+ bool gesture_mode; /* gesture enable or disable, default: disable */
+ /* multi-touch */
+ struct ts_event *events;
+ u8 *bus_tx_buf;
+ u8 *bus_rx_buf;
+ u8 *point_buf;
+ int pnt_buf_size;
+ int touchs;
+ int key_state;
+ int touch_point;
+ int point_num;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+#if FTS_PINCTRL_EN
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_active;
+ struct pinctrl_state *pins_suspend;
+ struct pinctrl_state *pins_release;
#endif
- struct work_struct touch_event_work;
- struct workqueue_struct *ts_workqueue;
- struct regulator *vdd;
- struct regulator *vcc_i2c;
- spinlock_t irq_lock;
- struct mutex report_mutex;
- u16 addr;
- bool suspended;
- u8 fw_ver[3];
- u8 fw_vendor_id;
- int touchs;
- int irq_disable;
-
#if defined(CONFIG_FB)
- struct notifier_block fb_notif;
+ struct notifier_block fb_notif;
#elif defined(CONFIG_HAS_EARLYSUSPEND)
- struct early_suspend early_suspend;
+ struct early_suspend early_suspend;
#endif
};
-
-#if FTS_PSENSOR_EN
-struct fts_psensor_platform_data {
- struct input_dev *input_psensor_dev;
- struct sensors_classdev ps_cdev;
- int tp_psensor_opened;
- char tp_psensor_data; /* 0 near, 1 far */
- struct fts_ts_data *data;
-};
-
-int fts_sensor_init(struct fts_ts_data *data);
-int fts_sensor_read_data(struct fts_ts_data *data);
-int fts_sensor_suspend(struct fts_ts_data *data);
-int fts_sensor_resume(struct fts_ts_data *data);
-int fts_sensor_remove(struct fts_ts_data *data);
-#endif
-
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-extern struct i2c_client *fts_i2c_client;
-extern struct fts_ts_data *fts_wq_data;
-extern struct input_dev *fts_input_dev;
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+extern struct fts_ts_data *fts_data;
+/* communication interface */
+int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen);
+int fts_read_reg(u8 addr, u8 *value);
+int fts_write(u8 *writebuf, u32 writelen);
+int fts_write_reg(u8 addr, u8 value);
+void fts_hid2std(void);
+int fts_bus_init(struct fts_ts_data *ts_data);
+int fts_bus_exit(struct fts_ts_data *ts_data);
+
+/* Gesture functions */
+int fts_gesture_init(struct fts_ts_data *ts_data);
+int fts_gesture_exit(struct fts_ts_data *ts_data);
+void fts_gesture_recovery(struct fts_ts_data *ts_data);
+int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data);
+int fts_gesture_suspend(struct fts_ts_data *ts_data);
+int fts_gesture_resume(struct fts_ts_data *ts_data);
+
+/* Apk and functions */
+int fts_create_apk_debug_channel(struct fts_ts_data *);
+void fts_release_apk_debug_channel(struct fts_ts_data *);
+
+/* ADB functions */
+int fts_create_sysfs(struct fts_ts_data *ts_data);
+int fts_remove_sysfs(struct fts_ts_data *ts_data);
+
+/* ESD */
+#if FTS_ESDCHECK_EN
+int fts_esdcheck_init(struct fts_ts_data *ts_data);
+int fts_esdcheck_exit(struct fts_ts_data *ts_data);
+int fts_esdcheck_switch(bool enable);
+int fts_esdcheck_proc_busy(bool proc_debug);
+int fts_esdcheck_set_intr(bool intr);
+int fts_esdcheck_suspend(void);
+int fts_esdcheck_resume(void);
+#endif
+
+
+/* Point Report Check*/
+#if FTS_POINT_REPORT_CHECK_EN
+int fts_point_report_check_init(struct fts_ts_data *ts_data);
+int fts_point_report_check_exit(struct fts_ts_data *ts_data);
+void fts_prc_queue_work(struct fts_ts_data *ts_data);
+#endif
+
+/* FW upgrade */
+int fts_fwupg_init(struct fts_ts_data *ts_data);
+int fts_fwupg_exit(struct fts_ts_data *ts_data);
+int fts_upgrade_bin(char *fw_name, bool force);
+int fts_enter_test_environment(bool test_state);
+
+/* Other */
+int fts_reset_proc(int hdelayms);
+int fts_wait_tp_to_valid(void);
+void fts_release_all_finger(void);
+void fts_tp_state_recovery(struct fts_ts_data *ts_data);
+int fts_ex_mode_init(struct fts_ts_data *ts_data);
+int fts_ex_mode_exit(struct fts_ts_data *ts_data);
+int fts_ex_mode_recovery(struct fts_ts_data *ts_data);
+
+void fts_irq_disable(void);
+void fts_irq_enable(void);
#endif /* __LINUX_FOCALTECH_CORE_H__ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c b/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
index 0b2fc53..b34bb26 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,463 +16,449 @@
*/
/*****************************************************************************
- *
- * File Name: focaltech_esdcheck.c
- *
- * Author: luoguojin
- *
- * Created: 2016-08-03
- *
- * Abstract: ESD check function
- *
- * Version: v1.0
- *
- * Revision History:
- * v1.0:
- * First release. By luougojin 2016-08-03
- * v1.1: By luougojin 2017-02-15
- * 1. Add LCD_ESD_PATCH to control idc_esdcheck_lcderror
- *****************************************************************************/
+*
+* File Name: focaltech_esdcheck.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-03
+*
+* Abstract: ESD check function
+*
+* Version: v1.0
+*
+* Revision History:
+* v1.0:
+* First release. By luougojin 2016-08-03
+* v1.1: By luougojin 2017-02-15
+* 1. Add LCD_ESD_PATCH to control idc_esdcheck_lcderror
+*****************************************************************************/
/*****************************************************************************
- * Included header files
- *****************************************************************************/
+* Included header files
+*****************************************************************************/
#include "focaltech_core.h"
#if FTS_ESDCHECK_EN
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
+* Private constant and macro definitions using #define
+*****************************************************************************/
#define ESDCHECK_WAIT_TIME 1000 /* ms */
#define LCD_ESD_PATCH 0
+#define ESDCHECK_INTRCNT_MAX 2
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
struct fts_esdcheck_st {
- u8 active : 1; /* 1- esd check active, need check esd
- * 0- no esd check
- */
- u8 suspend : 1;
- u8 proc_debug : 1; /* apk or adb is accessing I2C */
- u8 intr : 1; /* 1- Interrupt trigger */
- u8 unused : 4;
- u8 flow_work_hold_cnt; /* Flow Work Cnt(reg0x91)
- * keep a same value for x times.
- * >=5 times is ESD, need reset
- */
- u8 flow_work_cnt_last; /* Save Flow Work Cnt(reg0x91) value */
- u32 hardware_reset_cnt;
- u32 i2c_nack_cnt;
- u32 i2c_dataerror_cnt;
+ u8 mode : 1; /* 1- need check esd 0- no esd check */
+ u8 suspend : 1;
+ u8 proc_debug : 1; /* apk or adb use */
+ u8 intr : 1; /* 1- Interrupt trigger */
+ u8 unused : 4;
+ u8 intr_cnt;
+ u8 flow_work_hold_cnt; /* Flow Work Cnt(reg0x91) keep a same value for x times. >=5 times is ESD, need reset */
+ u8 flow_work_cnt_last; /* Save Flow Work Cnt(reg0x91) value */
+ u32 hardware_reset_cnt;
+ u32 nack_cnt;
+ u32 dataerror_cnt;
};
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-static struct delayed_work fts_esdcheck_work;
-static struct workqueue_struct *fts_esdcheck_workqueue;
+* Static variables
+*****************************************************************************/
static struct fts_esdcheck_st fts_esdcheck_data;
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
+* Global variable or extern global variabls/functions
+*****************************************************************************/
/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
+* Static function prototypes
+*****************************************************************************/
/*****************************************************************************
- * functions body
- *****************************************************************************/
+* functions body
+*****************************************************************************/
#if LCD_ESD_PATCH
-/*****************************************************************************
- * Name: lcd_esdcheck
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
int lcd_need_reset;
static int tp_need_recovery; /* LCD reset cause Tp reset */
-int idc_esdcheck_lcderror(void)
+int idc_esdcheck_lcderror(struct fts_ts_data *ts_data)
{
- u8 val;
- int ret;
+ int ret = 0;
+ u8 val = 0;
- FTS_DEBUG("[ESD]Check LCD ESD");
- if ((tp_need_recovery == 1) && (lcd_need_reset == 0)) {
- tp_need_recovery = 0;
- /* LCD reset, need recover TP state */
- fts_tp_state_recovery(fts_i2c_client);
- }
+ FTS_DEBUG("check LCD ESD");
+ if ( (tp_need_recovery == 1) && (lcd_need_reset == 0) ) {
+ tp_need_recovery = 0;
+ /* LCD reset, need recover TP state */
+ fts_release_all_finger();
+ fts_tp_state_recovery(ts_data);
+ }
- ret = fts_i2c_read_reg(fts_i2c_client, FTS_REG_ESD_SATURATE, &val);
- if (ret < 0) {
- FTS_ERROR("[ESD]: Read ESD_SATURATE(0xED) failed ret=%d", ret);
- return -EIO;
- }
+ ret = fts_read_reg(FTS_REG_ESD_SATURATE, &val);
+ if ( ret < 0) {
+ FTS_ERROR("read reg0xED fail,ret:%d", ret);
+ return -EIO;
+ }
- if (val == 0xAA) {
- /*
- * 1. Set flag lcd_need_reset = 1;
- * 2. LCD driver need reset(recovery) LCD and
- * set lcd_need_reset to 0
- * 3. recover TP state
- */
- FTS_INFO("LCD ESD, Execute LCD reset!");
- lcd_need_reset = 1;
- tp_need_recovery = 1;
- }
+ if (val == 0xAA) {
+ /*
+ * 1. Set flag lcd_need_reset = 1;
+ * 2. LCD driver need reset(recovery) LCD and set lcd_need_reset to 0
+ * 3. recover TP state
+ */
+ FTS_INFO("LCD ESD, need execute LCD reset");
+ lcd_need_reset = 1;
+ tp_need_recovery = 1;
+ }
- return 0;
+ return 0;
}
#endif
-/*****************************************************************************
- * Name: fts_esdcheck_tp_reset
- * Brief: esd check algorithm
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_esdcheck_tp_reset(void)
+static int fts_esdcheck_tp_reset(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
+ FTS_FUNC_ENTER();
- fts_esdcheck_data.flow_work_hold_cnt = 0;
- fts_esdcheck_data.hardware_reset_cnt++;
+ fts_esdcheck_data.flow_work_hold_cnt = 0;
+ fts_esdcheck_data.hardware_reset_cnt++;
- fts_reset_proc(200);
- fts_tp_state_recovery(fts_i2c_client);
+ fts_reset_proc(200);
+ fts_release_all_finger();
+ fts_tp_state_recovery(ts_data);
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+static bool get_chip_id(struct fts_ts_data *ts_data)
+{
+ int ret = 0;
+ int i = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
+ u8 chip_id = ts_data->ic_info.ids.chip_idh;
+
+ for (i = 0; i < 3; i++) {
+ reg_addr = FTS_REG_CHIP_ID;
+ ret = fts_read(®_addr, 1, ®_value, 1);
+ if (ret < 0) {
+ FTS_ERROR("read chip id fail,ret:%d", ret);
+ fts_esdcheck_data.nack_cnt++;
+ } else {
+ if (reg_value == chip_id) {
+ break;
+ } else {
+ FTS_DEBUG("read chip_id:%x,retry:%d", reg_value, i);
+ fts_esdcheck_data.dataerror_cnt++;
+ }
+ }
+ msleep(10);
+ }
+
+ /* if can't get correct data in 3 times, then need hardware reset */
+ if (i >= 3) {
+ FTS_ERROR("read chip id 3 times fail, need execute TP reset");
+ return true;
+ }
+
+ return false;
}
/*****************************************************************************
- * Name: get_chip_id
- * Brief: Read Chip Id 3 times
- * Input:
- * Output:
- * Return: 1 - Read Chip Id 3 times failed
- * 0 - Read Chip Id pass
- *****************************************************************************/
-static bool get_chip_id(void)
+* Name: get_flow_cnt
+* Brief: Read flow cnt(0x91)
+* Input:
+* Output:
+* Return: 1(true) - Reg 0x91(flow cnt) abnormal: hold a value for 5 times
+* 0(false) - Reg 0x91(flow cnt) normal
+*****************************************************************************/
+static bool get_flow_cnt(struct fts_ts_data *ts_data)
{
- int err = 0;
- int i = 0;
- u8 reg_value = 0;
- u8 reg_addr = 0;
+ int ret = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
- for (i = 0; i < 3; i++) {
- reg_addr = FTS_REG_CHIP_ID;
- err = fts_i2c_read(fts_i2c_client, ®_addr, 1,
- ®_value, 1);
+ reg_addr = FTS_REG_FLOW_WORK_CNT;
+ ret = fts_read(®_addr, 1, ®_value, 1);
+ if (ret < 0) {
+ FTS_ERROR("read reg0x91 fail,ret:%d", ret);
+ fts_esdcheck_data.nack_cnt++;
+ } else {
+ if ( reg_value == fts_esdcheck_data.flow_work_cnt_last ) {
+ FTS_DEBUG("reg0x91,val:%x,last:%x", reg_value,
+ fts_esdcheck_data.flow_work_cnt_last);
+ fts_esdcheck_data.flow_work_hold_cnt++;
+ } else {
+ fts_esdcheck_data.flow_work_hold_cnt = 0;
+ }
- if (err < 0) {
- FTS_ERROR("[ESD]: Read Reg 0xA3 failed ret = %d!!",
- err);
- fts_esdcheck_data.i2c_nack_cnt++;
- } else {
- /* Upgrade sometimes can't detect */
- if ((reg_value == chip_types.chip_idh)
- || (reg_value == 0xEF))
- break;
+ fts_esdcheck_data.flow_work_cnt_last = reg_value;
+ }
- fts_esdcheck_data.i2c_dataerror_cnt++;
- }
- }
+ /* Flow Work Cnt keep a value for 5 times, need execute TP reset */
+ if (fts_esdcheck_data.flow_work_hold_cnt >= 5) {
+ FTS_DEBUG("reg0x91 keep a value for 5 times, need execute TP reset");
+ return true;
+ }
- /* if can't get correct data in 3 times, then need hardware reset */
- if (i >= 3) {
- FTS_ERROR("[ESD]: Read Chip id failed, need TP reset!!");
- return 1;
- }
-
- return 0;
+ return false;
}
-/*****************************************************************************
- * Name: get_flow_cnt
- * Brief: Read flow cnt(0x91)
- * Input:
- * Output:
- * Return: 1 - Reg 0x91(flow cnt) abnormal: hold a value for 5 times
- * 0 - Reg 0x91(flow cnt) normal
- *****************************************************************************/
-static bool get_flow_cnt(void)
+static int esdcheck_algorithm(struct fts_ts_data *ts_data)
{
- int err = 0;
- u8 reg_value = 0;
- u8 reg_addr = 0;
+ int ret = 0;
+ u8 reg_value = 0;
+ u8 reg_addr = 0;
+ bool hardware_reset = 0;
- reg_addr = FTS_REG_FLOW_WORK_CNT;
- err = fts_i2c_read(fts_i2c_client, ®_addr, 1, ®_value, 1);
- if (err < 0) {
- FTS_ERROR("[ESD]: Read Reg 0x91 failed ret = %d!!", err);
- fts_esdcheck_data.i2c_nack_cnt++;
- } else {
- if (reg_value == fts_esdcheck_data.flow_work_cnt_last)
- fts_esdcheck_data.flow_work_hold_cnt++;
- else
- fts_esdcheck_data.flow_work_hold_cnt = 0;
+ /* 1. esdcheck is interrupt, then return */
+ if (fts_esdcheck_data.intr == 1) {
+ fts_esdcheck_data.intr_cnt++;
+ if (fts_esdcheck_data.intr_cnt > ESDCHECK_INTRCNT_MAX)
+ fts_esdcheck_data.intr = 0;
+ else
+ return 0;
+ }
- fts_esdcheck_data.flow_work_cnt_last = reg_value;
- }
+ /* 2. check power state, if suspend, no need check esd */
+ if (fts_esdcheck_data.suspend == 1) {
+ FTS_DEBUG("In suspend, not check esd");
+ /* because in suspend state, adb can be used, when upgrade FW, will
+ * active ESD check(active = 1); But in suspend, then will don't
+ * queue_delayed_work, when resume, don't check ESD again
+ */
+ return 0;
+ }
- /* if read flow work cnt 5 times and the value are all the same,
- * then need hardware_reset.
- */
- if (fts_esdcheck_data.flow_work_hold_cnt >= 5) {
- FTS_DEBUG("[ESD]: Flow Work Cnt, need execute TP reset!!");
- return 1;
- }
+ /* 3. check fts_esdcheck_data.proc_debug state, if 1-proc busy, no need check esd*/
+ if (fts_esdcheck_data.proc_debug == 1) {
+ FTS_INFO("In apk/adb command mode, not check esd");
+ return 0;
+ }
- return 0;
-}
+ /* 4. In factory mode, can't check esd */
+ reg_addr = FTS_REG_WORKMODE;
+ ret = fts_read_reg(reg_addr, ®_value);
+ if ( ret < 0 ) {
+ fts_esdcheck_data.nack_cnt++;
+ } else if ( (reg_value & 0x70) != FTS_REG_WORKMODE_WORK_VALUE) {
+ FTS_DEBUG("not in work mode(%x), no check esd", reg_value);
+ return 0;
+ }
-/*****************************************************************************
- * Name: esdcheck_algorithm
- * Brief: esd check algorithm
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int esdcheck_algorithm(void)
-{
- int err = 0;
- u8 reg_value = 0;
- u8 reg_addr = 0;
- bool hardware_reset = 0;
-
- /* 1. esdcheck is interrupt, then return */
- if (fts_esdcheck_data.intr == 1) {
- FTS_INFO("[ESD]: In interrupt state, not check esd, return!!");
- return 0;
- }
-
- /* 2. check power state, if suspend, no need check esd */
- if (fts_esdcheck_data.suspend == 1) {
- FTS_INFO("[ESD]: In suspend, not check esd, return!!");
- /* because in suspend state, adb can be used, when upgrade FW,
- * will active ESD check(active = 1).
- * But in suspend, then will don't queue_delayed_work,
- * when resume, don't check ESD again
- */
- fts_esdcheck_data.active = 0;
- return 0;
- }
-
- /* 3. check fts_esdcheck_data.proc_debug state,
- * if 1-proc busy, no need check esd
- */
- if (fts_esdcheck_data.proc_debug == 1) {
- FTS_INFO("[ESD]: In cmd mode, not check esd, return!!");
- return 0;
- }
-
- /* 4. In factory mode, can't check esd */
- reg_addr = FTS_REG_WORKMODE;
- err = fts_i2c_read(fts_i2c_client, ®_addr, 1, ®_value, 1);
- if (err < 0) {
- fts_esdcheck_data.i2c_nack_cnt++;
- } else if ((reg_value & 0x70) == FTS_REG_WORKMODE_FACTORY_VALUE) {
- FTS_INFO("[ESD]: In factory mode, not check esd, return!!");
- return 0;
- }
-
- /* 5. IDC esd check lcd default:close */
+ /* 5. IDC esd check lcd default:close */
#if LCD_ESD_PATCH
- idc_esdcheck_lcderror();
+ idc_esdcheck_lcderror(ts_data);
#endif
- /* 6. Get Chip ID */
- hardware_reset = get_chip_id();
+ /* 6. Get Chip ID */
+ hardware_reset = get_chip_id(ts_data);
- /* 7. get Flow work cnt: 0x91 If no change for 5 times,
- * then ESD and reset
- */
- if (!hardware_reset)
- hardware_reset = get_flow_cnt();
+ /* 7. get Flow work cnt: 0x91 If no change for 5 times, then ESD and reset */
+ if (!hardware_reset) {
+ hardware_reset = get_flow_cnt(ts_data);
+ }
- /* 8. If need hardware reset, then handle it here */
- if (hardware_reset == 1)
- fts_esdcheck_tp_reset();
+ /* 8. If need hardware reset, then handle it here */
+ if (hardware_reset == 1) {
+ FTS_DEBUG("NoACK=%d, Error Data=%d, Hardware Reset=%d",
+ fts_esdcheck_data.nack_cnt,
+ fts_esdcheck_data.dataerror_cnt,
+ fts_esdcheck_data.hardware_reset_cnt);
+ fts_esdcheck_tp_reset(ts_data);
+ }
- FTS_INFO("[ESD]: NoACK=%d, Error Data=%d, Hardware Reset=%d\n",
- fts_esdcheck_data.i2c_nack_cnt,
- fts_esdcheck_data.i2c_dataerror_cnt,
- fts_esdcheck_data.hardware_reset_cnt);
- return 0;
+ return 0;
}
-/*****************************************************************************
- * Name: fts_esdcheck_func
- * Brief: fts_esdcheck_func
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
static void esdcheck_func(struct work_struct *work)
{
- FTS_FUNC_ENTER();
+ struct fts_ts_data *ts_data = container_of(work,
+ struct fts_ts_data, esdcheck_work.work);
- esdcheck_algorithm();
+ if (ENABLE == fts_esdcheck_data.mode) {
+ esdcheck_algorithm(ts_data);
+ queue_delayed_work(ts_data->ts_workqueue, &ts_data->esdcheck_work,
+ msecs_to_jiffies(ESDCHECK_WAIT_TIME));
+ }
- if (fts_esdcheck_data.suspend == 0) {
- queue_delayed_work(fts_esdcheck_workqueue,
- &fts_esdcheck_work,
- msecs_to_jiffies(ESDCHECK_WAIT_TIME));
- }
-
- FTS_FUNC_EXIT();
}
-/*****************************************************************************
- * Name: fts_esdcheck_set_intr
- * Brief: interrupt flag (main used in interrupt tp report)
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
int fts_esdcheck_set_intr(bool intr)
{
- /* interrupt don't add debug message */
- fts_esdcheck_data.intr = intr;
- return 0;
+ /* interrupt don't add debug message */
+ fts_esdcheck_data.intr = intr;
+ fts_esdcheck_data.intr_cnt = (u8)intr;
+ return 0;
}
-/*****************************************************************************
- * Name: fts_esdcheck_get_status(void)
- * Brief: get current status
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-int fts_esdcheck_get_status(void)
+static int fts_esdcheck_get_status(void)
{
- /* interrupt don't add debug message */
- return fts_esdcheck_data.active;
+ /* interrupt don't add debug message */
+ return fts_esdcheck_data.mode;
}
/*****************************************************************************
- * Name: fts_esdcheck_proc_busy
- * Brief: When APK or ADB command access TP via driver, then need
- * set proc_debug, then will not check ESD.
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
+* Name: fts_esdcheck_proc_busy
+* Brief: When APK or ADB command access TP via driver, then need set proc_debug,
+* then will not check ESD.
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
int fts_esdcheck_proc_busy(bool proc_debug)
{
- fts_esdcheck_data.proc_debug = proc_debug;
- return 0;
+ fts_esdcheck_data.proc_debug = proc_debug;
+ return 0;
}
/*****************************************************************************
- * Name: fts_esdcheck_switch
- * Brief: FTS esd check function switch.
- * Input: enable: 1 - Enable esd check
- * 0 - Disable esd check
- * Output:
- * Return:
- *****************************************************************************/
+* Name: fts_esdcheck_switch
+* Brief: FTS esd check function switch.
+* Input: enable: 1 - Enable esd check
+* 0 - Disable esd check
+* Output:
+* Return:
+*****************************************************************************/
int fts_esdcheck_switch(bool enable)
{
- FTS_FUNC_ENTER();
- if (enable == 1) {
- if (fts_esdcheck_data.active == 0) {
- FTS_INFO("[ESD]: ESD check start!!");
- fts_esdcheck_data.active = 1;
- queue_delayed_work(fts_esdcheck_workqueue,
- &fts_esdcheck_work,
- msecs_to_jiffies(ESDCHECK_WAIT_TIME));
- }
- } else {
- if (fts_esdcheck_data.active == 1) {
- FTS_INFO("[ESD]: ESD check stop!!");
- fts_esdcheck_data.active = 0;
- cancel_delayed_work_sync(&fts_esdcheck_work);
- }
- }
+ struct fts_ts_data *ts_data = fts_data;
+ FTS_FUNC_ENTER();
+ if (fts_esdcheck_data.mode == ENABLE) {
+ if (enable) {
+ FTS_DEBUG("ESD check start");
+ fts_esdcheck_data.flow_work_hold_cnt = 0;
+ fts_esdcheck_data.flow_work_cnt_last = 0;
+ fts_esdcheck_data.intr = 0;
+ fts_esdcheck_data.intr_cnt = 0;
+ queue_delayed_work(ts_data->ts_workqueue,
+ &ts_data->esdcheck_work,
+ msecs_to_jiffies(ESDCHECK_WAIT_TIME));
+ } else {
+ FTS_DEBUG("ESD check stop");
+ cancel_delayed_work_sync(&ts_data->esdcheck_work);
+ }
+ }
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_EXIT();
+ return 0;
}
-/*****************************************************************************
- * Name: fts_esdcheck_suspend
- * Brief: Run when tp enter into suspend
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
int fts_esdcheck_suspend(void)
{
- FTS_FUNC_ENTER();
- fts_esdcheck_switch(DISABLE);
- fts_esdcheck_data.suspend = 1;
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_ENTER();
+ fts_esdcheck_switch(DISABLE);
+ fts_esdcheck_data.suspend = 1;
+ fts_esdcheck_data.intr = 0;
+ fts_esdcheck_data.intr_cnt = 0;
+ FTS_FUNC_EXIT();
+ return 0;
}
-/*****************************************************************************
- * Name: fts_esdcheck_resume
- * Brief: Run when tp resume
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-int fts_esdcheck_resume(void)
+int fts_esdcheck_resume( void )
{
- FTS_FUNC_ENTER();
- fts_esdcheck_switch(ENABLE);
- fts_esdcheck_data.suspend = 0;
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_ENTER();
+ fts_esdcheck_switch(ENABLE);
+ fts_esdcheck_data.suspend = 0;
+ fts_esdcheck_data.intr = 0;
+ fts_esdcheck_data.intr_cnt = 0;
+ FTS_FUNC_EXIT();
+ return 0;
}
-
-/*****************************************************************************
- * Name: fts_esdcheck_init
- * Brief: Init and create a queue work to check esd
- * Input:
- * Output:
- * Return: < 0: Fail to create esd check queue
- *****************************************************************************/
-int fts_esdcheck_init(void)
+static ssize_t fts_esdcheck_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- FTS_FUNC_ENTER();
+ struct input_dev *input_dev = fts_data->input_dev;
- INIT_DELAYED_WORK(&fts_esdcheck_work, esdcheck_func);
- fts_esdcheck_workqueue = create_workqueue("fts_esdcheck_wq");
- if (fts_esdcheck_workqueue == NULL)
- FTS_INFO("[ESD]: Failed to create esd work queue!!");
+ mutex_lock(&input_dev->mutex);
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ FTS_DEBUG("enable esdcheck");
+ fts_esdcheck_data.mode = ENABLE;
+ fts_esdcheck_switch(ENABLE);
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ FTS_DEBUG("disable esdcheck");
+ fts_esdcheck_switch(DISABLE);
+ fts_esdcheck_data.mode = DISABLE;
+ }
+ mutex_unlock(&input_dev->mutex);
- memset((u8 *)&fts_esdcheck_data, 0, sizeof(struct fts_esdcheck_st));
-
- fts_esdcheck_switch(ENABLE);
- FTS_FUNC_EXIT();
- return 0;
+ return count;
}
-/*****************************************************************************
- * Name: fts_esdcheck_exit
- * Brief: When FTS TP driver is removed, then call this function
- * to destroy work queue
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-int fts_esdcheck_exit(void)
+static ssize_t fts_esdcheck_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- FTS_FUNC_ENTER();
+ int count;
+ struct input_dev *input_dev = fts_data->input_dev;
- destroy_workqueue(fts_esdcheck_workqueue);
+ mutex_lock(&input_dev->mutex);
+ count = snprintf(buf, PAGE_SIZE, "Esd check: %s\n", \
+ fts_esdcheck_get_status() ? "On" : "Off");
+ mutex_unlock(&input_dev->mutex);
- FTS_FUNC_EXIT();
- return 0;
+ return count;
+}
+
+/* sysfs esd node
+ * read example: cat fts_esd_mode ---read esd mode
+ * write example:echo 01 > fts_esd_mode ---make esdcheck enable
+ *
+ */
+static DEVICE_ATTR (fts_esd_mode, S_IRUGO | S_IWUSR, fts_esdcheck_show, fts_esdcheck_store);
+
+static struct attribute *fts_esd_mode_attrs[] = {
+
+ &dev_attr_fts_esd_mode.attr,
+ NULL,
+};
+
+static struct attribute_group fts_esd_group = {
+ .attrs = fts_esd_mode_attrs,
+};
+
+int fts_create_esd_sysfs(struct device *dev)
+{
+ int ret = 0;
+
+ ret = sysfs_create_group(&dev->kobj, &fts_esd_group);
+ if ( ret != 0) {
+ FTS_ERROR("fts_create_esd_sysfs(sysfs) create fail");
+ sysfs_remove_group(&dev->kobj, &fts_esd_group);
+ return ret;
+ }
+ return 0;
+}
+
+int fts_esdcheck_init(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
+
+ if (ts_data->ts_workqueue) {
+ INIT_DELAYED_WORK(&ts_data->esdcheck_work, esdcheck_func);
+ } else {
+ FTS_ERROR("fts workqueue is NULL, can't run esd check function");
+ return -EINVAL;
+ }
+
+ memset((u8 *)&fts_esdcheck_data, 0, sizeof(struct fts_esdcheck_st));
+
+ fts_esdcheck_data.mode = ENABLE;
+ fts_esdcheck_data.intr = 0;
+ fts_esdcheck_data.intr_cnt = 0;
+ fts_esdcheck_switch(ENABLE);
+ fts_create_esd_sysfs(ts_data->dev);
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+int fts_esdcheck_exit(struct fts_ts_data *ts_data)
+{
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_esd_group);
+ return 0;
}
#endif /* FTS_ESDCHECK_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_fun.c b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_fun.c
index 6b21aca..b012c09 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_fun.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_fun.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,28 +16,27 @@
*/
/*****************************************************************************
- *
- * File Name: Focaltech_ex_fun.c
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-08
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: Focaltech_ex_fun.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
+* 1.Included header files
+*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-/*create apk debug channel*/
+* Private constant and macro definitions using #define
+*****************************************************************************/
#define PROC_UPGRADE 0
#define PROC_READ_REGISTER 1
#define PROC_WRITE_REGISTER 2
@@ -48,1098 +47,1135 @@
#define PROC_SET_TEST_FLAG 8
#define PROC_SET_SLAVE_ADDR 10
#define PROC_HW_RESET 11
+#define PROC_READ_STATUS 12
+#define PROC_SET_BOOT_MODE 13
+#define PROC_ENTER_TEST_ENVIRONMENT 14
#define PROC_NAME "ftxxxx-debug"
-#define WRITE_BUF_SIZE 512
-#define READ_BUF_SIZE 512
+#define PROC_BUF_SIZE 256
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+enum {
+ RWREG_OP_READ = 0,
+ RWREG_OP_WRITE = 1,
+};
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-static unsigned char proc_operate_mode = PROC_UPGRADE;
-static struct proc_dir_entry *fts_proc_entry;
-static struct
+* Static variables
+*****************************************************************************/
+static struct rwreg_operation_t {
+ int type; /* 0: read, 1: write */
+ int reg; /* register */
+ int len; /* read/write length */
+ int val; /* length = 1; read: return value, write: op return */
+ int res; /* 0: success, otherwise: fail */
+ char *opbuf; /* length >= 1, read return value, write: op return */
+} rw_op;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+static ssize_t fts_debug_write(
+ struct file *filp, const char __user *buff, size_t count, loff_t *ppos)
{
- int op; /* 0: read, 1: write */
- int reg; /* register */
- int value; /* read: return value, write: op return */
- int result; /* 0: success, otherwise: fail */
-} g_rwreg_result;
+ u8 *writebuf = NULL;
+ u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
+ int buflen = count;
+ int writelen = 0;
+ int ret = 0;
+ char tmp[PROC_BUF_SIZE];
+ struct fts_ts_data *ts_data = fts_data;
+ struct ftxxxx_proc *proc = &ts_data->proc;
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
+ if ((buflen <= 1) || (buflen > PAGE_SIZE)) {
+ FTS_ERROR("apk proc wirte count(%d>%d) fail", buflen, (int)PAGE_SIZE);
+ return -EINVAL;
+ }
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
+ if (buflen > PROC_BUF_SIZE) {
+ writebuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
+ if (NULL == writebuf) {
+ FTS_ERROR("apk proc wirte buf zalloc fail");
+ return -ENOMEM;
+ }
+ } else {
+ writebuf = tmpbuf;
+ }
+
+ if (copy_from_user(writebuf, buff, buflen)) {
+ FTS_ERROR("[APK]: copy from user error!!");
+ ret = -EFAULT;
+ goto proc_write_err;
+ }
+
+ proc->opmode = writebuf[0];
+ switch (proc->opmode) {
+ case PROC_SET_TEST_FLAG:
+ FTS_DEBUG("[APK]: PROC_SET_TEST_FLAG = %x", writebuf[1]);
+ if (writebuf[1] == 0) {
#if FTS_ESDCHECK_EN
-static void esd_process(u8 *writebuf, int buflen, bool flag)
-{
- if (flag) {
- if ((writebuf[1] == 0xFC) && (writebuf[2] == 0x55)
- && (buflen == 0x03)) {
- /* Upgrade command */
- FTS_DEBUG("[ESD]: Upgrade command(%x %x %x)!!",
- writebuf[0], writebuf[1], writebuf[2]);
- fts_esdcheck_switch(DISABLE);
- } else if ((writebuf[1] == 0x00) && (writebuf[2] == 0x40)
- && (buflen == 0x03)) {
- /* factory mode bit 4 5 6 */
- FTS_DEBUG("[ESD]: Entry factory mode(%x %x %x)!!",
- writebuf[0], writebuf[1], writebuf[2]);
- fts_esdcheck_switch(DISABLE);
- } else if ((writebuf[1] == 0x00) && (writebuf[2] == 0x00)
- && (buflen == 0x03)) {
- /* normal mode bit 4 5 6 */
- FTS_DEBUG("[ESD]: Exit factory mode(%x %x %x)!!",
- writebuf[0], writebuf[1], writebuf[2]);
- fts_esdcheck_switch(ENABLE);
- } else {
- fts_esdcheck_proc_busy(1);
- }
- } else {
- if ((writebuf[1] == 0x07) && (buflen == 0x02)) {
- FTS_DEBUG("[ESD]: Upgrade finish-trigger (07)(%x %x)!!",
- writebuf[0], writebuf[1]);
- fts_esdcheck_switch(ENABLE);
- } else {
- fts_esdcheck_proc_busy(0);
- }
- }
-}
+ fts_esdcheck_switch(ENABLE);
#endif
-
-/*interface of write proc*/
-/************************************************************************
- * Name: fts_debug_write
- * Brief:interface of write proc
- * Input: file point, data buf, data len, no use
- * Output: no
- * Return: data len
- ***********************************************************************/
-static ssize_t fts_debug_write(struct file *filp, const char __user *buff,
- size_t count, loff_t *ppos)
-{
- unsigned char writebuf[WRITE_BUF_SIZE];
- char upgrade_file_path[FILE_NAME_LENGTH];
- int buflen = count;
- int writelen = 0;
- int ret = 0;
- char tmp[25];
-
- if (copy_from_user(&writebuf, buff, buflen)) {
- FTS_DEBUG("[APK]: copy from user error!!");
- return -EFAULT;
- }
+ } else {
#if FTS_ESDCHECK_EN
- esd_process(writebuf, buflen, 1);
+ fts_esdcheck_switch(DISABLE);
#endif
- proc_operate_mode = writebuf[0];
- switch (proc_operate_mode) {
- case PROC_UPGRADE:
+ }
+ break;
- memset(upgrade_file_path, 0, sizeof(upgrade_file_path));
- snprintf(upgrade_file_path, FILE_NAME_LENGTH,
- "%s", writebuf + 1);
- upgrade_file_path[buflen-1] = '\0';
- FTS_DEBUG("%s\n", upgrade_file_path);
- fts_irq_disable();
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(DISABLE);
-#endif
- if (fts_updatefun_curr.upgrade_with_app_bin_file)
- ret = fts_updatefun_curr.
- upgrade_with_app_bin_file(fts_i2c_client,
- upgrade_file_path);
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(ENABLE);
-#endif
- fts_irq_enable();
- if (ret < 0)
- FTS_ERROR("[APK]: upgrade failed!!");
- break;
+ case PROC_READ_REGISTER:
+ proc->cmd[0] = writebuf[1];
+ break;
- case PROC_SET_TEST_FLAG:
- FTS_DEBUG("[APK]: PROC_SET_TEST_FLAG = %x!!", writebuf[1]);
-#if FTS_ESDCHECK_EN
- if (writebuf[1] == 0)
- fts_esdcheck_switch(DISABLE);
- else
- fts_esdcheck_switch(ENABLE);
-#endif
- break;
- case PROC_READ_REGISTER:
- writelen = 1;
- ret = fts_i2c_write(fts_i2c_client, writebuf + 1, writelen);
- if (ret < 0)
- FTS_ERROR("[APK]: write iic error!!");
- break;
- case PROC_WRITE_REGISTER:
- writelen = 2;
- ret = fts_i2c_write(fts_i2c_client, writebuf + 1, writelen);
- if (ret < 0)
- FTS_ERROR("[APK]: write iic error!!");
- break;
- case PROC_SET_SLAVE_ADDR:
- ret = fts_i2c_client->addr;
- FTS_DEBUG("Original i2c addr 0x%x ", ret << 1);
- if (writebuf[1] != fts_i2c_client->addr) {
- fts_i2c_client->addr = writebuf[1];
- FTS_DEBUG("Change i2c addr 0x%x to 0x%x", ret << 1,
- writebuf[1] << 1);
+ case PROC_WRITE_REGISTER:
+ ret = fts_write_reg(writebuf[1], writebuf[2]);
+ if (ret < 0) {
+ FTS_ERROR("PROC_WRITE_REGISTER write error");
+ goto proc_write_err;
+ }
+ break;
- }
- break;
+ case PROC_READ_DATA:
+ writelen = buflen - 1;
+ if (writelen >= FTX_MAX_COMMMAND_LENGTH) {
+ FTS_ERROR("cmd(PROC_READ_DATA) length(%d) fail", writelen);
+ goto proc_write_err;
+ }
+ memcpy(proc->cmd, writebuf + 1, writelen);
+ proc->cmd_len = writelen;
+ ret = fts_write(writebuf + 1, writelen);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_DATA write error");
+ goto proc_write_err;
+ }
+ break;
- case PROC_HW_RESET:
+ case PROC_WRITE_DATA:
+ writelen = buflen - 1;
+ ret = fts_write(writebuf + 1, writelen);
+ if (ret < 0) {
+ FTS_ERROR("PROC_WRITE_DATA write error");
+ goto proc_write_err;
+ }
+ break;
- snprintf(tmp, 25, "%s", writebuf + 1);
- tmp[buflen - 1] = '\0';
- if (memcmp(tmp, "focal_driver", 12) == 0) {
- FTS_DEBUG("Begin HW Reset");
- fts_reset_proc(1);
- }
+ case PROC_SET_SLAVE_ADDR:
+ break;
- break;
+ case PROC_HW_RESET:
+ snprintf(tmp, PROC_BUF_SIZE, "%s", writebuf + 1);
+ tmp[buflen - 1] = '\0';
+ if (strncmp(tmp, "focal_driver", 12) == 0) {
+ FTS_INFO("APK execute HW Reset");
+ fts_reset_proc(0);
+ }
+ break;
- case PROC_AUTOCLB:
- FTS_DEBUG("[APK]: autoclb!!");
- fts_ctpm_auto_clb(fts_i2c_client);
- break;
- case PROC_READ_DATA:
- case PROC_WRITE_DATA:
- writelen = count - 1;
- if (writelen > 0) {
- ret = fts_i2c_write(fts_i2c_client, writebuf + 1,
- writelen);
- if (ret < 0)
- FTS_ERROR("[APK]: write iic error!!");
- }
- break;
- default:
- break;
- }
+ case PROC_SET_BOOT_MODE:
+ FTS_DEBUG("[APK]: PROC_SET_BOOT_MODE = %x", writebuf[1]);
+ if (0 == writebuf[1]) {
+ ts_data->fw_is_running = true;
+ } else {
+ ts_data->fw_is_running = false;
+ }
+ break;
+ case PROC_ENTER_TEST_ENVIRONMENT:
+ FTS_DEBUG("[APK]: PROC_ENTER_TEST_ENVIRONMENT = %x", writebuf[1]);
+ if (0 == writebuf[1]) {
+ fts_enter_test_environment(0);
+ } else {
+ fts_enter_test_environment(1);
+ }
+ break;
-#if FTS_ESDCHECK_EN
- esd_process(writebuf, buflen, 0);
-#endif
+ default:
+ break;
+ }
- if (ret < 0)
- return ret;
- else
- return count;
+ ret = buflen;
+proc_write_err:
+ if ((buflen > PROC_BUF_SIZE) && writebuf) {
+ kfree(writebuf);
+ writebuf = NULL;
+ }
+ return ret;
}
-/* interface of read proc */
-/************************************************************************
- * Name: fts_debug_read
- * Brief:interface of read proc
- * Input: point to the data, no use, no use, read len, no use, no use
- * Output: page point to data
- * Return: read char number
- ***********************************************************************/
-static ssize_t fts_debug_read(struct file *filp, char __user *buff,
- size_t count, loff_t *ppos)
+static ssize_t fts_debug_read(
+ struct file *filp, char __user *buff, size_t count, loff_t *ppos)
{
- int ret = 0;
- int num_read_chars = 0;
- int readlen = 0;
- u8 regvalue = 0x00, regaddr = 0x00;
- unsigned char buf[READ_BUF_SIZE];
+ int ret = 0;
+ int num_read_chars = 0;
+ int buflen = count;
+ u8 *readbuf = NULL;
+ u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
+ struct fts_ts_data *ts_data = fts_data;
+ struct ftxxxx_proc *proc = &ts_data->proc;
- memset(buf, 0, READ_BUF_SIZE);
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(1);
-#endif
- switch (proc_operate_mode) {
- case PROC_UPGRADE:
- /* after calling fts_debug_write to upgrade */
- regaddr = FTS_REG_FW_VER;
- ret = fts_i2c_read_reg(fts_i2c_client, regaddr, ®value);
- if (ret < 0)
- num_read_chars = snprintf(buf, READ_BUF_SIZE, "%s",
- "get fw version failed.\n");
- else
- num_read_chars = snprintf(buf, READ_BUF_SIZE,
- "current fw ver:0x%02x\n", regvalue);
- break;
- case PROC_READ_REGISTER:
- readlen = 1;
- ret = fts_i2c_read(fts_i2c_client, NULL, 0, buf, readlen);
- if (ret < 0) {
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
-#endif
- FTS_ERROR("[APK]: read iic error!!");
- return ret;
- }
- num_read_chars = 1;
- break;
- case PROC_READ_DATA:
- readlen = count;
- ret = fts_i2c_read(fts_i2c_client, NULL, 0, buf, readlen);
- if (ret < 0) {
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
-#endif
- FTS_ERROR("[APK]: read iic error!!");
- return ret;
- }
+ if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
+ FTS_ERROR("apk proc read count(%d>%d) fail", buflen, (int)PAGE_SIZE);
+ return -EINVAL;
+ }
- num_read_chars = readlen;
- break;
- case PROC_WRITE_DATA:
- break;
- default:
- break;
- }
+ if (buflen > PROC_BUF_SIZE) {
+ readbuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
+ if (NULL == readbuf) {
+ FTS_ERROR("apk proc wirte buf zalloc fail");
+ return -ENOMEM;
+ }
+ } else {
+ readbuf = tmpbuf;
+ }
#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
+ fts_esdcheck_proc_busy(1);
#endif
- if (copy_to_user(buff, buf, num_read_chars)) {
- FTS_ERROR("[APK]: copy to user error!!");
- return -EFAULT;
- }
+ switch (proc->opmode) {
+ case PROC_READ_REGISTER:
+ num_read_chars = 1;
+ ret = fts_read_reg(proc->cmd[0], &readbuf[0]);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_REGISTER read error");
+ goto proc_read_err;
+ }
+ break;
+ case PROC_WRITE_REGISTER:
+ break;
- return num_read_chars;
+ case PROC_READ_DATA:
+ num_read_chars = buflen;
+ ret = fts_read(NULL, 0, readbuf, num_read_chars);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_DATA read error");
+ goto proc_read_err;
+ }
+ break;
+
+ case PROC_WRITE_DATA:
+ break;
+
+ default:
+ break;
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_proc_busy(0);
+#endif
+
+ if (copy_to_user(buff, readbuf, num_read_chars)) {
+ FTS_ERROR("copy to user error");
+ ret = -EFAULT;
+ goto proc_read_err;
+ }
+
+ ret = num_read_chars;
+proc_read_err:
+ if ((buflen > PROC_BUF_SIZE) && readbuf) {
+ kfree(readbuf);
+ readbuf = NULL;
+ }
+ return ret;
}
static const struct file_operations fts_proc_fops = {
- .owner = THIS_MODULE,
- .read = fts_debug_read,
- .write = fts_debug_write,
+ .owner = THIS_MODULE,
+ .read = fts_debug_read,
+ .write = fts_debug_write,
};
-
-/************************************************************************
- * Name: fts_create_apk_debug_channel
- * Brief: create apk debug channel
- * Input: i2c info
- * Output: no
- * Return: success =0
- ***********************************************************************/
-int fts_create_apk_debug_channel(struct i2c_client *client)
+#else
+static int fts_debug_write(
+ struct file *filp, const char __user *buff, unsigned long len, void *data)
{
- fts_proc_entry = proc_create(PROC_NAME, 0644, NULL, &fts_proc_fops);
- if (fts_proc_entry == NULL) {
- FTS_ERROR("Couldn't create proc entry!");
- return -ENOMEM;
- }
+ u8 *writebuf = NULL;
+ u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
+ int buflen = count;
+ int writelen = 0;
+ int ret = 0;
+ char tmp[PROC_BUF_SIZE];
+ struct fts_ts_data *ts_data = fts_data;
+ struct ftxxxx_proc *proc = &ts_data->proc;
- FTS_INFO("Create proc entry success!");
+ if ((buflen <= 1) || (buflen > PAGE_SIZE)) {
+ FTS_ERROR("apk proc wirte count(%d>%d) fail", buflen, (int)PAGE_SIZE);
+ return -EINVAL;
+ }
- return 0;
+ if (buflen > PROC_BUF_SIZE) {
+ writebuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
+ if (NULL == writebuf) {
+ FTS_ERROR("apk proc wirte buf zalloc fail");
+ return -ENOMEM;
+ }
+ } else {
+ writebuf = tmpbuf;
+ }
+
+ if (copy_from_user(writebuf, buff, buflen)) {
+ FTS_ERROR("[APK]: copy from user error!!");
+ ret = -EFAULT;
+ goto proc_write_err;
+ }
+
+ proc->opmode = writebuf[0];
+ switch (proc->opmode) {
+ case PROC_SET_TEST_FLAG:
+ FTS_DEBUG("[APK]: PROC_SET_TEST_FLAG = %x", writebuf[1]);
+ if (writebuf[1] == 0) {
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(ENABLE);
+#endif
+ } else {
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(DISABLE);
+#endif
+ }
+ break;
+
+ case PROC_READ_REGISTER:
+ proc->cmd[0] = writebuf[1];
+ break;
+
+ case PROC_WRITE_REGISTER:
+ ret = fts_write_reg(writebuf[1], writebuf[2]);
+ if (ret < 0) {
+ FTS_ERROR("PROC_WRITE_REGISTER write error");
+ goto proc_write_err;
+ }
+ break;
+
+ case PROC_READ_DATA:
+ writelen = buflen - 1;
+ if (writelen >= FTX_MAX_COMMMAND_LENGTH) {
+ FTS_ERROR("cmd(PROC_READ_DATA) length(%d) fail", writelen);
+ goto proc_write_err;
+ }
+ memcpy(proc->cmd, writebuf + 1, writelen);
+ proc->cmd_len = writelen;
+ ret = fts_write(writebuf + 1, writelen);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_DATA write error");
+ goto proc_write_err;
+ }
+ break;
+
+ case PROC_WRITE_DATA:
+ writelen = buflen - 1;
+ ret = fts_write(writebuf + 1, writelen);
+ if (ret < 0) {
+ FTS_ERROR("PROC_WRITE_DATA write error");
+ goto proc_write_err;
+ }
+ break;
+
+ case PROC_SET_SLAVE_ADDR:
+ break;
+
+ case PROC_HW_RESET:
+ snprintf(tmp, PROC_BUF_SIZE, "%s", writebuf + 1);
+ tmp[buflen - 1] = '\0';
+ if (strncmp(tmp, "focal_driver", 12) == 0) {
+ FTS_INFO("APK execute HW Reset");
+ fts_reset_proc(0);
+ }
+ break;
+
+ case PROC_SET_BOOT_MODE:
+ FTS_DEBUG("[APK]: PROC_SET_BOOT_MODE = %x", writebuf[1]);
+ if (0 == writebuf[1]) {
+ ts_data->fw_is_running = true;
+ } else {
+ ts_data->fw_is_running = false;
+ }
+ break;
+ case PROC_ENTER_TEST_ENVIRONMENT:
+ FTS_DEBUG("[APK]: PROC_ENTER_TEST_ENVIRONMENT = %x", writebuf[1]);
+ if (0 == writebuf[1]) {
+ fts_enter_test_environment(0);
+ } else {
+ fts_enter_test_environment(1);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ret = buflen;
+proc_write_err:
+ if ((buflen > PROC_BUF_SIZE) && writebuf) {
+ kfree(writebuf);
+ writebuf = NULL;
+ }
+ return ret;
+}
+
+static int fts_debug_read(
+ char *page, char **start, off_t off, int count, int *eof, void *data )
+{
+ int ret = 0;
+ int num_read_chars = 0;
+ int buflen = count;
+ u8 *readbuf = NULL;
+ u8 tmpbuf[PROC_BUF_SIZE] = { 0 };
+ struct fts_ts_data *ts_data = fts_data;
+ struct ftxxxx_proc *proc = &ts_data->proc;
+
+ if ((buflen <= 0) || (buflen > PAGE_SIZE)) {
+ FTS_ERROR("apk proc read count(%d>%d) fail", buflen, (int)PAGE_SIZE);
+ return -EINVAL;
+ }
+
+ if (buflen > PROC_BUF_SIZE) {
+ readbuf = (u8 *)kzalloc(buflen * sizeof(u8), GFP_KERNEL);
+ if (NULL == readbuf) {
+ FTS_ERROR("apk proc wirte buf zalloc fail");
+ return -ENOMEM;
+ }
+ } else {
+ readbuf = tmpbuf;
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_proc_busy(1);
+#endif
+
+ switch (proc->opmode) {
+ case PROC_READ_REGISTER:
+ num_read_chars = 1;
+ ret = fts_read_reg(proc->cmd[0], &readbuf[0]);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_REGISTER read error");
+ goto proc_read_err;
+ }
+ break;
+ case PROC_WRITE_REGISTER:
+ break;
+
+ case PROC_READ_DATA:
+ num_read_chars = buflen;
+ ret = fts_read(NULL, 0, readbuf, num_read_chars);
+ if (ret < 0) {
+ FTS_ERROR("PROC_READ_DATA read error");
+ goto proc_read_err;
+ }
+ break;
+
+ case PROC_WRITE_DATA:
+ break;
+
+ default:
+ break;
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_proc_busy(0);
+#endif
+
+ if (copy_to_user(buff, readbuf, num_read_chars)) {
+ FTS_ERROR("copy to user error");
+ ret = -EFAULT;
+ goto proc_read_err;
+ }
+
+ ret = num_read_chars;
+proc_read_err:
+ if ((buflen > PROC_BUF_SIZE) && readbuf) {
+ kfree(readbuf);
+ readbuf = NULL;
+ }
+ return ret;
+}
+#endif
+
+int fts_create_apk_debug_channel(struct fts_ts_data *ts_data)
+{
+ struct ftxxxx_proc *proc = &ts_data->proc;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+ proc->proc_entry = proc_create(PROC_NAME, 0777, NULL, &fts_proc_fops);
+ if (NULL == proc->proc_entry) {
+ FTS_ERROR("create proc entry fail");
+ return -ENOMEM;
+ }
+#else
+ proc->proc_entry = create_proc_entry(PROC_NAME, 0777, NULL);
+ if (NULL == proc->proc_entry) {
+ FTS_ERROR("create proc entry fail");
+ return -ENOMEM;
+ }
+ proc->proc_entry->write_proc = fts_debug_write;
+ proc->proc_entry->read_proc = fts_debug_read;
+#endif
+
+ FTS_INFO("Create proc entry success!");
+ return 0;
+}
+
+void fts_release_apk_debug_channel(struct fts_ts_data *ts_data)
+{
+ struct ftxxxx_proc *proc = &ts_data->proc;
+
+ if (proc->proc_entry) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+ proc_remove(proc->proc_entry);
+#else
+ remove_proc_entry(PROC_NAME, NULL);
+#endif
+ }
}
/************************************************************************
- * Name: fts_release_apk_debug_channel
- * Brief: release apk debug channel
- * Input: no
- * Output: no
- * Return: no
+ * sysfs interface
***********************************************************************/
-void fts_release_apk_debug_channel(void)
+/* fts_hw_reset interface */
+static ssize_t fts_hw_reset_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- if (fts_proc_entry)
- proc_remove(fts_proc_entry);
+ struct input_dev *input_dev = fts_data->input_dev;
+ ssize_t count = 0;
+
+ mutex_lock(&input_dev->mutex);
+ fts_reset_proc(0);
+ count = snprintf(buf, PAGE_SIZE, "hw reset executed\n");
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
}
+static ssize_t fts_hw_reset_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
+
+/* fts_irq interface */
+static ssize_t fts_irq_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t count = 0;
+ struct irq_desc *desc = irq_to_desc(fts_data->irq);
+
+ count = snprintf(buf, PAGE_SIZE, "irq_depth:%d\n", desc->depth);
+
+ return count;
+}
+
+static ssize_t fts_irq_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ FTS_INFO("enable irq");
+ fts_irq_enable();
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ FTS_INFO("disable irq");
+ fts_irq_disable();
+ }
+ mutex_unlock(&input_dev->mutex);
+ return count;
+}
+
+/* fts_boot_mode interface */
+static ssize_t fts_bootmode_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ FTS_FUNC_ENTER();
+ mutex_lock(&input_dev->mutex);
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ FTS_INFO("[EX-FUN]set to boot mode");
+ fts_data->fw_is_running = false;
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ FTS_INFO("[EX-FUN]set to fw mode");
+ fts_data->fw_is_running = true;
+ }
+ mutex_unlock(&input_dev->mutex);
+ FTS_FUNC_EXIT();
+
+ return count;
+}
+
+static ssize_t fts_bootmode_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t count = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ FTS_FUNC_ENTER();
+ mutex_lock(&input_dev->mutex);
+ if (true == fts_data->fw_is_running) {
+ count = snprintf(buf, PAGE_SIZE, "tp is in fw mode\n");
+ } else {
+ count = snprintf(buf, PAGE_SIZE, "tp is in boot mode\n");
+ }
+ mutex_unlock(&input_dev->mutex);
+ FTS_FUNC_EXIT();
+
+ return count;
+}
+
+/* fts_tpfwver interface */
+static ssize_t fts_tpfwver_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct fts_ts_data *ts_data = fts_data;
+ struct input_dev *input_dev = ts_data->input_dev;
+ ssize_t num_read_chars = 0;
+ u8 fwver = 0;
+
+ mutex_lock(&input_dev->mutex);
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_proc_busy(1);
+#endif
+ fts_read_reg(FTS_REG_FW_VER, &fwver);
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_proc_busy(0);
+#endif
+ if ((fwver == 0xFF) || (fwver == 0x00))
+ num_read_chars = snprintf(buf, PAGE_SIZE, "get tp fw version fail!\n");
+ else
+ num_read_chars = snprintf(buf, PAGE_SIZE, "%02x\n", fwver);
+
+ mutex_unlock(&input_dev->mutex);
+ return num_read_chars;
+}
+
+static ssize_t fts_tpfwver_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
+
+/* fts_rw_reg */
+static ssize_t fts_tprwreg_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count;
+ int i;
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+
+ if (rw_op.len < 0) {
+ count = snprintf(buf, PAGE_SIZE, "Invalid cmd line\n");
+ } else if (rw_op.len == 1) {
+ if (RWREG_OP_READ == rw_op.type) {
+ if (rw_op.res == 0) {
+ count = snprintf(buf, PAGE_SIZE, "Read %02X: %02X\n", rw_op.reg, rw_op.val);
+ } else {
+ count = snprintf(buf, PAGE_SIZE, "Read %02X failed, ret: %d\n", rw_op.reg, rw_op.res);
+ }
+ } else {
+ if (rw_op.res == 0) {
+ count = snprintf(buf, PAGE_SIZE, "Write %02X, %02X success\n", rw_op.reg, rw_op.val);
+ } else {
+ count = snprintf(buf, PAGE_SIZE, "Write %02X failed, ret: %d\n", rw_op.reg, rw_op.res);
+ }
+ }
+ } else {
+ if (RWREG_OP_READ == rw_op.type) {
+ count = snprintf(buf, PAGE_SIZE, "Read Reg: [%02X]-[%02X]\n", rw_op.reg, rw_op.reg + rw_op.len);
+ count += snprintf(buf + count, PAGE_SIZE, "Result: ");
+ if (rw_op.res) {
+ count += snprintf(buf + count, PAGE_SIZE, "failed, ret: %d\n", rw_op.res);
+ } else {
+ if (rw_op.opbuf) {
+ for (i = 0; i < rw_op.len; i++) {
+ count += snprintf(buf + count, PAGE_SIZE, "%02X ", rw_op.opbuf[i]);
+ }
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ }
+ }
+ } else {
+ ;
+ count = snprintf(buf, PAGE_SIZE, "Write Reg: [%02X]-[%02X]\n", rw_op.reg, rw_op.reg + rw_op.len - 1);
+ count += snprintf(buf + count, PAGE_SIZE, "Write Data: ");
+ if (rw_op.opbuf) {
+ for (i = 1; i < rw_op.len; i++) {
+ count += snprintf(buf + count, PAGE_SIZE, "%02X ", rw_op.opbuf[i]);
+ }
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ }
+ if (rw_op.res) {
+ count += snprintf(buf + count, PAGE_SIZE, "Result: failed, ret: %d\n", rw_op.res);
+ } else {
+ count += snprintf(buf + count, PAGE_SIZE, "Result: success\n");
+ }
+ }
+ /*if (rw_op.opbuf) {
+ kfree(rw_op.opbuf);
+ rw_op.opbuf = NULL;
+ }*/
+ }
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+static int shex_to_int(const char *hex_buf, int size)
+{
+ int i;
+ int base = 1;
+ int value = 0;
+ char single;
+
+ for (i = size - 1; i >= 0; i--) {
+ single = hex_buf[i];
+
+ if ((single >= '0') && (single <= '9')) {
+ value += (single - '0') * base;
+ } else if ((single >= 'a') && (single <= 'z')) {
+ value += (single - 'a' + 10) * base;
+ } else if ((single >= 'A') && (single <= 'Z')) {
+ value += (single - 'A' + 10) * base;
+ } else {
+ return -EINVAL;
+ }
+
+ base *= 16;
+ }
+
+ return value;
+}
+
+
+static u8 shex_to_u8(const char *hex_buf, int size)
+{
+ return (u8)shex_to_int(hex_buf, size);
+}
/*
- * fts_hw_reset interface
+ * Format buf:
+ * [0]: '0' write, '1' read(reserved)
+ * [1-2]: addr, hex
+ * [3-4]: length, hex
+ * [5-6]...[n-(n+1)]: data, hex
*/
-static ssize_t fts_hw_reset_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static int fts_parse_buf(const char *buf, size_t cmd_len)
{
- return -EPERM;
-}
-static ssize_t fts_hw_reset_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t count = 0;
+ int length;
+ int i;
+ char *tmpbuf;
- fts_reset_proc(200);
+ rw_op.reg = shex_to_u8(buf + 1, 2);
+ length = shex_to_int(buf + 3, 2);
- count = snprintf(buf, PAGE_SIZE, "hw reset executed\n");
+ if (buf[0] == '1') {
+ rw_op.len = length;
+ rw_op.type = RWREG_OP_READ;
+ FTS_DEBUG("read %02X, %d bytes", rw_op.reg, rw_op.len);
+ } else {
+ if (cmd_len < (length * 2 + 5)) {
+ pr_err("data invalided!\n");
+ return -EINVAL;
+ }
+ FTS_DEBUG("write %02X, %d bytes", rw_op.reg, length);
- return count;
+ /* first byte is the register addr */
+ rw_op.type = RWREG_OP_WRITE;
+ rw_op.len = length + 1;
+ }
+
+ if (rw_op.len > 0) {
+ tmpbuf = (char *)kzalloc(rw_op.len, GFP_KERNEL);
+ if (!tmpbuf) {
+ FTS_ERROR("allocate memory failed!\n");
+ return -ENOMEM;
+ }
+
+ if (RWREG_OP_WRITE == rw_op.type) {
+ tmpbuf[0] = rw_op.reg & 0xFF;
+ FTS_DEBUG("write buffer: ");
+ for (i = 1; i < rw_op.len; i++) {
+ tmpbuf[i] = shex_to_u8(buf + 5 + i * 2 - 2, 2);
+ FTS_DEBUG("buf[%d]: %02X", i, tmpbuf[i] & 0xFF);
+ }
+ }
+ rw_op.opbuf = tmpbuf;
+ }
+
+ return rw_op.len;
}
-/*
- * fts_irq interface
- */
-static ssize_t fts_irq_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t fts_tprwreg_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- if (FTS_SYSFS_ECHO_ON(buf)) {
- FTS_INFO("[EX-FUN]enable irq");
- fts_irq_enable();
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- FTS_INFO("[EX-FUN]disable irq");
- fts_irq_disable();
- }
+ struct input_dev *input_dev = fts_data->input_dev;
+ ssize_t cmd_length = 0;
- return count;
-}
+ mutex_lock(&input_dev->mutex);
+ cmd_length = count - 1;
-static ssize_t fts_irq_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return -EPERM;
-}
+ if (rw_op.opbuf) {
+ kfree(rw_op.opbuf);
+ rw_op.opbuf = NULL;
+ }
-/************************************************************************
- * Name: fts_tpfwver_show
- * Brief: show tp fw vwersion
- * Input: device, device attribute, char buf
- * Output: no
- * Return: char number
- ***********************************************************************/
-static ssize_t fts_tpfwver_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t num_read_chars = 0;
- u8 fwver = 0;
-
- mutex_lock(&fts_input_dev->mutex);
+ FTS_DEBUG("cmd len: %d, buf: %s", (int)cmd_length, buf);
+ /* compatible old ops */
+ if (2 == cmd_length) {
+ rw_op.type = RWREG_OP_READ;
+ rw_op.len = 1;
+ rw_op.reg = shex_to_int(buf, 2);
+ } else if (4 == cmd_length) {
+ rw_op.type = RWREG_OP_WRITE;
+ rw_op.len = 1;
+ rw_op.reg = shex_to_int(buf, 2);
+ rw_op.val = shex_to_int(buf + 2, 2);
+ } else if (cmd_length < 5) {
+ FTS_ERROR("Invalid cmd buffer");
+ mutex_unlock(&input_dev->mutex);
+ return -EINVAL;
+ } else {
+ rw_op.len = fts_parse_buf(buf, cmd_length);
+ }
#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(1);
+ fts_esdcheck_proc_busy(1);
#endif
- if (fts_i2c_read_reg(fts_i2c_client, FTS_REG_FW_VER, &fwver) < 0)
- num_read_chars = snprintf(buf, PAGE_SIZE,
- "I2c transfer error!\n");
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
-#endif
- if (fwver == 255)
- num_read_chars = snprintf(buf, PAGE_SIZE,
- "get tp fw version fail!\n");
- else
- num_read_chars = snprintf(buf, PAGE_SIZE, "%02X\n", fwver);
+ if (rw_op.len < 0) {
+ FTS_ERROR("cmd buffer error!");
- mutex_unlock(&fts_input_dev->mutex);
+ } else {
+ if (RWREG_OP_READ == rw_op.type) {
+ if (rw_op.len == 1) {
+ u8 reg, val;
+ reg = rw_op.reg & 0xFF;
+ rw_op.res = fts_read_reg(reg, &val);
+ rw_op.val = val;
+ } else {
+ char reg;
+ reg = rw_op.reg & 0xFF;
- return num_read_chars;
-}
-/************************************************************************
- * Name: fts_tpfwver_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_tpfwver_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
- return -EPERM;
-}
+ rw_op.res = fts_read(®, 1, rw_op.opbuf, rw_op.len);
+ }
-static int fts_is_hex_char(const char ch)
-{
- int result = 0;
+ if (rw_op.res < 0) {
+ FTS_ERROR("Could not read 0x%02x", rw_op.reg);
+ } else {
+ FTS_INFO("read 0x%02x, %d bytes successful", rw_op.reg, rw_op.len);
+ rw_op.res = 0;
+ }
- if (ch >= '0' && ch <= '9')
- result = 1;/* (int)(ch - '0'); */
- else if (ch >= 'a' && ch <= 'f')
- result = 1;/* (int)(ch - 'a') + 10; */
- else if (ch >= 'A' && ch <= 'F')
- result = 1;/* (int)(ch - 'A') + 10; */
- else
- result = 0;
+ } else {
+ if (rw_op.len == 1) {
+ u8 reg, val;
+ reg = rw_op.reg & 0xFF;
+ val = rw_op.val & 0xFF;
+ rw_op.res = fts_write_reg(reg, val);
+ } else {
+ rw_op.res = fts_write(rw_op.opbuf, rw_op.len);
+ }
+ if (rw_op.res < 0) {
+ FTS_ERROR("Could not write 0x%02x", rw_op.reg);
- return result;
-}
-
-static int fts_hex_char_to_int(const char ch)
-{
- int result = 0;
-
- if (ch >= '0' && ch <= '9')
- result = (int)(ch - '0');
- else if (ch >= 'a' && ch <= 'f')
- result = (int)(ch - 'a') + 10;
- else if (ch >= 'A' && ch <= 'F')
- result = (int)(ch - 'A') + 10;
- else
- result = -1;
-
- return result;
-}
-
-static int fts_hex_to_str(char *hex, int iHexLen, char *ch, int *iChLen)
-{
- int high = 0;
- int low = 0;
- int tmp = 0;
- int i = 0;
- int iCharLen = 0;
-
- if (hex == NULL || ch == NULL)
- return -EINVAL;
-
- FTS_DEBUG("iHexLen: %d in function:%s!!\n\n", iHexLen, __func__);
-
- if (iHexLen % 2 == 1)
- return -EINVAL;
-
- for (i = 0; i < iHexLen; i += 2) {
- high = fts_hex_char_to_int(hex[i]);
- if (high < 0) {
- ch[iCharLen] = '\0';
- return -EINVAL;
- }
-
- low = fts_hex_char_to_int(hex[i+1]);
- if (low < 0) {
- ch[iCharLen] = '\0';
- return -EINVAL;
- }
-
- tmp = (high << 4) + low;
- ch[iCharLen++] = (char)tmp;
- }
-
- ch[iCharLen] = '\0';
- *iChLen = iCharLen;
- FTS_DEBUG("iCharLen: %d, iChLen: %d in function:%s!!\n\n", iCharLen,
- *iChLen, __func__);
-
- return 0;
-}
-
-static void fts_str_to_bytes(char *bufStr, int iLen,
- char *uBytes, int *iBytesLen)
-{
- int i = 0;
- int iNumChLen = 0;
-
- *iBytesLen = 0;
-
- for (i = 0; i < iLen; i++) {
- if (fts_is_hex_char(bufStr[i])) /* filter illegal chars */
- bufStr[iNumChLen++] = bufStr[i];
- }
-
- bufStr[iNumChLen] = '\0';
-
- fts_hex_to_str(bufStr, iNumChLen, uBytes, iBytesLen);
-}
-/************************************************************************
- * Name: fts_tprwreg_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_tprwreg_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int count;
-
- mutex_lock(&fts_input_dev->mutex);
-
- if (!g_rwreg_result.op) {
- if (g_rwreg_result.result == 0)
- count = snprintf(buf, PAGE_SIZE, "Read %02X: %02X\n",
- g_rwreg_result.reg,
- g_rwreg_result.value);
- else
- count = snprintf(buf, PAGE_SIZE,
- "Read %02X failed, ret: %d\n",
- g_rwreg_result.reg,
- g_rwreg_result.result);
- } else {
- if (g_rwreg_result.result == 0)
- count = snprintf(buf, PAGE_SIZE,
- "Write %02X, %02X success\n",
- g_rwreg_result.reg,
- g_rwreg_result.value);
- else
- count = snprintf(buf, PAGE_SIZE,
- "Write %02X failed, ret: %d\n",
- g_rwreg_result.reg,
- g_rwreg_result.result);
- }
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_tprwreg_store
- * Brief: read/write register
- * Input: device, device attribute, char buf, char count
- * Output: print register value
- * Return: char count
- ***********************************************************************/
-static ssize_t fts_tprwreg_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- ssize_t num_read_chars = 0;
- int retval;
- unsigned long int wmreg = 0;
- u8 regaddr = 0xff, regvalue = 0xff;
- u8 valbuf[5] = {0};
-
- memset(valbuf, 0, sizeof(valbuf));
- mutex_lock(&fts_input_dev->mutex);
- num_read_chars = count - 1;
- if (num_read_chars != 2) {
- if (num_read_chars != 4) {
- FTS_ERROR("please input 2 or 4 character");
- goto error_return;
- }
- }
- memcpy(valbuf, buf, num_read_chars);
- retval = kstrtoul(valbuf, 16, &wmreg);
- fts_str_to_bytes((char *)buf, num_read_chars, valbuf, &retval);
-
- if (retval == 1) {
- regaddr = valbuf[0];
- retval = 0;
- } else if (retval == 2) {
- regaddr = valbuf[0];
- regvalue = valbuf[1];
- retval = 0;
- } else
- retval = -1;
-
- if (retval != 0) {
- FTS_ERROR("ERROR: Can't convert to number %s", buf);
- goto error_return;
- }
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(1);
-#endif
- if (num_read_chars == 2) {
- g_rwreg_result.op = 0;
- g_rwreg_result.reg = regaddr;
- /*read register*/
- regaddr = wmreg;
- g_rwreg_result.result = fts_i2c_read_reg(client, regaddr,
- ®value);
- if (g_rwreg_result.result < 0) {
- FTS_ERROR("Could not read the register(0x%02x)",
- regaddr);
- } else {
- FTS_INFO("the register(0x%02x) is 0x%02x", regaddr,
- regvalue);
- g_rwreg_result.value = regvalue;
- g_rwreg_result.result = 0;
- }
- } else {
- regaddr = wmreg>>8;
- regvalue = wmreg;
-
- g_rwreg_result.op = 1;
- g_rwreg_result.reg = regaddr;
- g_rwreg_result.value = regvalue;
- g_rwreg_result.result = fts_i2c_write_reg(client, regaddr,
- regvalue);
- if (g_rwreg_result.result < 0) {
- FTS_ERROR("Could not write the register(0x%02x)",
- regaddr);
-
- } else {
- FTS_INFO("Write 0x%02x to (0x%02x) successful",
- regvalue, regaddr);
- g_rwreg_result.result = 0;
- }
- }
-#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
-#endif
-error_return:
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_fwupdate_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_fwupdate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- /* place holder for future use */
- return -EPERM;
-}
-
-/************************************************************************
- * Name: fts_fwupdate_store
- * Brief: upgrade from *.i
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: char count
- ***********************************************************************/
-static ssize_t fts_fwupdate_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-
- mutex_lock(&fts_input_dev->mutex);
- fts_irq_disable();
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(DISABLE);
-#endif
- if (fts_updatefun_curr.upgrade_with_app_i_file)
- fts_updatefun_curr.upgrade_with_app_i_file(client);
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(ENABLE);
-#endif
- fts_irq_enable();
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_fwupgradeapp_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_fwupgradeapp_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- /* place holder for future use */
- return -EPERM;
-}
-
-/************************************************************************
- * Name: fts_fwupgradeapp_store
- * Brief: upgrade from app.bin
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: char count
- ***********************************************************************/
-static ssize_t fts_fwupgradeapp_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- char fwname[FILE_NAME_LENGTH];
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-
- memset(fwname, 0, sizeof(fwname));
- snprintf(fwname, FILE_NAME_LENGTH, "%s", buf);
- fwname[count-1] = '\0';
-
- mutex_lock(&fts_input_dev->mutex);
- fts_irq_disable();
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(DISABLE);
-#endif
- if (fts_updatefun_curr.upgrade_with_app_bin_file)
- fts_updatefun_curr.upgrade_with_app_bin_file(client, fwname);
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(ENABLE);
-#endif
- fts_irq_enable();
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_driverversion_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_driverversion_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int count;
-
- mutex_lock(&fts_input_dev->mutex);
-
- count = snprintf(buf, PAGE_SIZE, FTS_DRIVER_VERSION "\n");
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_driverversion_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_driverversion_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
- return -EPERM;
-}
+ } else {
+ FTS_INFO("Write 0x%02x, %d bytes successful", rw_op.val, rw_op.len);
+ rw_op.res = 0;
+ }
+ }
+ }
#if FTS_ESDCHECK_EN
-/************************************************************************
- * Name: fts_esdcheck_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_esdcheck_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- mutex_lock(&fts_input_dev->mutex);
-
- if (FTS_SYSFS_ECHO_ON(buf)) {
- FTS_DEBUG("enable esdcheck");
- fts_esdcheck_switch(ENABLE);
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- FTS_DEBUG("disable esdcheck");
- fts_esdcheck_switch(DISABLE);
- }
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return -EPERM;
-}
-
-/************************************************************************
- * Name: fts_esdcheck_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_esdcheck_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int count;
-
- mutex_lock(&fts_input_dev->mutex);
-
- count = snprintf(buf, PAGE_SIZE, "Esd check: %s\n",
- fts_esdcheck_get_status() ? "On" : "Off");
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
+ fts_esdcheck_proc_busy(0);
#endif
-/************************************************************************
- * Name: fts_module_config_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_module_config_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int count = 0;
+ mutex_unlock(&input_dev->mutex);
- mutex_lock(&fts_input_dev->mutex);
-
- count += snprintf(buf, PAGE_SIZE, "FTS_CHIP_TYPE: \t\t\t%04X\n",
- FTS_CHIP_TYPE);
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_DEBUG_EN: \t\t\t%s\n",
- FTS_DEBUG_EN ? "ON" : "OFF");
-#if defined(FTS_MT_PROTOCOL_B_EN)
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_MT_PROTOCOL_B_EN: \t\t%s\n",
- FTS_MT_PROTOCOL_B_EN ? "ON" : "OFF");
-#endif
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_GESTURE_EN: \t\t%s\n",
- FTS_GESTURE_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_ESDCHECK_EN: \t\t%s\n",
- FTS_ESDCHECK_EN ? "ON" : "OFF");
-#if defined(FTS_PSENSOR_EN)
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_PSENSOR_EN: \t\t%s\n",
- FTS_PSENSOR_EN ? "ON" : "OFF");
-#endif
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_GLOVE_EN: \t\t\t%s\n",
- FTS_GLOVE_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_COVER_EN: \t\t%s\n",
- FTS_COVER_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_CHARGER_EN: \t\t\t%s\n",
- FTS_CHARGER_EN ? "ON" : "OFF");
-
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_REPORT_PRESSURE_EN: \t\t%s\n",
- FTS_REPORT_PRESSURE_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_FORCE_TOUCH_EN: \t\t%s\n",
- FTS_FORCE_TOUCH_EN ? "ON" : "OFF");
-
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_TEST_EN: \t\t\t%s\n",
- FTS_TEST_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_APK_NODE_EN: \t\t%s\n",
- FTS_APK_NODE_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_POWER_SOURCE_CUST_EN: \t%s\n",
- FTS_POWER_SOURCE_CUST_EN ? "ON" : "OFF");
- count += snprintf(buf+count, PAGE_SIZE - count,
- "FTS_AUTO_UPGRADE_EN: \t\t%s\n",
- FTS_AUTO_UPGRADE_EN ? "ON" : "OFF");
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_module_config_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_module_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
- return -EPERM;
+ return count;
}
-/************************************************************************
- * Name: fts_show_log_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_show_log_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+/* fts_upgrade_bin interface */
+static ssize_t fts_fwupgradebin_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- int count;
-
- mutex_lock(&fts_input_dev->mutex);
-
- count = snprintf(buf, PAGE_SIZE,
- "Log: %s\n", g_show_log ? "On" : "Off");
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-/************************************************************************
- * Name: fts_show_log_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_show_log_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
-
- mutex_lock(&fts_input_dev->mutex);
-
- if (FTS_SYSFS_ECHO_ON(buf)) {
- FTS_DEBUG("enable show log info/error");
- g_show_log = 1;
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- FTS_DEBUG("disable show log info/error");
- g_show_log = 0;
- }
-
- mutex_unlock(&fts_input_dev->mutex);
- return count;
-}
-/************************************************************************
- * Name: fts_dumpreg_store
- * Brief: no
- * Input: device, device attribute, char buf, char count
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_dumpreg_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
- return -EPERM;
+ return -EPERM;
}
-/************************************************************************
- * Name: fts_dumpreg_show
- * Brief: no
- * Input: device, device attribute, char buf
- * Output: no
- * Return: EPERM
- ***********************************************************************/
-static ssize_t fts_dumpreg_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t fts_fwupgradebin_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- char tmp[256];
- int count = 0;
- u8 regvalue = 0;
- struct i2c_client *client;
+ char fwname[FILE_NAME_LENGTH] = { 0 };
+ struct input_dev *input_dev = fts_data->input_dev;
- mutex_lock(&fts_input_dev->mutex);
+ if ((count <= 1) || (count >= FILE_NAME_LENGTH - 32)) {
+ FTS_ERROR("fw bin name's length(%d) fail", (int)count);
+ return -EINVAL;
+ }
+ memset(fwname, 0, sizeof(fwname));
+ snprintf(fwname, FILE_NAME_LENGTH, "%s", buf);
+ fwname[count - 1] = '\0';
+
+ FTS_INFO("upgrade with bin file through sysfs node");
+ mutex_lock(&input_dev->mutex);
+ fts_upgrade_bin(fwname, 0);
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+/* fts_force_upgrade interface */
+static ssize_t fts_fwforceupg_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return -EPERM;
+}
+
+static ssize_t fts_fwforceupg_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ char fwname[FILE_NAME_LENGTH];
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ if ((count <= 1) || (count >= FILE_NAME_LENGTH - 32)) {
+ FTS_ERROR("fw bin name's length(%d) fail", (int)count);
+ return -EINVAL;
+ }
+ memset(fwname, 0, sizeof(fwname));
+ snprintf(fwname, FILE_NAME_LENGTH, "%s", buf);
+ fwname[count - 1] = '\0';
+
+ FTS_INFO("force upgrade through sysfs node");
+ mutex_lock(&input_dev->mutex);
+ fts_upgrade_bin(fwname, 1);
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+/* fts_driver_info interface */
+static ssize_t fts_driverinfo_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct fts_ts_platform_data *pdata = ts_data->pdata;
+ struct input_dev *input_dev = ts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+ count += snprintf(buf + count, PAGE_SIZE, "Driver Ver:%s\n", FTS_DRIVER_VERSION);
+
+ count += snprintf(buf + count, PAGE_SIZE, "Resolution:(%d,%d)~(%d,%d)\n",
+ pdata->x_min, pdata->y_min, pdata->x_max, pdata->y_max);
+
+ count += snprintf(buf + count, PAGE_SIZE, "Max Touchs:%d\n", pdata->max_touch_number);
+
+ count += snprintf(buf + count, PAGE_SIZE, "reset gpio:%d,int gpio:%d,irq:%d\n",
+ pdata->reset_gpio, pdata->irq_gpio, ts_data->irq);
+
+ count += snprintf(buf + count, PAGE_SIZE, "IC ID:0x%02x%02x\n",
+ ts_data->ic_info.ids.chip_idh, ts_data->ic_info.ids.chip_idl);
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+static ssize_t fts_driverinfo_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
+
+/* fts_dump_reg interface */
+static ssize_t fts_dumpreg_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ u8 val = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(1);
+ fts_esdcheck_proc_busy(1);
#endif
- client = container_of(dev, struct i2c_client, dev);
- /* power mode 0:active 1:monitor 3:sleep */
- fts_i2c_read_reg(client, FTS_REG_POWER_MODE, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "Power Mode:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_POWER_MODE, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "Power Mode:0x%02x\n", val);
- /* FWver */
- fts_i2c_read_reg(client, FTS_REG_FW_VER, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "FW Ver:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_FW_VER, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "FW Ver:0x%02x\n", val);
- /* Vendor ID */
- fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "Vendor ID:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_LIC_VER, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "LCD Initcode Ver:0x%02x\n", val);
- /* LCD Busy number */
- fts_i2c_read_reg(client, FTS_REG_LCD_BUSY_NUM, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "LCD Busy Number:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_IDE_PARA_VER_ID, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "Param Ver:0x%02x\n", val);
- /* 1 Gesture mode,0 Normal mode */
- fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "Gesture Mode:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_IDE_PARA_STATUS, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "Param status:0x%02x\n", val);
- /* 3 charge in */
- fts_i2c_read_reg(client, FTS_REG_CHARGER_MODE_EN, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "charge stat:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_VENDOR_ID, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "Vendor ID:0x%02x\n", val);
- /* Interrupt counter */
- fts_i2c_read_reg(client, FTS_REG_INT_CNT, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "INT count:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_LCD_BUSY_NUM, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "LCD Busy Number:0x%02x\n", val);
- /* Flow work counter */
- fts_i2c_read_reg(client, FTS_REG_FLOW_WORK_CNT, ®value);
- count += snprintf(tmp + count, PAGE_SIZE - count,
- "ESD count:0x%02x\n", regvalue);
+ fts_read_reg(FTS_REG_GESTURE_EN, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "Gesture Mode:0x%02x\n", val);
+
+ fts_read_reg(FTS_REG_CHARGER_MODE_EN, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "charge stat:0x%02x\n", val);
+
+ fts_read_reg(FTS_REG_INT_CNT, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "INT count:0x%02x\n", val);
+
+ fts_read_reg(FTS_REG_FLOW_WORK_CNT, &val);
+ count += snprintf(buf + count, PAGE_SIZE, "ESD count:0x%02x\n", val);
#if FTS_ESDCHECK_EN
- fts_esdcheck_proc_busy(0);
+ fts_esdcheck_proc_busy(0);
#endif
- memcpy(buf, tmp, count);
- mutex_unlock(&fts_input_dev->mutex);
- return count;
+
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
}
-/****************************************/
-/* sysfs */
-/* get the fw version
- * example:cat fw_version
- */
-static DEVICE_ATTR(fts_fw_version, 0644,
- fts_tpfwver_show, fts_tpfwver_store);
+static ssize_t fts_dumpreg_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
-/* upgrade from *.i
- * example: echo 1 > fw_update
- */
-static DEVICE_ATTR(fts_fw_update, 0644,
- fts_fwupdate_show, fts_fwupdate_store);
+/* fts_dump_reg interface */
+static ssize_t fts_tpbuf_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ int i = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
-/* read and write register
- * read example: echo 88 > rw_reg ---read register 0x88
- * write example:echo 8807 > rw_reg ---write 0x07 into register 0x88
- *
- * note:the number of input must be 2 or 4.if it not enough,
- * please fill in the 0.
- */
-static DEVICE_ATTR(fts_rw_reg, 0644,
- fts_tprwreg_show, fts_tprwreg_store);
+ mutex_lock(&input_dev->mutex);
+ count += snprintf(buf + count, PAGE_SIZE, "touch point buffer:\n");
+ for (i = 0; i < fts_data->pnt_buf_size; i++) {
+ count += snprintf(buf + count, PAGE_SIZE, "%02x ", fts_data->point_buf[i]);
+ }
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ mutex_unlock(&input_dev->mutex);
-/* upgrade from app.bin
- * example:echo "*_app.bin" > upgrade_app
- */
-static DEVICE_ATTR(fts_upgrade_app, 0644,
- fts_fwupgradeapp_show, fts_fwupgradeapp_store);
-static DEVICE_ATTR(fts_driver_version, 0644,
- fts_driverversion_show, fts_driverversion_store);
-static DEVICE_ATTR(fts_dump_reg, 0644,
- fts_dumpreg_show, fts_dumpreg_store);
-static DEVICE_ATTR(fts_show_log, 0644,
- fts_show_log_show, fts_show_log_store);
-static DEVICE_ATTR(fts_module_config, 0644,
- fts_module_config_show, fts_module_config_store);
-static DEVICE_ATTR(fts_hw_reset, 0644,
- fts_hw_reset_show, fts_hw_reset_store);
-static DEVICE_ATTR(fts_irq, 0644,
- fts_irq_show, fts_irq_store);
+ return count;
+}
-#if FTS_ESDCHECK_EN
-static DEVICE_ATTR(fts_esd_check, 0644,
- fts_esdcheck_show, fts_esdcheck_store);
-#endif
+static ssize_t fts_tpbuf_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
+
+/* fts_log_level interface */
+static ssize_t fts_log_level_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+ count += snprintf(buf + count, PAGE_SIZE, "log level:%d\n",
+ fts_data->log_level);
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+static ssize_t fts_log_level_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
+
+ FTS_FUNC_ENTER();
+ mutex_lock(&input_dev->mutex);
+ sscanf(buf, "%d", &value);
+ FTS_DEBUG("log level:%d->%d", fts_data->log_level, value);
+ fts_data->log_level = value;
+ mutex_unlock(&input_dev->mutex);
+ FTS_FUNC_EXIT();
+
+ return count;
+}
+
+/* get the fw version example:cat fw_version */
+static DEVICE_ATTR(fts_fw_version, S_IRUGO | S_IWUSR, fts_tpfwver_show, fts_tpfwver_store);
+
+/* read and write register(s)
+* All data type is **HEX**
+* Single Byte:
+* read: echo 88 > rw_reg ---read register 0x88
+* write: echo 8807 > rw_reg ---write 0x07 into register 0x88
+* Multi-bytes:
+* [0:rw-flag][1-2: reg addr, hex][3-4: length, hex][5-6...n-n+1: write data, hex]
+* rw-flag: 0, write; 1, read
+* read: echo 10005 > rw_reg ---read reg 0x00-0x05
+* write: echo 000050102030405 > rw_reg ---write reg 0x00-0x05 as 01,02,03,04,05
+* Get result:
+* cat rw_reg
+*/
+static DEVICE_ATTR(fts_rw_reg, S_IRUGO | S_IWUSR, fts_tprwreg_show, fts_tprwreg_store);
+/* upgrade from fw bin file example:echo "*.bin" > fts_upgrade_bin */
+static DEVICE_ATTR(fts_upgrade_bin, S_IRUGO | S_IWUSR, fts_fwupgradebin_show, fts_fwupgradebin_store);
+static DEVICE_ATTR(fts_force_upgrade, S_IRUGO | S_IWUSR, fts_fwforceupg_show, fts_fwforceupg_store);
+static DEVICE_ATTR(fts_driver_info, S_IRUGO | S_IWUSR, fts_driverinfo_show, fts_driverinfo_store);
+static DEVICE_ATTR(fts_dump_reg, S_IRUGO | S_IWUSR, fts_dumpreg_show, fts_dumpreg_store);
+static DEVICE_ATTR(fts_hw_reset, S_IRUGO | S_IWUSR, fts_hw_reset_show, fts_hw_reset_store);
+static DEVICE_ATTR(fts_irq, S_IRUGO | S_IWUSR, fts_irq_show, fts_irq_store);
+static DEVICE_ATTR(fts_boot_mode, S_IRUGO | S_IWUSR, fts_bootmode_show, fts_bootmode_store);
+static DEVICE_ATTR(fts_touch_point, S_IRUGO | S_IWUSR, fts_tpbuf_show, fts_tpbuf_store);
+static DEVICE_ATTR(fts_log_level, S_IRUGO | S_IWUSR, fts_log_level_show, fts_log_level_store);
/* add your attr in here*/
static struct attribute *fts_attributes[] = {
- &dev_attr_fts_fw_version.attr,
- &dev_attr_fts_fw_update.attr,
- &dev_attr_fts_rw_reg.attr,
- &dev_attr_fts_dump_reg.attr,
- &dev_attr_fts_upgrade_app.attr,
- &dev_attr_fts_driver_version.attr,
- &dev_attr_fts_show_log.attr,
- &dev_attr_fts_module_config.attr,
- &dev_attr_fts_hw_reset.attr,
- &dev_attr_fts_irq.attr,
-#if FTS_ESDCHECK_EN
- &dev_attr_fts_esd_check.attr,
-#endif
- NULL
+ &dev_attr_fts_fw_version.attr,
+ &dev_attr_fts_rw_reg.attr,
+ &dev_attr_fts_dump_reg.attr,
+ &dev_attr_fts_upgrade_bin.attr,
+ &dev_attr_fts_force_upgrade.attr,
+ &dev_attr_fts_driver_info.attr,
+ &dev_attr_fts_hw_reset.attr,
+ &dev_attr_fts_irq.attr,
+ &dev_attr_fts_boot_mode.attr,
+ &dev_attr_fts_touch_point.attr,
+ &dev_attr_fts_log_level.attr,
+ NULL
};
static struct attribute_group fts_attribute_group = {
- .attrs = fts_attributes
+ .attrs = fts_attributes
};
-/************************************************************************
- * Name: fts_create_sysfs
- * Brief: create sysfs for debug
- * Input: i2c info
- * Output: no
- * Return: success =0
- ***********************************************************************/
-int fts_create_sysfs(struct i2c_client *client)
+int fts_create_sysfs(struct fts_ts_data *ts_data)
{
- int err;
+ int ret = 0;
- err = sysfs_create_group(&client->dev.kobj, &fts_attribute_group);
- if (err != 0) {
- FTS_ERROR("[EX]: sysfs_create_group() failed!!");
- sysfs_remove_group(&client->dev.kobj, &fts_attribute_group);
- return -EIO;
- }
+ ret = sysfs_create_group(&ts_data->dev->kobj, &fts_attribute_group);
+ if (ret) {
+ FTS_ERROR("[EX]: sysfs_create_group() failed!!");
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_attribute_group);
+ return -ENOMEM;
+ } else {
+ FTS_INFO("[EX]: sysfs_create_group() succeeded!!");
+ }
- FTS_INFO("[EX]: sysfs_create_group() succeeded!!");
-
- return err;
+ return ret;
}
-/************************************************************************
- * Name: fts_remove_sysfs
- * Brief: remove sys
- * Input: i2c info
- * Output: no
- * Return: no
- ***********************************************************************/
-int fts_remove_sysfs(struct i2c_client *client)
+
+int fts_remove_sysfs(struct fts_ts_data *ts_data)
{
- sysfs_remove_group(&client->dev.kobj, &fts_attribute_group);
- return 0;
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_attribute_group);
+ return 0;
}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
index 6e007f6..c0c970b 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
@@ -2,7 +2,7 @@
*
* FocalTech ftxxxx TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,332 +16,292 @@
*/
/*****************************************************************************
- *
- * File Name: focaltech_ex_mode.c
- *
- * Author: Liu WeiGuang
- *
- * Created: 2016-08-31
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_ex_mode.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-31
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
+* 1.Included header files
+*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
- * 2.Private constant and macro definitions using #define
- *****************************************************************************/
+* 2.Private constant and macro definitions using #define
+*****************************************************************************/
/*****************************************************************************
- * 3.Private enumerations, structures and unions using typedef
- *****************************************************************************/
-struct fts_mode_flag {
- int fts_glove_mode_flag;
- int fts_cover_mode_flag;
- int fts_charger_mode_flag;
+* 3.Private enumerations, structures and unions using typedef
+*****************************************************************************/
+enum _ex_mode {
+ MODE_GLOVE = 0,
+ MODE_COVER,
+ MODE_CHARGER,
};
-static struct fts_mode_flag g_fts_mode_flag;
+/*****************************************************************************
+* 4.Static variables
+*****************************************************************************/
/*****************************************************************************
- * 4.Static variables
- *****************************************************************************/
+* 5.Global variable or extern global variabls/functions
+*****************************************************************************/
/*****************************************************************************
- * 5.Global variable or extern global variabls/functions
- *****************************************************************************/
-
-/*****************************************************************************
- * 6.Static function prototypes
- *****************************************************************************/
-
-#if FTS_GLOVE_EN
-static ssize_t fts_touch_glove_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+* 6.Static function prototypes
+*******************************************************************************/
+static int fts_ex_mode_switch(enum _ex_mode mode, u8 value)
{
- return snprintf(buf, PAGE_SIZE, "Glove: %s\n",
- g_fts_mode_flag.fts_glove_mode_flag ? "On" : "Off");
+ int ret = 0;
+ u8 m_val = 0;
+
+ if (value)
+ m_val = 0x01;
+ else
+ m_val = 0x00;
+
+ switch (mode) {
+ case MODE_GLOVE:
+ ret = fts_write_reg(FTS_REG_GLOVE_MODE_EN, m_val);
+ if (ret < 0) {
+ FTS_ERROR("MODE_GLOVE switch to %d fail", m_val);
+ }
+ break;
+ case MODE_COVER:
+ ret = fts_write_reg(FTS_REG_COVER_MODE_EN, m_val);
+ if (ret < 0) {
+ FTS_ERROR("MODE_COVER switch to %d fail", m_val);
+ }
+ break;
+ case MODE_CHARGER:
+ ret = fts_write_reg(FTS_REG_CHARGER_MODE_EN, m_val);
+ if (ret < 0) {
+ FTS_ERROR("MODE_CHARGER switch to %d fail", m_val);
+ }
+ break;
+ default:
+ FTS_ERROR("mode(%d) unsupport", mode);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
}
-static ssize_t fts_touch_glove_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t fts_glove_mode_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- int ret;
+ int count = 0;
+ u8 val = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct input_dev *input_dev = ts_data->input_dev;
- if (FTS_SYSFS_ECHO_ON(buf)) {
- if (!g_fts_mode_flag.fts_glove_mode_flag) {
- FTS_INFO("[Mode]enter glove mode");
- ret = fts_enter_glove_mode(fts_i2c_client, true);
- if (ret >= 0)
- g_fts_mode_flag.fts_glove_mode_flag = true;
- }
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- if (g_fts_mode_flag.fts_glove_mode_flag) {
- FTS_INFO("[Mode]exit glove mode");
- ret = fts_enter_glove_mode(fts_i2c_client, false);
- if (ret >= 0)
- g_fts_mode_flag.fts_glove_mode_flag = false;
- }
- }
+ mutex_lock(&input_dev->mutex);
+ fts_read_reg(FTS_REG_GLOVE_MODE_EN, &val);
+ count = snprintf(buf + count, PAGE_SIZE, "Glove Mode:%s\n",
+ ts_data->glove_mode ? "On" : "Off");
+ count += snprintf(buf + count, PAGE_SIZE, "Glove Reg(0xC0):%d\n", val);
+ mutex_unlock(&input_dev->mutex);
- FTS_INFO("[Mode]glove mode status: %d",
- g_fts_mode_flag.fts_glove_mode_flag);
- return count;
+ return count;
}
-/************************************************************************
- * Name: fts_enter_glove_mode
- * Brief: change glove mode
- * Input: glove mode
- * Output: no
- * Return: success >=0, otherwise failed
- ***********************************************************************/
-int fts_enter_glove_mode(struct i2c_client *client, int mode)
+static ssize_t fts_glove_mode_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- int ret = 0;
- static u8 buf_addr[2] = { 0 };
- static u8 buf_value[2] = { 0 };
+ int ret = 0;
+ struct fts_ts_data *ts_data = fts_data;
- buf_addr[0] = FTS_REG_GLOVE_MODE_EN; /* glove control */
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!ts_data->glove_mode) {
+ FTS_DEBUG("enter glove mode");
+ ret = fts_ex_mode_switch(MODE_GLOVE, ENABLE);
+ if (ret >= 0) {
+ ts_data->glove_mode = ENABLE;
+ }
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (ts_data->glove_mode) {
+ FTS_DEBUG("exit glove mode");
+ ret = fts_ex_mode_switch(MODE_GLOVE, DISABLE);
+ if (ret >= 0) {
+ ts_data->glove_mode = DISABLE;
+ }
+ }
+ }
- if (mode)
- buf_value[0] = 0x01;
- else
- buf_value[0] = 0x00;
-
- ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
- if (ret < 0)
- FTS_ERROR("[Mode]fts_enter_glove_mode write value fail");
-
- return ret;
-
+ FTS_DEBUG("glove mode:%d", ts_data->glove_mode);
+ return count;
}
-/* read and write glove mode
- * read example: cat fts_touch_glove_mode---read glove mode
- * write example:echo 01 > fts_touch_glove_mode ---write glove mode to 01
- *
- */
-static DEVICE_ATTR(fts_glove_mode, 0644,
- fts_touch_glove_show, fts_touch_glove_store);
-#endif
-
-#if FTS_COVER_EN
-static ssize_t fts_touch_cover_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t fts_cover_mode_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "Cover: %s\n",
- g_fts_mode_flag.fts_cover_mode_flag ? "On" : "Off");
+ int count = 0;
+ u8 val = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct input_dev *input_dev = ts_data->input_dev;
+
+ mutex_lock(&input_dev->mutex);
+ fts_read_reg(FTS_REG_COVER_MODE_EN, &val);
+ count = snprintf(buf + count, PAGE_SIZE, "Cover Mode:%s\n",
+ ts_data->cover_mode ? "On" : "Off");
+ count += snprintf(buf + count, PAGE_SIZE, "Cover Reg(0xC1):%d\n", val);
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
}
-static ssize_t fts_touch_cover_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t fts_cover_mode_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- int ret;
+ int ret = 0;
+ struct fts_ts_data *ts_data = fts_data;
- if (FTS_SYSFS_ECHO_ON(buf)) {
- if (!g_fts_mode_flag.fts_cover_mode_flag) {
- FTS_INFO("[Mode]enter cover mode");
- ret = fts_enter_cover_mode(fts_i2c_client, true);
- if (ret >= 0)
- g_fts_mode_flag.fts_cover_mode_flag = true;
- }
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- if (g_fts_mode_flag.fts_cover_mode_flag) {
- FTS_INFO("[Mode]exit cover mode");
- ret = fts_enter_cover_mode(fts_i2c_client, false);
- if (ret >= 0)
- g_fts_mode_flag.fts_cover_mode_flag = false;
- }
- }
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!ts_data->cover_mode) {
+ FTS_DEBUG("enter cover mode");
+ ret = fts_ex_mode_switch(MODE_COVER, ENABLE);
+ if (ret >= 0) {
+ ts_data->cover_mode = ENABLE;
+ }
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (ts_data->cover_mode) {
+ FTS_DEBUG("exit cover mode");
+ ret = fts_ex_mode_switch(MODE_COVER, DISABLE);
+ if (ret >= 0) {
+ ts_data->cover_mode = DISABLE;
+ }
+ }
+ }
- FTS_INFO("[Mode]cover mode status: %d",
- g_fts_mode_flag.fts_cover_mode_flag);
- return count;
+ FTS_DEBUG("cover mode:%d", ts_data->cover_mode);
+ return count;
}
-/************************************************************************
- * Name: fts_enter_cover_mode
- * Brief: change cover mode
- * Input: cover mode
- * Output: no
- * Return: success >=0, otherwise failed
- ***********************************************************************/
-int fts_enter_cover_mode(struct i2c_client *client, int mode)
+static ssize_t fts_charger_mode_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
{
- int ret = 0;
- static u8 buf_addr[2] = { 0 };
- static u8 buf_value[2] = { 0 };
+ int count = 0;
+ u8 val = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct input_dev *input_dev = ts_data->input_dev;
- buf_addr[0] = FTS_REG_COVER_MODE_EN; /* cover control */
+ mutex_lock(&input_dev->mutex);
+ fts_read_reg(FTS_REG_CHARGER_MODE_EN, &val);
+ count = snprintf(buf + count, PAGE_SIZE, "Charger Mode:%s\n",
+ ts_data->charger_mode ? "On" : "Off");
+ count += snprintf(buf + count, PAGE_SIZE, "Charger Reg(0x8B):%d\n", val);
+ mutex_unlock(&input_dev->mutex);
- if (mode)
- buf_value[0] = 0x01;
- else
- buf_value[0] = 0x00;
-
- ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
- if (ret < 0)
- FTS_ERROR("[Mode] fts_enter_cover_mode write value fail\n");
-
- return ret;
-
+ return count;
}
-/* read and write cover mode
- * read example: cat fts_touch_cover_mode---read cover mode
- * write example:echo 01 > fts_touch_cover_mode ---write cover mode to 01
- *
- */
-static DEVICE_ATTR(fts_cover_mode, 0644,
- fts_touch_cover_show, fts_touch_cover_store);
-
-#endif
-
-#if FTS_CHARGER_EN
-static ssize_t fts_touch_charger_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t fts_charger_mode_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- return snprintf(buf, PAGE_SIZE, "Charger: %s\n",
- g_fts_mode_flag.fts_charger_mode_flag ? "On" : "Off");
+ int ret = 0;
+ struct fts_ts_data *ts_data = fts_data;
+
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ if (!ts_data->charger_mode) {
+ FTS_DEBUG("enter charger mode");
+ ret = fts_ex_mode_switch(MODE_CHARGER, ENABLE);
+ if (ret >= 0) {
+ ts_data->charger_mode = ENABLE;
+ }
+ }
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ if (ts_data->charger_mode) {
+ FTS_DEBUG("exit charger mode");
+ ret = fts_ex_mode_switch(MODE_CHARGER, DISABLE);
+ if (ret >= 0) {
+ ts_data->charger_mode = DISABLE;
+ }
+ }
+ }
+
+ FTS_DEBUG("charger mode:%d", ts_data->glove_mode);
+ return count;
}
-static ssize_t fts_touch_charger_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int ret;
-
- if (FTS_SYSFS_ECHO_ON(buf)) {
- if (!g_fts_mode_flag.fts_charger_mode_flag) {
- FTS_INFO("[Mode]enter charger mode");
- ret = fts_enter_charger_mode(fts_i2c_client, true);
- if (ret >= 0)
- g_fts_mode_flag.fts_charger_mode_flag = true;
- }
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- if (g_fts_mode_flag.fts_charger_mode_flag) {
- FTS_INFO("[Mode]exit charger mode");
- ret = fts_enter_charger_mode(fts_i2c_client, false);
- if (ret >= 0)
- g_fts_mode_flag.fts_charger_mode_flag = false;
- }
- }
-
- FTS_INFO("[Mode]charger mode status: %d",
- g_fts_mode_flag.fts_charger_mode_flag);
- return count;
-}
-
-/************************************************************************
- * Name: fts_enter_charger_mode
- * Brief: change charger mode
- * Input: charger mode
- * Output: no
- * Return: success >=0, otherwise failed
- ***********************************************************************/
-int fts_enter_charger_mode(struct i2c_client *client, int mode)
-{
- int ret = 0;
- static u8 buf_addr[2] = { 0 };
- static u8 buf_value[2] = { 0 };
-
- buf_addr[0] = FTS_REG_CHARGER_MODE_EN; /* charger control */
-
- if (mode)
- buf_value[0] = 0x01;
- else
- buf_value[0] = 0x00;
-
- ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
- if (ret < 0)
- FTS_DEBUG("[Mode]fts_enter_charger_mode write value fail");
-
- return ret;
-
-}
/* read and write charger mode
- * read example: cat fts_touch_charger_mode---read charger mode
- * write example:echo 01 > fts_touch_charger_mode ---write charger mode to 01
- *
+ * read example: cat fts_glove_mode ---read glove mode
+ * write example:echo 1 > fts_glove_mode ---write glove mode to 01
*/
-static DEVICE_ATTR(fts_charger_mode, 0644,
- fts_touch_charger_show, fts_touch_charger_store);
+static DEVICE_ATTR(fts_glove_mode, S_IRUGO | S_IWUSR,
+ fts_glove_mode_show, fts_glove_mode_store);
-#endif
+static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR,
+ fts_cover_mode_show, fts_cover_mode_store);
+
+static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR,
+ fts_charger_mode_show, fts_charger_mode_store);
static struct attribute *fts_touch_mode_attrs[] = {
-#if FTS_GLOVE_EN
- &dev_attr_fts_glove_mode.attr,
-#endif
-
-#if FTS_COVER_EN
- &dev_attr_fts_cover_mode.attr,
-#endif
-
-#if FTS_CHARGER_EN
- &dev_attr_fts_charger_mode.attr,
-#endif
-
- NULL,
+ &dev_attr_fts_glove_mode.attr,
+ &dev_attr_fts_cover_mode.attr,
+ &dev_attr_fts_charger_mode.attr,
+ NULL,
};
static struct attribute_group fts_touch_mode_group = {
- .attrs = fts_touch_mode_attrs,
+ .attrs = fts_touch_mode_attrs,
};
-int fts_ex_mode_init(struct i2c_client *client)
+int fts_ex_mode_recovery(struct fts_ts_data *ts_data)
{
- int err = 0;
+ if (ts_data->glove_mode) {
+ fts_ex_mode_switch(MODE_GLOVE, ENABLE);
+ }
- g_fts_mode_flag.fts_glove_mode_flag = false;
- g_fts_mode_flag.fts_cover_mode_flag = false;
- g_fts_mode_flag.fts_charger_mode_flag = false;
+ if (ts_data->cover_mode) {
+ fts_ex_mode_switch(MODE_COVER, ENABLE);
+ }
- err = sysfs_create_group(&client->dev.kobj, &fts_touch_mode_group);
- if (err != 0) {
- FTS_ERROR("[Mode]create sysfs failed.");
- sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
- return -EIO;
- }
+ if (ts_data->charger_mode) {
+ fts_ex_mode_switch(MODE_CHARGER, ENABLE);
+ }
- FTS_DEBUG("[Mode]create sysfs succeeded");
-
- return err;
-
+ return 0;
}
-int fts_ex_mode_exit(struct i2c_client *client)
+int fts_ex_mode_init(struct fts_ts_data *ts_data)
{
- sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
- return 0;
+ int ret = 0;
+
+ ts_data->glove_mode = DISABLE;
+ ts_data->cover_mode = DISABLE;
+ ts_data->charger_mode = DISABLE;
+
+ ret = sysfs_create_group(&ts_data->dev->kobj, &fts_touch_mode_group);
+ if (ret < 0) {
+ FTS_ERROR("create sysfs(ex_mode) fail");
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
+ return ret;
+ } else {
+ FTS_DEBUG("create sysfs(ex_mode) succeedfully");
+ }
+
+ return 0;
}
-int fts_ex_mode_recovery(struct i2c_client *client)
+int fts_ex_mode_exit(struct fts_ts_data *ts_data)
{
- int ret = 0;
-#if FTS_GLOVE_EN
- if (g_fts_mode_flag.fts_glove_mode_flag)
- ret = fts_enter_glove_mode(client, true);
-#endif
-
-#if FTS_COVER_EN
- if (g_fts_mode_flag.fts_cover_mode_flag)
- ret = fts_enter_cover_mode(client, true);
-#endif
-
-#if FTS_CHARGER_EN
- if (g_fts_mode_flag.fts_charger_mode_flag)
- ret = fts_enter_charger_mode(client, true);
-#endif
-
- return ret;
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
+ return 0;
}
-
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash.c
index 7b54a1c..67b04fa 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash.c
@@ -2,7 +2,7 @@
*
* FocalTech fts TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,659 +16,1996 @@
*/
/*****************************************************************************
- *
- * File Name: focaltech_flash.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-08
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_flash.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
+* 1.Included header files
+*****************************************************************************/
#include "focaltech_core.h"
#include "focaltech_flash.h"
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-struct ft_chip_t chip_types;
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_FW_REQUEST_SUPPORT 1
+/* Example: focaltech_ts_fw_tianma.bin */
+#define FTS_FW_NAME_PREX_WITH_REQUEST "focaltech_ts_fw_"
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-/* Upgrade FW/PRAMBOOT/LCD CFG */
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
-u8 CTPM_FW[] = {
-#include FTS_UPGRADE_FW_APP
-};
-#endif
-
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
-u8 CTPM_FW2[] = {
-#include FTS_UPGRADE_FW2_APP
-};
-#endif
-
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
-u8 CTPM_FW3[] = {
-#include FTS_UPGRADE_FW3_APP
-};
-#endif
-
-u8 aucFW_PRAM_BOOT[] = {
-#ifdef FTS_UPGRADE_PRAMBOOT
-#include FTS_UPGRADE_PRAMBOOT
-#endif
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+u8 fw_file[] = {
+#include FTS_UPGRADE_FW_FILE
};
-#if (FTS_CHIP_TYPE == _FT8006)
-u8 CTPM_LCD_CFG[] = {
-#ifdef FTS_UPGRADE_LCD_CFG
-#include FTS_UPGRADE_LCD_CFG
-#endif
+u8 fw_file2[] = {
+#include FTS_UPGRADE_FW2_FILE
};
-#endif
-struct fts_upgrade_fun fts_updatefun_curr;
-struct workqueue_struct *touch_wq;
-struct work_struct fw_update_work;
-u8 *g_fw_file;
-int g_fw_len;
+u8 fw_file3[] = {
+#include FTS_UPGRADE_FW3_FILE
+};
+
+struct upgrade_module module_list[] = {
+ {FTS_MODULE_ID, FTS_MODULE_NAME, fw_file, sizeof(fw_file)},
+ {FTS_MODULE2_ID, FTS_MODULE2_NAME, fw_file2, sizeof(fw_file2)},
+ {FTS_MODULE3_ID, FTS_MODULE3_NAME, fw_file3, sizeof(fw_file3)},
+};
+
+struct upgrade_func *upgrade_func_list[] = {
+ &upgrade_func_ft5452,
+};
+
+struct fts_upgrade *fwupgrade;
+
/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
+* Static function prototypes
+*****************************************************************************/
+static bool fts_fwupg_check_state(
+ struct fts_upgrade *upg, enum FW_STATUS rstate);
/************************************************************************
- * Name: fts_ctpm_upgrade_delay
- * Brief: 0
- * Input: 0
- * Output: 0
- * Return: 0
- ***********************************************************************/
-void fts_ctpm_upgrade_delay(u32 i)
+* Name: fts_fwupg_get_boot_state
+* Brief: read boot id(rom/pram/bootloader), confirm boot environment
+* Input:
+* Output:
+* Return: return 0 if success, otherwise return error code
+***********************************************************************/
+static int fts_fwupg_get_boot_state(
+ struct fts_upgrade *upg,
+ enum FW_STATUS *fw_sts)
{
- do {
- i--;
- } while (i > 0);
+ int ret = 0;
+ u8 cmd[4] = { 0 };
+ u32 cmd_len = 0;
+ u8 val[2] = { 0 };
+ struct ft_chip_t *ids = NULL;
+
+ FTS_INFO("**********read boot id**********");
+ if ((!upg) || (!upg->func) || (!upg->ts_data) || (!fw_sts)) {
+ FTS_ERROR("upg/func/ts_data/fw_sts is null");
+ return -EINVAL;
+ }
+
+ if (upg->func->hid_supported)
+ fts_hid2std();
+
+ cmd[0] = FTS_CMD_START1;
+ cmd[1] = FTS_CMD_START2;
+ ret = fts_write(cmd, 2);
+ if (ret < 0) {
+ FTS_ERROR("write 55 aa cmd fail");
+ return ret;
+ }
+
+ msleep(FTS_CMD_START_DELAY);
+ cmd[0] = FTS_CMD_READ_ID;
+ cmd[1] = cmd[2] = cmd[3] = 0x00;
+ if (fts_data->ic_info.is_incell)
+ cmd_len = FTS_CMD_READ_ID_LEN_INCELL;
+ else
+ cmd_len = FTS_CMD_READ_ID_LEN;
+ ret = fts_read(cmd, cmd_len, val, 2);
+ if (ret < 0) {
+ FTS_ERROR("write 90 cmd fail");
+ return ret;
+ }
+ FTS_INFO("read boot id:0x%02x%02x", val[0], val[1]);
+
+ ids = &upg->ts_data->ic_info.ids;
+ if ((val[0] == ids->rom_idh) && (val[1] == ids->rom_idl)) {
+ FTS_INFO("tp run in romboot");
+ *fw_sts = FTS_RUN_IN_ROM;
+ } else if ((val[0] == ids->pb_idh) && (val[1] == ids->pb_idl)) {
+ FTS_INFO("tp run in pramboot");
+ *fw_sts = FTS_RUN_IN_PRAM;
+ } else if ((val[0] == ids->bl_idh) && (val[1] == ids->bl_idl)) {
+ FTS_INFO("tp run in bootloader");
+ *fw_sts = FTS_RUN_IN_BOOTLOADER;
+ }
+
+ return 0;
+}
+
+static int fts_fwupg_reset_to_boot(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ u8 reg = FTS_REG_UPGRADE;
+
+ FTS_INFO("send 0xAA and 0x55 to FW, reset to boot environment");
+ if (upg && upg->func && upg->func->is_reset_register_BC) {
+ reg = FTS_REG_UPGRADE2;
+ }
+
+ ret = fts_write_reg(reg, FTS_UPGRADE_AA);
+ if (ret < 0) {
+ FTS_ERROR("write FC=0xAA fail");
+ return ret;
+ }
+ msleep(FTS_DELAY_UPGRADE_AA);
+
+ ret = fts_write_reg(reg, FTS_UPGRADE_55);
+ if (ret < 0) {
+ FTS_ERROR("write FC=0x55 fail");
+ return ret;
+ }
+
+ msleep(FTS_DELAY_UPGRADE_RESET);
+ return 0;
}
/************************************************************************
- * Name: fts_ctpm_i2c_hid2std
- * Brief: HID to I2C
- * Input: i2c info
- * Output: no
- * Return: fail =0
- ***********************************************************************/
-int fts_ctpm_i2c_hid2std(struct i2c_client *client)
+* Name: fts_fwupg_reset_to_romboot
+* Brief: reset to romboot, to load pramboot
+* Input:
+* Output:
+* Return: return 0 if success, otherwise return error code
+***********************************************************************/
+static int fts_fwupg_reset_to_romboot(struct fts_upgrade *upg)
{
-#if (FTS_CHIP_IDC)
- return 0;
-#else
- u8 buf[5] = {0};
- int bRet = 0;
+ int ret = 0;
+ int i = 0;
+ u8 cmd = FTS_CMD_RESET;
+ enum FW_STATUS state = FTS_RUN_IN_ERROR;
- buf[0] = 0xeb;
- buf[1] = 0xaa;
- buf[2] = 0x09;
- bRet = fts_i2c_write(client, buf, 3);
- msleep(20);
- buf[0] = buf[1] = buf[2] = 0;
- fts_i2c_read(client, buf, 0, buf, 3);
+ ret = fts_write(&cmd, 1);
+ if (ret < 0) {
+ FTS_ERROR("pram/rom/bootloader reset cmd write fail");
+ return ret;
+ }
+ mdelay(10);
- if ((buf[0] == 0xeb) && (buf[1] == 0xaa) && (buf[2] == 0x08)) {
- FTS_DEBUG("hidi2c change to stdi2c successful!!");
- bRet = 1;
- } else {
- FTS_ERROR("hidi2c change to stdi2c error!!");
- bRet = 0;
- }
+ for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
+ ret = fts_fwupg_get_boot_state(upg, &state);
+ if (FTS_RUN_IN_ROM == state)
+ break;
+ mdelay(5);
+ }
+ if (i >= FTS_UPGRADE_LOOP) {
+ FTS_ERROR("reset to romboot fail");
+ return -EIO;
+ }
- return bRet;
-#endif
+ return 0;
+}
+
+static u16 fts_crc16_calc_host(u8 *pbuf, u16 length)
+{
+ u16 ecc = 0;
+ u16 i = 0;
+ u16 j = 0;
+
+ for ( i = 0; i < length; i += 2 ) {
+ ecc ^= ((pbuf[i] << 8) | (pbuf[i + 1]));
+ for (j = 0; j < 16; j ++) {
+ if (ecc & 0x01)
+ ecc = (u16)((ecc >> 1) ^ AL2_FCS_COEF);
+ else
+ ecc >>= 1;
+ }
+ }
+
+ return ecc;
+}
+
+static u16 fts_pram_ecc_calc_host(u8 *pbuf, u16 length)
+{
+ return fts_crc16_calc_host(pbuf, length);
+}
+
+static int fts_pram_ecc_cal_algo(
+ struct fts_upgrade *upg,
+ u32 start_addr,
+ u32 ecc_length)
+{
+ int ret = 0;
+ int i = 0;
+ int ecc = 0;
+ u8 val[2] = { 0 };
+ u8 tmp = 0;
+ u8 cmd[FTS_ROMBOOT_CMD_ECC_NEW_LEN] = { 0 };
+
+ FTS_INFO("read out pramboot checksum");
+ if ((!upg) || (!upg->func)) {
+ FTS_ERROR("upg/func is null");
+ return -EINVAL;
+ }
+
+ cmd[0] = FTS_ROMBOOT_CMD_ECC;
+ cmd[1] = BYTE_OFF_16(start_addr);
+ cmd[2] = BYTE_OFF_8(start_addr);
+ cmd[3] = BYTE_OFF_0(start_addr);
+ cmd[4] = BYTE_OFF_16(ecc_length);
+ cmd[5] = BYTE_OFF_8(ecc_length);
+ cmd[6] = BYTE_OFF_0(ecc_length);
+ ret = fts_write(cmd, FTS_ROMBOOT_CMD_ECC_NEW_LEN);
+ if (ret < 0) {
+ FTS_ERROR("write pramboot ecc cal cmd fail");
+ return ret;
+ }
+
+ cmd[0] = FTS_ROMBOOT_CMD_ECC_FINISH;
+ for (i = 0; i < FTS_ECC_FINISH_TIMEOUT; i++) {
+ msleep(1);
+ ret = fts_read(cmd, 1, val, 1);
+ if (ret < 0) {
+ FTS_ERROR("ecc_finish read cmd fail");
+ return ret;
+ }
+ if (upg->func->new_return_value_from_ic) {
+ tmp = FTS_ROMBOOT_CMD_ECC_FINISH_OK_A5;
+ } else {
+ tmp = FTS_ROMBOOT_CMD_ECC_FINISH_OK_00;
+ }
+ if (tmp == val[0])
+ break;
+ }
+ if (i >= 100) {
+ FTS_ERROR("wait ecc finish fail");
+ return -EIO;
+ }
+
+ cmd[0] = FTS_ROMBOOT_CMD_ECC_READ;
+ ret = fts_read(cmd, 1, val, 2);
+ if (ret < 0) {
+ FTS_ERROR("read pramboot ecc fail");
+ return ret;
+ }
+
+ ecc = ((u16)(val[0] << 8) + val[1]) & 0x0000FFFF;
+ return ecc;
+}
+
+static int fts_pram_ecc_cal_xor(void)
+{
+ int ret = 0;
+ u8 reg_val = 0;
+
+ FTS_INFO("read out pramboot checksum");
+
+ ret = fts_read_reg(FTS_ROMBOOT_CMD_ECC, ®_val);
+ if (ret < 0) {
+ FTS_ERROR("read pramboot ecc fail");
+ return ret;
+ }
+
+ return (int)reg_val;
+}
+
+static int fts_pram_ecc_cal(struct fts_upgrade *upg, u32 saddr, u32 len)
+{
+ if ((!upg) || (!upg->func)) {
+ FTS_ERROR("upg/func is null");
+ return -EINVAL;
+ }
+
+ if (ECC_CHECK_MODE_CRC16 == upg->func->pram_ecc_check_mode) {
+ return fts_pram_ecc_cal_algo(upg, saddr, len);
+ } else {
+ return fts_pram_ecc_cal_xor();
+ }
+}
+
+static int fts_pram_write_buf(struct fts_upgrade *upg, u8 *buf, u32 len)
+{
+ int ret = 0;
+ u32 i = 0;
+ u32 j = 0;
+ u32 offset = 0;
+ u32 remainder = 0;
+ u32 packet_number;
+ u32 packet_len = 0;
+ u8 packet_buf[FTS_FLASH_PACKET_LENGTH + FTS_CMD_WRITE_LEN] = { 0 };
+ u8 ecc_tmp = 0;
+ int ecc_in_host = 0;
+
+ FTS_INFO("write pramboot to pram");
+ if ((!upg) || (!upg->func) || !buf) {
+ FTS_ERROR("upg/func/buf is null");
+ return -EINVAL;
+ }
+
+ FTS_INFO("pramboot len=%d", len);
+ if ((len < PRAMBOOT_MIN_SIZE) || (len > PRAMBOOT_MAX_SIZE)) {
+ FTS_ERROR("pramboot length(%d) fail", len);
+ return -EINVAL;
+ }
+
+ packet_number = len / FTS_FLASH_PACKET_LENGTH;
+ remainder = len % FTS_FLASH_PACKET_LENGTH;
+ if (remainder > 0)
+ packet_number++;
+ packet_len = FTS_FLASH_PACKET_LENGTH;
+
+ packet_buf[0] = FTS_ROMBOOT_CMD_WRITE;
+ for (i = 0; i < packet_number; i++) {
+ offset = i * FTS_FLASH_PACKET_LENGTH;
+ packet_buf[1] = BYTE_OFF_16(offset);
+ packet_buf[2] = BYTE_OFF_8(offset);
+ packet_buf[3] = BYTE_OFF_0(offset);
+
+ /* last packet */
+ if ((i == (packet_number - 1)) && remainder)
+ packet_len = remainder;
+
+ packet_buf[4] = BYTE_OFF_8(packet_len);
+ packet_buf[5] = BYTE_OFF_0(packet_len);
+
+ for (j = 0; j < packet_len; j++) {
+ packet_buf[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
+ if (ECC_CHECK_MODE_XOR == upg->func->pram_ecc_check_mode) {
+ ecc_tmp ^= packet_buf[FTS_CMD_WRITE_LEN + j];
+ }
+ }
+
+ ret = fts_write(packet_buf, packet_len + FTS_CMD_WRITE_LEN);
+ if (ret < 0) {
+ FTS_ERROR("pramboot write data(%d) fail", i);
+ return ret;
+ }
+ }
+
+ if (ECC_CHECK_MODE_CRC16 == upg->func->pram_ecc_check_mode) {
+ ecc_in_host = (int)fts_pram_ecc_calc_host(buf, len);
+ } else {
+ ecc_in_host = (int)ecc_tmp;
+ }
+
+ return ecc_in_host;
+}
+
+static int fts_pram_start(void)
+{
+ u8 cmd = FTS_ROMBOOT_CMD_START_APP;
+ int ret = 0;
+
+ FTS_INFO("remap to start pramboot");
+
+ ret = fts_write(&cmd, 1);
+ if (ret < 0) {
+ FTS_ERROR("write start pram cmd fail");
+ return ret;
+ }
+ msleep(FTS_DELAY_PRAMBOOT_START);
+
+ return 0;
+}
+
+static int fts_pram_write_remap(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ int ecc_in_host = 0;
+ int ecc_in_tp = 0;
+ u8 *pb_buf = NULL;
+ u32 pb_len = 0;
+
+ FTS_INFO("write pram and remap");
+ if (!upg || !upg->func || !upg->func->pramboot) {
+ FTS_ERROR("upg/func/pramboot is null");
+ return -EINVAL;
+ }
+
+ if (upg->func->pb_length < FTS_MIN_LEN) {
+ FTS_ERROR("pramboot length(%d) fail", upg->func->pb_length);
+ return -EINVAL;
+ }
+
+ pb_buf = upg->func->pramboot;
+ pb_len = upg->func->pb_length;
+
+ /* write pramboot to pram */
+ ecc_in_host = fts_pram_write_buf(upg, pb_buf, pb_len);
+ if (ecc_in_host < 0) {
+ FTS_ERROR( "write pramboot fail");
+ return ecc_in_host;
+ }
+
+ /* read out checksum */
+ ecc_in_tp = fts_pram_ecc_cal(upg, 0, pb_len);
+ if (ecc_in_tp < 0) {
+ FTS_ERROR( "read pramboot ecc fail");
+ return ecc_in_tp;
+ }
+
+ FTS_INFO("pram ecc in tp:%x, host:%x", ecc_in_tp, ecc_in_host);
+ /* pramboot checksum != fw checksum, upgrade fail */
+ if (ecc_in_host != ecc_in_tp) {
+ FTS_ERROR("pramboot ecc check fail");
+ return -EIO;
+ }
+
+ /*start pram*/
+ ret = fts_pram_start();
+ if (ret < 0) {
+ FTS_ERROR("pram start fail");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fts_pram_init(void)
+{
+ int ret = 0;
+ u8 reg_val = 0;
+ u8 wbuf[3] = { 0 };
+
+ FTS_INFO("pramboot initialization");
+
+ /* read flash ID */
+ wbuf[0] = FTS_CMD_FLASH_TYPE;
+ ret = fts_read(wbuf, 1, ®_val, 1);
+ if (ret < 0) {
+ FTS_ERROR("read flash type fail");
+ return ret;
+ }
+
+ /* set flash clk */
+ wbuf[0] = FTS_CMD_FLASH_TYPE;
+ wbuf[1] = reg_val;
+ wbuf[2] = 0x00;
+ ret = fts_write(wbuf, 3);
+ if (ret < 0) {
+ FTS_ERROR("write flash type fail");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fts_pram_write_init(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ bool state = 0;
+ enum FW_STATUS status = FTS_RUN_IN_ERROR;
+
+ FTS_INFO("**********pram write and init**********");
+ if ((NULL == upg) || (NULL == upg->func)) {
+ FTS_ERROR("upgrade/func is null");
+ return -EINVAL;
+ }
+
+ if (!upg->func->pramboot_supported) {
+ FTS_ERROR("ic not support pram");
+ return -EINVAL;
+ }
+
+ FTS_DEBUG("check whether tp is in romboot or not ");
+ /* need reset to romboot when non-romboot state */
+ ret = fts_fwupg_get_boot_state(upg, &status);
+ if (status != FTS_RUN_IN_ROM) {
+ if (FTS_RUN_IN_PRAM == status) {
+ FTS_INFO("tp is in pramboot, need send reset cmd before upgrade");
+ ret = fts_pram_init();
+ if (ret < 0) {
+ FTS_ERROR("pramboot(before) init fail");
+ return ret;
+ }
+ }
+
+ FTS_INFO("tp isn't in romboot, need send reset to romboot");
+ ret = fts_fwupg_reset_to_romboot(upg);
+ if (ret < 0) {
+ FTS_ERROR("reset to romboot fail");
+ return ret;
+ }
+ }
+
+ /* check the length of the pramboot */
+ ret = fts_pram_write_remap(upg);
+ if (ret < 0) {
+ FTS_ERROR("pram write fail, ret=%d", ret);
+ return ret;
+ }
+
+ FTS_DEBUG("after write pramboot, confirm run in pramboot");
+ state = fts_fwupg_check_state(upg, FTS_RUN_IN_PRAM);
+ if (!state) {
+ FTS_ERROR("not in pramboot");
+ return -EIO;
+ }
+
+ ret = fts_pram_init();
+ if (ret < 0) {
+ FTS_ERROR("pramboot init fail");
+ return ret;
+ }
+
+ return 0;
+}
+
+static bool fts_fwupg_check_fw_valid(void)
+{
+ int ret = 0;
+
+ ret = fts_wait_tp_to_valid();
+ if (ret < 0) {
+ FTS_INFO("tp fw invaild");
+ return false;
+ }
+
+ FTS_INFO("tp fw vaild");
+ return true;
}
/************************************************************************
- * Name: fts_get_chip_types
- * Brief: get correct chip information
- * Input:
+* Name: fts_fwupg_check_state
+* Brief: confirm tp run in which mode: romboot/pramboot/bootloader
+* Input:
+* Output:
+* Return: return true if state is match, otherwise return false
+***********************************************************************/
+static bool fts_fwupg_check_state(
+ struct fts_upgrade *upg, enum FW_STATUS rstate)
+{
+ int ret = 0;
+ int i = 0;
+ enum FW_STATUS cstate = FTS_RUN_IN_ERROR;
+
+ for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
+ ret = fts_fwupg_get_boot_state(upg, &cstate);
+ /* FTS_DEBUG("fw state=%d, retries=%d", cstate, i); */
+ if (cstate == rstate)
+ return true;
+ msleep(FTS_DELAY_READ_ID);
+ }
+
+ return false;
+}
+
+/************************************************************************
+* Name: fts_fwupg_reset_in_boot
+* Brief: RST CMD(07), reset to romboot(bootloader) in boot environment
+* Input:
+* Output:
+* Return: return 0 if success, otherwise return error code
+***********************************************************************/
+int fts_fwupg_reset_in_boot(void)
+{
+ int ret = 0;
+ u8 cmd = FTS_CMD_RESET;
+
+ FTS_INFO("reset in boot environment");
+ ret = fts_write(&cmd, 1);
+ if (ret < 0) {
+ FTS_ERROR("pram/rom/bootloader reset cmd write fail");
+ return ret;
+ }
+
+ msleep(FTS_DELAY_UPGRADE_RESET);
+ return 0;
+}
+
+/************************************************************************
+* Name: fts_fwupg_enter_into_boot
+* Brief: enter into boot environment, ready for upgrade
+* Input:
+* Output:
+* Return: return 0 if success, otherwise return error code
+***********************************************************************/
+int fts_fwupg_enter_into_boot(void)
+{
+ int ret = 0;
+ bool fwvalid = false;
+ bool state = false;
+ struct fts_upgrade *upg = fwupgrade;
+
+ FTS_INFO("***********enter into pramboot/bootloader***********");
+ if ((!upg) || (NULL == upg->func)) {
+ FTS_ERROR("upgrade/func is null");
+ return -EINVAL;
+ }
+
+ fwvalid = fts_fwupg_check_fw_valid();
+ if (fwvalid) {
+ ret = fts_fwupg_reset_to_boot(upg);
+ if (ret < 0) {
+ FTS_ERROR("enter into romboot/bootloader fail");
+ return ret;
+ }
+ } else if (upg->func->read_boot_id_need_reset) {
+ ret = fts_fwupg_reset_in_boot();
+ if (ret < 0) {
+ FTS_ERROR("reset before read boot id when fw invalid fail");
+ return ret;
+ }
+ }
+
+ if (upg->func->pramboot_supported) {
+ FTS_INFO("pram supported, write pramboot and init");
+ /* pramboot */
+ ret = fts_pram_write_init(upg);
+ if (ret < 0) {
+ FTS_ERROR("pram write_init fail");
+ return ret;
+ }
+ } else {
+ FTS_DEBUG("pram not supported, confirm in bootloader");
+ /* bootloader */
+ state = fts_fwupg_check_state(upg, FTS_RUN_IN_BOOTLOADER);
+ if (!state) {
+ FTS_ERROR("fw not in bootloader, fail");
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+/************************************************************************
+ * Name: fts_fwupg_check_flash_status
+ * Brief: read status from tp
+ * Input: flash_status: correct value from tp
+ * retries: read retry times
+ * retries_delay: retry delay
* Output:
- * Return:
- ***********************************************************************/
-static void fts_get_chip_types(void)
+ * Return: return true if flash status check pass, otherwise return false
+***********************************************************************/
+static bool fts_fwupg_check_flash_status(
+ u16 flash_status,
+ int retries,
+ int retries_delay)
{
- struct ft_chip_t ctype[] = FTS_CHIP_TYPE_MAPPING;
- int ic_type = 0;
+ int ret = 0;
+ int i = 0;
+ u8 cmd = 0;
+ u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
+ u16 read_status = 0;
- if (sizeof(ctype) != sizeof(struct ft_chip_t)) /* only one array */
- ic_type = IC_SERIALS - 1;
+ for (i = 0; i < retries; i++) {
+ cmd = FTS_CMD_FLASH_STATUS;
+ ret = fts_read(&cmd , 1, val, FTS_CMD_FLASH_STATUS_LEN);
+ read_status = (((u16)val[0]) << 8) + val[1];
+ if (flash_status == read_status) {
+ /* FTS_DEBUG("[UPGRADE]flash status ok"); */
+ return true;
+ }
+ /* FTS_DEBUG("flash status fail,ok:%04x read:%04x, retries:%d", flash_status, read_status, i); */
+ msleep(retries_delay);
+ }
- chip_types = ctype[ic_type];
-
- FTS_INFO("CHIP TYPE ID = 0x%02x%02x",
- chip_types.chip_idh, chip_types.chip_idl);
+ return false;
}
/************************************************************************
- * Name: fts_ctpm_get_upgrade_array
- * Brief: decide which ic
- * Input: no
- * Output: get ic info in fts_updateinfo_curr
- * Return: no
- ***********************************************************************/
-void fts_ctpm_get_upgrade_array(void)
-{
-
- FTS_FUNC_ENTER();
-
- fts_get_chip_types();
-
- fts_ctpm_i2c_hid2std(fts_i2c_client);
-
- /* Get functin pointer */
- memcpy(&fts_updatefun_curr, &fts_updatefun,
- sizeof(struct fts_upgrade_fun));
-
- FTS_FUNC_EXIT();
-}
-
-/************************************************************************
- * Name: fts_ctpm_rom_or_pram_reset
- * Brief: RST CMD(07), reset to romboot(maybe->bootloader)
- * Input:
+ * Name: fts_fwupg_erase
+ * Brief: erase flash area
+ * Input: delay - delay after erase
* Output:
- * Return:
+ * Return: return 0 if success, otherwise return error code
***********************************************************************/
-void fts_ctpm_rom_or_pram_reset(struct i2c_client *client)
+int fts_fwupg_erase(u32 delay)
{
- u8 rst_cmd = FTS_REG_RESET_FW;
+ int ret = 0;
+ u8 cmd = 0;
+ bool flag = false;
- FTS_INFO("[UPGRADE]******Reset to romboot/bootloader******");
- fts_i2c_write(client, &rst_cmd, 1);
- /* The delay can't be changed */
- msleep(300);
+ FTS_INFO("**********erase now**********");
+
+ /*send to erase flash*/
+ cmd = FTS_CMD_ERASE_APP;
+ ret = fts_write(&cmd, 1);
+ if (ret < 0) {
+ FTS_ERROR("erase cmd fail");
+ return ret;
+ }
+ msleep(delay);
+
+ /* read status 0xF0AA: success */
+ flag = fts_fwupg_check_flash_status(FTS_CMD_FLASH_STATUS_ERASE_OK,
+ FTS_RETRIES_REASE,
+ FTS_RETRIES_DELAY_REASE);
+ if (!flag) {
+ FTS_ERROR("ecc flash status check fail");
+ return -EIO;
+ }
+
+ return 0;
}
/************************************************************************
- * Name: fts_ctpm_auto_clb
- * Brief: auto calibration
- * Input: i2c info
- * Output: no
- * Return: 0
- ***********************************************************************/
-int fts_ctpm_auto_clb(struct i2c_client *client)
-{
-#if FTS_AUTO_CLB_EN
- u8 uc_temp = 0x00;
- u8 i = 0;
-
- /*start auto CLB */
- msleep(200);
-
- fts_i2c_write_reg(client, 0, FTS_REG_WORKMODE_FACTORY_VALUE);
- /*make sure already enter factory mode */
- msleep(100);
- /*write command to start calibration */
- fts_i2c_write_reg(client, 2, 0x4);
- msleep(300);
- if ((chip_types.chip_idh == 0x11) || (chip_types.chip_idh == 0x12)
- || (chip_types.chip_idh == 0x13)
- || (chip_types.chip_idh == 0x14)) {
- /* 5x36,5x36i */
- for (i = 0; i < 100; i++) {
- fts_i2c_read_reg(client, 0x02, &uc_temp);
- if ((uc_temp == 0x02) ||
- (uc_temp == 0xFF))
- break;
- msleep(20);
- }
- } else {
- for (i = 0; i < 100; i++) {
- fts_i2c_read_reg(client, 0, &uc_temp);
- if (((uc_temp&0x70)>>4) == 0x0)
- break;
- msleep(20);
- }
- }
-
- fts_i2c_write_reg(client, 0, 0x40);
- msleep(200);
- fts_i2c_write_reg(client, 2, 0x5);
- msleep(300);
- fts_i2c_write_reg(client, 0, FTS_REG_WORKMODE_WORK_VALUE);
- msleep(300);
-#endif
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_getsize
- * Brief: Get different file's size
- * Input:
+ * Name: fts_fwupg_ecc_cal
+ * Brief: calculate and get ecc from tp
+ * Input: saddr - start address need calculate ecc
+ * len - length need calculate ecc
* Output:
- * Return: file's size
+ * Return: return data ecc of tp if success, otherwise return error code
***********************************************************************/
-u32 fts_getsize(u8 fw_type)
+int fts_fwupg_ecc_cal(u32 saddr, u32 len)
{
- int fw_len = 0;
+ int ret = 0;
+ u32 i = 0;
+ u8 wbuf[FTS_CMD_ECC_CAL_LEN] = { 0 };
+ u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
+ int ecc = 0;
+ int ecc_len = 0;
+ u32 packet_num = 0;
+ u32 packet_len = 0;
+ u32 remainder = 0;
+ u32 addr = 0;
+ u32 offset = 0;
+ struct fts_upgrade *upg = fwupgrade;
-#if FTS_CHIP_IDC
- if (fw_type == PRAMBOOT_SIZE)
- fw_len = sizeof(aucFW_PRAM_BOOT);
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- else if (fw_type == FW_SIZE)
- fw_len = sizeof(CTPM_FW);
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- else if (fw_type == FW2_SIZE)
- fw_len = sizeof(CTPM_FW2);
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- else if (fw_type == FW3_SIZE)
- fw_len = sizeof(CTPM_FW3);
-#endif
-#if (FTS_CHIP_TYPE == _FT8006)
- else if (fw_type == LCD_CFG_SIZE)
- fw_len = sizeof(CTPM_LCD_CFG);
-#endif
+ FTS_INFO( "**********read out checksum**********");
+ if ((NULL == upg) || (NULL == upg->func)) {
+ FTS_ERROR("upgrade/func is null");
+ return -EINVAL;
+ }
- return fw_len;
+ /* check sum init */
+ wbuf[0] = FTS_CMD_ECC_INIT;
+ ret = fts_write(wbuf, 1);
+ if (ret < 0) {
+ FTS_ERROR("ecc init cmd write fail");
+ return ret;
+ }
+
+ packet_num = len / FTS_MAX_LEN_ECC_CALC;
+ remainder = len % FTS_MAX_LEN_ECC_CALC;
+ if (remainder)
+ packet_num++;
+ packet_len = FTS_MAX_LEN_ECC_CALC;
+ FTS_INFO("ecc calc num:%d, remainder:%d", packet_num, remainder);
+
+ /* send commond to start checksum */
+ wbuf[0] = FTS_CMD_ECC_CAL;
+ for (i = 0; i < packet_num; i++) {
+ offset = FTS_MAX_LEN_ECC_CALC * i;
+ addr = saddr + offset;
+ wbuf[1] = BYTE_OFF_16(addr);
+ wbuf[2] = BYTE_OFF_8(addr);
+ wbuf[3] = BYTE_OFF_0(addr);
+
+ if ((i == (packet_num - 1)) && remainder)
+ packet_len = remainder;
+ wbuf[4] = BYTE_OFF_8(packet_len);
+ wbuf[5] = BYTE_OFF_0(packet_len);
+
+ FTS_DEBUG("ecc calc startaddr:0x%04x, len:%d", addr, packet_len);
+ ret = fts_write(wbuf, FTS_CMD_ECC_CAL_LEN);
+ if (ret < 0) {
+ FTS_ERROR("ecc calc cmd write fail");
+ return ret;
+ }
+
+ msleep(packet_len / 256);
+
+ /* read status if check sum is finished */
+ ret = fts_fwupg_check_flash_status(FTS_CMD_FLASH_STATUS_ECC_OK,
+ FTS_RETRIES_ECC_CAL,
+ FTS_RETRIES_DELAY_ECC_CAL);
+ if (ret < 0) {
+ FTS_ERROR("ecc flash status read fail");
+ return ret;
+ }
+ }
+
+ ecc_len = 1;
+ if (ECC_CHECK_MODE_CRC16 == upg->func->fw_ecc_check_mode) {
+ ecc_len = 2;
+ }
+
+ /* read out check sum */
+ wbuf[0] = FTS_CMD_ECC_READ;
+ ret = fts_read(wbuf, 1, val, ecc_len);
+ if (ret < 0) {
+ FTS_ERROR( "ecc read cmd write fail");
+ return ret;
+ }
+
+ if (ECC_CHECK_MODE_CRC16 == upg->func->fw_ecc_check_mode) {
+ ecc = (int)((u16)(val[0] << 8) + val[1]);
+ } else {
+ ecc = (int)val[0];
+ }
+
+ return ecc;
}
/************************************************************************
- * Name: fts_ctpm_get_pram_or_rom_id
- * Brief: 0
- * Input: 0
- * Output: 0
- * Return: 0
- ***********************************************************************/
-enum FW_STATUS fts_ctpm_get_pram_or_rom_id(struct i2c_client *client)
-{
- u8 buf[4];
- u8 reg_val[2] = {0};
- enum FW_STATUS inRomBoot = FTS_RUN_IN_ERROR;
-
- fts_ctpm_i2c_hid2std(client);
-
- /*Enter upgrade mode*/
- /*send 0x55 in time windows*/
- buf[0] = FTS_UPGRADE_55;
- buf[1] = FTS_UPGRADE_AA;
- fts_i2c_write(client, buf, 2);
-
- msleep(20);
-
- buf[0] = 0x90;
- buf[1] = buf[2] = buf[3] = 0x00;
- fts_i2c_read(client, buf, 4, reg_val, 2);
-
- FTS_DEBUG("[UPGRADE] Read ROM/PRAM/Bootloader id:0x%02x%02x",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == 0x00) || (reg_val[0] == 0xFF))
- inRomBoot = FTS_RUN_IN_ERROR;
- else if (reg_val[0] == chip_types.pramboot_idh
- && reg_val[1] == chip_types.pramboot_idl)
- inRomBoot = FTS_RUN_IN_PRAM;
- else if (reg_val[0] == chip_types.rom_idh
- && reg_val[1] == chip_types.rom_idl)
- inRomBoot = FTS_RUN_IN_ROM;
- else if (reg_val[0] == chip_types.bootloader_idh
- && reg_val[1] == chip_types.bootloader_idl)
- inRomBoot = FTS_RUN_IN_BOOTLOADER;
-
- return inRomBoot;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_file
- * Brief: get app file by Vendor ID
- * Input:
+ * Name: fts_flash_write_buf
+ * Brief: write buf data to flash address
+ * Input: saddr - start address data write to flash
+ * buf - data buffer
+ * len - data length
+ * delay - delay after write
* Output:
- * Return: <0: vendor id not correct,not upgrade
+ * Return: return data ecc of host if success, otherwise return error code
***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
+int fts_flash_write_buf(
+ u32 saddr,
+ u8 *buf,
+ u32 len,
+ u32 delay)
{
- int ret;
+ int ret = 0;
+ u32 i = 0;
+ u32 j = 0;
+ u32 packet_number = 0;
+ u32 packet_len = 0;
+ u32 addr = 0;
+ u32 offset = 0;
+ u32 remainder = 0;
+ u8 packet_buf[FTS_FLASH_PACKET_LENGTH + FTS_CMD_WRITE_LEN] = { 0 };
+ u8 ecc_tmp = 0;
+ int ecc_in_host = 0;
+ u8 cmd = 0;
+ u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
+ u16 read_status = 0;
+ u16 wr_ok = 0;
+ struct fts_upgrade *upg = fwupgrade;
- if (fts_updatefun_curr.get_i_file)
- ret = fts_updatefun_curr.get_i_file(client, fw_valid);
- else
- ret = -EIO;
+ FTS_INFO( "**********write data to flash**********");
+ if ((!upg) || (!upg->func || !buf || !len)) {
+ FTS_ERROR("upgrade/func/buf/len is invalid");
+ return -EINVAL;
+ }
- return ret;
+ FTS_INFO("data buf start addr=0x%x, len=0x%x", saddr, len);
+ packet_number = len / FTS_FLASH_PACKET_LENGTH;
+ remainder = len % FTS_FLASH_PACKET_LENGTH;
+ if (remainder > 0)
+ packet_number++;
+ packet_len = FTS_FLASH_PACKET_LENGTH;
+ FTS_INFO("write data, num:%d remainder:%d", packet_number, remainder);
+
+ packet_buf[0] = FTS_CMD_WRITE;
+ for (i = 0; i < packet_number; i++) {
+ offset = i * FTS_FLASH_PACKET_LENGTH;
+ addr = saddr + offset;
+ packet_buf[1] = BYTE_OFF_16(addr);
+ packet_buf[2] = BYTE_OFF_8(addr);
+ packet_buf[3] = BYTE_OFF_0(addr);
+
+ /* last packet */
+ if ((i == (packet_number - 1)) && remainder)
+ packet_len = remainder;
+
+ packet_buf[4] = BYTE_OFF_8(packet_len);
+ packet_buf[5] = BYTE_OFF_0(packet_len);
+
+ for (j = 0; j < packet_len; j++) {
+ packet_buf[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
+ ecc_tmp ^= packet_buf[FTS_CMD_WRITE_LEN + j];
+ }
+
+ ret = fts_write(packet_buf, packet_len + FTS_CMD_WRITE_LEN);
+ if (ret < 0) {
+ FTS_ERROR("app write fail");
+ return ret;
+ }
+ mdelay(delay);
+
+ /* read status */
+ wr_ok = FTS_CMD_FLASH_STATUS_WRITE_OK + addr / packet_len;
+ for (j = 0; j < FTS_RETRIES_WRITE; j++) {
+ cmd = FTS_CMD_FLASH_STATUS;
+ ret = fts_read(&cmd , 1, val, FTS_CMD_FLASH_STATUS_LEN);
+ read_status = (((u16)val[0]) << 8) + val[1];
+ /* FTS_INFO("%x %x", wr_ok, read_status); */
+ if (wr_ok == read_status) {
+ break;
+ }
+ mdelay(FTS_RETRIES_DELAY_WRITE);
+ }
+ }
+
+ ecc_in_host = (int)ecc_tmp;
+ if (ECC_CHECK_MODE_CRC16 == upg->func->fw_ecc_check_mode) {
+ ecc_in_host = (int)fts_crc16_calc_host(buf, len);
+ }
+
+ return ecc_in_host;
}
/************************************************************************
- * Name: fts_ctpm_get_app_ver
- * Brief: get app file version
- * Input:
+ * Name: fts_flash_read_buf
+ * Brief: read data from flash
+ * Input: saddr - start address data write to flash
+ * buf - buffer to store data read from flash
+ * len - read length
* Output:
- * Return: fw version
+ * Return: return 0 if success, otherwise return error code
+ *
+ * Warning: can't call this function directly, need call in boot environment
***********************************************************************/
-int fts_ctpm_get_app_ver(void)
+static int fts_flash_read_buf(u32 saddr, u8 *buf, u32 len)
{
- int i_ret = 0;
+ int ret = 0;
+ u32 i = 0;
+ u32 packet_number = 0;
+ u32 packet_len = 0;
+ u32 addr = 0;
+ u32 offset = 0;
+ u32 remainder = 0;
+ u8 wbuf[FTS_CMD_READ_LEN] = { 0 };
- if (fts_updatefun_curr.get_app_i_file_ver)
- i_ret = fts_updatefun_curr.get_app_i_file_ver();
+ if ((NULL == buf) || (0 == len)) {
+ FTS_ERROR("buf is NULL or len is 0");
+ return -EINVAL;
+ }
- return i_ret;
+ packet_number = len / FTS_FLASH_PACKET_LENGTH;
+ remainder = len % FTS_FLASH_PACKET_LENGTH;
+ if (remainder > 0) {
+ packet_number++;
+ }
+ packet_len = FTS_FLASH_PACKET_LENGTH;
+ FTS_INFO("read packet_number:%d, remainder:%d", packet_number, remainder);
+
+ wbuf[0] = FTS_CMD_READ;
+ for (i = 0; i < packet_number; i++) {
+ offset = i * FTS_FLASH_PACKET_LENGTH;
+ addr = saddr + offset;
+ wbuf[1] = BYTE_OFF_16(addr);
+ wbuf[2] = BYTE_OFF_8(addr);
+ wbuf[3] = BYTE_OFF_0(addr);
+
+ /* last packet */
+ if ((i == (packet_number - 1)) && remainder)
+ packet_len = remainder;
+
+ ret = fts_write(wbuf, FTS_CMD_READ_LEN);
+ if (ret < 0) {
+ FTS_ERROR("pram/bootloader write 03 command fail");
+ return ret;
+ }
+
+ msleep(FTS_CMD_READ_DELAY); /* must wait, otherwise read wrong data */
+ ret = fts_read(NULL, 0, buf + offset, packet_len);
+ if (ret < 0) {
+ FTS_ERROR("pram/bootloader read 03 command fail");
+ return ret;
+ }
+ }
+
+ return 0;
}
/************************************************************************
- * Name: fts_ctpm_fw_upgrade
- * Brief: fw upgrade entry funciotn
- * Input:
- * Output:
- * Return: 0 - upgrade successfully
- * <0 - upgrade failed
- ***********************************************************************/
-int fts_ctpm_fw_upgrade(struct i2c_client *client)
-{
- int i_ret = 0;
-
- if (fts_updatefun_curr.upgrade_with_app_i_file)
- i_ret = fts_updatefun_curr.upgrade_with_app_i_file(client);
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade
- * Brief: fw upgrade entry funciotn
- * Input:
- * Output:
- * Return: 0 - upgrade successfully
- * <0 - upgrade failed
- ***********************************************************************/
-int fts_ctpm_lcd_cfg_upgrade(struct i2c_client *client)
-{
- int i_ret = 0;
-
- if (fts_updatefun_curr.upgrade_with_lcd_cfg_i_file)
- i_ret = fts_updatefun_curr.upgrade_with_lcd_cfg_i_file(client);
-
- return i_ret;
-}
-
-static int check_chip_id(u8 chip_id1, u8 chip_id2)
-{
-#if FTS_CHIP_IDC
- if ((chip_id1 == chip_types.chip_idh)
- && (chip_id2 == chip_types.chip_idl) {
-#else
- if (chip_id1 == chip_types.chip_idh) {
-#endif
- return 1;
- }
- return 0;
-}
-
-#if (!(FTS_UPGRADE_STRESS_TEST))
-/************************************************************************
- * Name: fts_ctpm_check_fw_status
- * Brief: Check App is valid or not
- * Input:
- * Output:
- * Return: -EIO - I2C communication error
- * FTS_RUN_IN_APP - APP valid
- * 0 - APP invalid
- ***********************************************************************/
-static int fts_ctpm_check_fw_status(struct i2c_client *client)
-{
- u8 chip_id1 = 0;
- u8 chip_id2 = 0;
- int fw_status = FTS_RUN_IN_ERROR;
- int i = 0;
- int ret = 0;
- int i2c_noack_retry = 0;
-
- for (i = 0; i < 5; i++) {
- ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &chip_id1);
- if (ret < 0) {
- i2c_noack_retry++;
- continue;
- }
-
- ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID2, &chip_id2);
- if (ret < 0) {
- i2c_noack_retry++;
- continue;
- }
-
- if (check_chip_id(chip_id1, chip_id2)) {
- fw_status = FTS_RUN_IN_APP;
- break;
- }
- }
-
- FTS_DEBUG("[UPGRADE]: chip_id = %02x%02x", chip_id1, chip_id2);
- FTS_DEBUG("[UPGRADE]:chip_types.chip_idh = %02x%02x",
- chip_types.chip_idh, chip_types.chip_idl);
-
- /* I2C No ACK 5 times, then return -EIO */
- if (i2c_noack_retry >= 5)
- return -EIO;
-
- /* I2C communication ok, but not get correct ID,
- * need check pram/rom/bootloader
- */
- if (i >= 5)
- fw_status = fts_ctpm_get_pram_or_rom_id(client);
-
- return fw_status;
-}
-
-/************************************************************************
- * Name: fts_ctpm_check_fw_ver
- * Brief: Check vendor id is valid or not
- * Input:
- * Output:
- * Return: 1 - vendor id valid
- * 0 - vendor id invalid
- ***********************************************************************/
-static int fts_ctpm_check_fw_ver(struct i2c_client *client)
-{
- u8 uc_tp_fm_ver = 0;
- u8 uc_host_fm_ver = 0;
-
- fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
- uc_host_fm_ver = fts_ctpm_get_app_ver();
-
- FTS_DEBUG("[UPGRADE]: uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x!!",
- uc_tp_fm_ver, uc_host_fm_ver);
- if (uc_tp_fm_ver < uc_host_fm_ver)
- return 1;
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_check_need_upgrade
+ * Name: fts_flash_read
* Brief:
- * Input:
- * Output:
- * Return: 1 - Need upgrade
- * 0 - No upgrade
+ * Input: addr - address of flash
+ * len - length of read
+ * Output: buf - data read from flash
+ * Return: return 0 if success, otherwise return error code
***********************************************************************/
-static int fts_ctpm_check_need_upgrade(struct i2c_client *client)
+static int fts_flash_read(u32 addr, u8 *buf, u32 len)
{
- int fw_status = 0;
- int bUpgradeFlag = false;
+ int ret = 0;
- FTS_FUNC_ENTER();
+ FTS_INFO("***********read flash***********");
+ if ((NULL == buf) || (0 == len)) {
+ FTS_ERROR("buf is NULL or len is 0");
+ return -EINVAL;
+ }
- /* 1. veriry FW APP is valid or not */
- fw_status = fts_ctpm_check_fw_status(client);
- FTS_DEBUG("[UPGRADE]: fw_status = %d!!", fw_status);
- if (fw_status < 0) {
- /* I2C no ACK, return immediately */
- FTS_ERROR("[UPGRADE]******I2C NO ACK,exit upgrade******");
- return -EIO;
- } else if (fw_status == FTS_RUN_IN_ERROR) {
- FTS_ERROR("[UPGRADE]******IC Type Fail******");
- } else if (fw_status == FTS_RUN_IN_APP) {
- FTS_INFO("[UPGRADE]**********FW APP valid**********");
+ ret = fts_fwupg_enter_into_boot();
+ if (ret < 0) {
+ FTS_ERROR("enter into pramboot/bootloader fail");
+ goto read_flash_err;
+ }
- if (fts_ctpm_get_i_file(client, 1) != 0) {
- FTS_DEBUG("[UPGRADE]***Get upgrade file(fw) fail***");
- return -EIO;
- }
+ ret = fts_flash_read_buf(addr, buf, len);
+ if (ret < 0) {
+ FTS_ERROR("read flash fail");
+ goto read_flash_err;
+ }
- if (fts_ctpm_check_fw_ver(client) == 1) {
- FTS_DEBUG("[UPGRADE]******need upgrade fw******");
- bUpgradeFlag = true;
- } else {
- FTS_DEBUG("[UPGRADE]****Don't need upgrade fw****");
- bUpgradeFlag = false;
- }
- } else {
- /* if app is invalid, reset to run ROM */
- FTS_INFO("[UPGRADE]**********FW APP invalid**********");
- fts_ctpm_rom_or_pram_reset(client);
- if (fts_ctpm_get_i_file(client, 0) != 0) {
- FTS_DEBUG("[UPGRADE]**Get upgrade file(flash) fail**");
- fts_ctpm_rom_or_pram_reset(client);
- return -EIO;
- }
- fts_ctpm_rom_or_pram_reset(client);
- bUpgradeFlag = true;
- }
+read_flash_err:
+ /* reset to normal boot */
+ ret = fts_fwupg_reset_in_boot();
+ if (ret < 0) {
+ FTS_ERROR("reset to normal boot fail");
+ }
+ return ret;
+}
- FTS_FUNC_EXIT();
+static int fts_read_file(char *file_name, u8 **file_buf)
+{
+ int ret = 0;
+ char file_path[FILE_NAME_LENGTH] = { 0 };
+ struct file *filp = NULL;
+ struct inode *inode;
+ mm_segment_t old_fs;
+ loff_t pos;
+ loff_t file_len = 0;
- return bUpgradeFlag;
+ if ((NULL == file_name) || (NULL == file_buf)) {
+ FTS_ERROR("filename/filebuf is NULL");
+ return -EINVAL;
+ }
+
+ snprintf(file_path, FILE_NAME_LENGTH, "%s%s", FTS_FW_BIN_FILEPATH, file_name);
+ filp = filp_open(file_path, O_RDONLY, 0);
+ if (IS_ERR(filp)) {
+ FTS_ERROR("open %s file fail", file_path);
+ return -ENOENT;
+ }
+
+#if 1
+ inode = filp->f_inode;
+#else
+ /* reserved for linux earlier verion */
+ inode = filp->f_dentry->d_inode;
+#endif
+
+ file_len = inode->i_size;
+ *file_buf = (u8 *)vmalloc(file_len);
+ if (NULL == *file_buf) {
+ FTS_ERROR("file buf malloc fail");
+ filp_close(filp, NULL);
+ return -ENOMEM;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ pos = 0;
+ ret = vfs_read(filp, *file_buf, file_len , &pos);
+ if (ret < 0)
+ FTS_ERROR("read file fail");
+ FTS_INFO("file len:%d read len:%d pos:%d", (u32)file_len, ret, (u32)pos);
+ filp_close(filp, NULL);
+ set_fs(old_fs);
+
+ return ret;
+}
+
+int fts_upgrade_bin(char *fw_name, bool force)
+{
+ int ret = 0;
+ u32 fw_file_len = 0;
+ u8 *fw_file_buf = NULL;
+ struct fts_upgrade *upg = fwupgrade;
+
+ FTS_INFO("start upgrade with fw bin");
+ if ((!upg) || (!upg->func) || !upg->ts_data) {
+ FTS_ERROR("upgrade/func/ts_data is null");
+ return -EINVAL;
+ }
+
+ upg->ts_data->fw_loading = 1;
+ fts_irq_disable();
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(DISABLE);
+#endif
+
+ ret = fts_read_file(fw_name, &fw_file_buf);
+ if ((ret < 0) || (ret < FTS_MIN_LEN) || (ret > FTS_MAX_LEN_FILE)) {
+ FTS_ERROR("read fw bin file(sdcard) fail, len:%d", fw_file_len);
+ goto err_bin;
+ }
+
+ fw_file_len = ret;
+ FTS_INFO("fw bin file len:%d", fw_file_len);
+ if (force) {
+ if (upg->func->force_upgrade) {
+ ret = upg->func->force_upgrade(fw_file_buf, fw_file_len);
+ } else {
+ FTS_INFO("force_upgrade function is null, no upgrade");
+ goto err_bin;
+ }
+ } else {
+#if FTS_AUTO_LIC_UPGRADE_EN
+ if (upg->func->lic_upgrade) {
+ ret = upg->func->lic_upgrade(fw_file_buf, fw_file_len);
+ } else {
+ FTS_INFO("lic_upgrade function is null, no upgrade");
+ }
+#endif
+ if (upg->func->upgrade) {
+ ret = upg->func->upgrade(fw_file_buf, fw_file_len);
+ } else {
+ FTS_INFO("upgrade function is null, no upgrade");
+ }
+ }
+
+ if (ret < 0) {
+ FTS_ERROR("upgrade fw bin failed");
+ fts_fwupg_reset_in_boot();
+ goto err_bin;
+ }
+
+ FTS_INFO("upgrade fw bin success");
+ ret = 0;
+
+err_bin:
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(ENABLE);
+#endif
+ fts_irq_enable();
+ upg->ts_data->fw_loading = 0;
+
+ if (fw_file_buf) {
+ vfree(fw_file_buf);
+ fw_file_buf = NULL;
+ }
+ return ret;
+}
+
+int fts_enter_test_environment(bool test_state)
+{
+ return 0;
+}
+#if FTS_AUTO_LIC_UPGRADE_EN
+static int fts_lic_get_vid_in_tp(u16 *vid)
+{
+ int ret = 0;
+ u8 val[2] = { 0 };
+
+ if (NULL == vid) {
+ FTS_ERROR("vid is NULL");
+ return -EINVAL;
+ }
+
+ ret = fts_read_reg(FTS_REG_VENDOR_ID, &val[0]);
+ if (fts_data->ic_info.is_incell)
+ ret = fts_read_reg(FTS_REG_MODULE_ID, &val[1]);
+ if (ret < 0) {
+ FTS_ERROR("read vid from tp fail");
+ return ret;
+ }
+
+ *vid = *(u16 *)val;
+ return 0;
+}
+
+static int fts_lic_get_vid_in_host(struct fts_upgrade *upg, u16 *vid)
+{
+ u8 val[2] = { 0 };
+ u8 *licbuf = NULL;
+ u32 conf_saddr = 0;
+
+ if (!upg || !upg->func || !upg->lic || !vid) {
+ FTS_ERROR("upgrade/func/get_hlic_ver/lic/vid is null");
+ return -EINVAL;
+ }
+
+ if (upg->lic_length < FTS_MAX_LEN_SECTOR) {
+ FTS_ERROR("lic length(%x) fail", upg->lic_length);
+ return -EINVAL;
+ }
+
+ licbuf = upg->lic;
+ conf_saddr = upg->func->fwcfgoff;
+ val[0] = licbuf[conf_saddr + FTS_CONIFG_VENDORID_OFF];
+ if (fts_data->ic_info.is_incell)
+ val[1] = licbuf[conf_saddr + FTS_CONIFG_MODULEID_OFF];
+
+ *vid = *(u16 *)val;
+ return 0;
+}
+
+static int fts_lic_get_ver_in_tp(u8 *ver)
+{
+ int ret = 0;
+
+ if (NULL == ver) {
+ FTS_ERROR("ver is NULL");
+ return -EINVAL;
+ }
+
+ ret = fts_read_reg(FTS_REG_LIC_VER, ver);
+ if (ret < 0) {
+ FTS_ERROR("read lcd initcode ver from tp fail");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fts_lic_get_ver_in_host(struct fts_upgrade *upg, u8 *ver)
+{
+ int ret = 0;
+
+ if (!upg || !upg->func || !upg->func->get_hlic_ver || !upg->lic) {
+ FTS_ERROR("upgrade/func/get_hlic_ver/lic is null");
+ return -EINVAL;
+ }
+
+ ret = upg->func->get_hlic_ver(upg->lic);
+ if (ret < 0) {
+ FTS_ERROR("get host lcd initial code version fail");
+ return ret;
+ }
+
+ *ver = (u8)ret;
+ return ret;
+}
+
+static bool fts_lic_need_upgrade(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ u8 initcode_ver_in_tp = 0;
+ u8 initcode_ver_in_host = 0;
+ u16 vid_in_tp = 0;
+ u16 vid_in_host = 0;
+ bool fwvalid = false;
+
+ fwvalid = fts_fwupg_check_fw_valid();
+ if ( !fwvalid) {
+ FTS_INFO("fw is invalid, no upgrade lcd init code");
+ return false;
+ }
+
+ ret = fts_lic_get_vid_in_host(upg, &vid_in_host);
+ if (ret < 0) {
+ FTS_ERROR("vendor id in host invalid");
+ return false;
+ }
+
+ ret = fts_lic_get_vid_in_tp(&vid_in_tp);
+ if (ret < 0) {
+ FTS_ERROR("vendor id in tp invalid");
+ return false;
+ }
+
+ FTS_DEBUG("vid in tp:0x%04x, host:0x%04x", vid_in_tp, vid_in_host);
+ if (vid_in_tp != vid_in_host) {
+ FTS_INFO("vendor id in tp&host are different, no upgrade lic");
+ return false;
+ }
+
+ ret = fts_lic_get_ver_in_host(upg, &initcode_ver_in_host);
+ if (ret < 0) {
+ FTS_ERROR("init code in host invalid");
+ return false;
+ }
+
+ ret = fts_lic_get_ver_in_tp(&initcode_ver_in_tp);
+ if (ret < 0) {
+ FTS_ERROR("read reg0xE4 fail");
+ return false;
+ }
+
+ FTS_DEBUG("lcd initial code version in tp:%x, host:%x",
+ initcode_ver_in_tp, initcode_ver_in_host);
+ if (0xA5 == initcode_ver_in_tp) {
+ FTS_INFO("lcd init code ver is 0xA5, don't upgade init code");
+ return false;
+ } else if (0xFF == initcode_ver_in_tp) {
+ FTS_DEBUG("lcd init code in tp is invalid, need upgrade init code");
+ return true;
+ } else if (initcode_ver_in_tp < initcode_ver_in_host)
+ return true;
+ else
+ return false;
+}
+
+static int fts_lic_upgrade(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ bool hlic_upgrade = false;
+ int upgrade_count = 0;
+ u8 ver = 0;
+
+ FTS_INFO("lcd initial code auto upgrade function");
+ if ((!upg) || (!upg->func) || (!upg->func->lic_upgrade)) {
+ FTS_ERROR("lcd upgrade function is null");
+ return -EINVAL;
+ }
+
+ hlic_upgrade = fts_lic_need_upgrade(upg);
+ FTS_INFO("lcd init code upgrade flag:%d", hlic_upgrade);
+ if (hlic_upgrade) {
+ FTS_INFO("lcd initial code need upgrade, upgrade begin...");
+ do {
+ FTS_INFO("lcd initial code upgrade times:%d", upgrade_count);
+ upgrade_count++;
+
+ ret = upg->func->lic_upgrade(upg->lic, upg->lic_length);
+ if (ret < 0) {
+ fts_fwupg_reset_in_boot();
+ } else {
+ fts_lic_get_ver_in_tp(&ver);
+ FTS_INFO("success upgrade to lcd initcode ver:%02x", ver);
+ break;
+ }
+ } while (upgrade_count < 2);
+ } else {
+ FTS_INFO("lcd initial code don't need upgrade");
+ }
+
+ return ret;
+}
+#endif /* FTS_AUTO_LIC_UPGRADE_EN */
+
+
+static int fts_param_get_ver_in_tp(u8 *ver)
+{
+ int ret = 0;
+
+ if (NULL == ver) {
+ FTS_ERROR("ver is NULL");
+ return -EINVAL;
+ }
+
+ ret = fts_read_reg(FTS_REG_IDE_PARA_VER_ID, ver);
+ if (ret < 0) {
+ FTS_ERROR("read fw param ver from tp fail");
+ return ret;
+ }
+
+ if ((0x00 == *ver) || (0xFF == *ver)) {
+ FTS_INFO("param version in tp invalid");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int fts_param_get_ver_in_host(struct fts_upgrade *upg, u8 *ver)
+{
+ if ((!upg) || (!upg->func) || (!upg->fw) || (!ver)) {
+ FTS_ERROR("fts_data/upgrade/func/fw/ver is NULL");
+ return -EINVAL;
+ }
+
+ if (upg->fw_length < upg->func->paramcfgveroff) {
+ FTS_ERROR("fw len(%x) < paramcfg ver offset(%x)",
+ upg->fw_length, upg->func->paramcfgveroff);
+ return -EINVAL;
+ }
+
+ FTS_INFO("fw paramcfg version offset:%x", upg->func->paramcfgveroff);
+ *ver = upg->fw[upg->func->paramcfgveroff];
+
+ if ((0x00 == *ver) || (0xFF == *ver)) {
+ FTS_INFO("param version in host invalid");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * return: < 0 : error
+ * == 0: no ide
+ * == 1: ide
+ */
+static int fts_param_ide_in_host(struct fts_upgrade *upg)
+{
+ u32 off = 0;
+
+ if ((!upg) || (!upg->func) || (!upg->fw)) {
+ FTS_ERROR("fts_data/upgrade/func/fw is NULL");
+ return -EINVAL;
+ }
+
+ if (upg->fw_length < upg->func->paramcfgoff + FTS_FW_IDE_SIG_LEN) {
+ FTS_INFO("fw len(%x) < paramcfg offset(%x), no IDE",
+ upg->fw_length, upg->func->paramcfgoff + FTS_FW_IDE_SIG_LEN);
+ return 0;
+ }
+
+ off = upg->func->paramcfgoff;
+ if (0 == memcmp(&upg->fw[off], FTS_FW_IDE_SIG, FTS_FW_IDE_SIG_LEN)) {
+ FTS_INFO("fw in host is IDE version");
+ return 1;
+ }
+
+ FTS_INFO("fw in host isn't IDE version");
+ return 0;
+}
+
+/*
+ * return: < 0 : error
+ * 0 : no ide
+ * 1 : ide
+ */
+static int fts_param_ide_in_tp(u8 *val)
+{
+ int ret = 0;
+
+ ret = fts_read_reg(FTS_REG_IDE_PARA_STATUS, val);
+ if (ret < 0) {
+ FTS_ERROR("read IDE PARAM STATUS in tp fail");
+ return ret;
+ }
+
+ if ((*val != 0xFF) && ((*val & 0x80) == 0x80)) {
+ FTS_INFO("fw in tp is IDE version");
+ return 1;
+ }
+
+ FTS_INFO("fw in tp isn't IDE version");
+ return 0;
}
/************************************************************************
- * Name: fts_ctpm_auto_upgrade
- * Brief: auto upgrade
+ * fts_param_need_upgrade - check fw paramcfg need upgrade or not
+ *
+ * Return: < 0 : error if paramcfg need upgrade
+ * 0 : no need upgrade
+ * 1 : need upgrade app + param
+ * 2 : need upgrade param
+ ***********************************************************************/
+static int fts_param_need_upgrade(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ u8 val = 0;
+ int ide_in_host = 0;
+ int ide_in_tp = 0;
+ u8 ver_in_host = 0;
+ u8 ver_in_tp = 0;
+ bool fwvalid = false;
+
+ fwvalid = fts_fwupg_check_fw_valid();
+ if ( !fwvalid) {
+ FTS_INFO("fw is invalid, upgrade app+param");
+ return 1;
+ }
+
+ ide_in_host = fts_param_ide_in_host(upg);
+ if (ide_in_host < 0) {
+ FTS_INFO("fts_param_ide_in_host fail");
+ return ide_in_host;
+ }
+
+ ide_in_tp = fts_param_ide_in_tp(&val);
+ if (ide_in_tp < 0) {
+ FTS_INFO("fts_param_ide_in_tp fail");
+ return ide_in_tp;
+ }
+
+ if ((0 == ide_in_host) && (0 == ide_in_tp)) {
+ FTS_INFO("fw in host&tp are both no ide");
+ return 0;
+ } else if (ide_in_host != ide_in_tp) {
+ FTS_INFO("fw in host&tp not equal, need upgrade app+param");
+ return 1;
+ } else if ((1 == ide_in_host) && (1 == ide_in_tp)) {
+ FTS_INFO("fw in host&tp are both ide");
+ if ((val & 0x7F) != 0x00) {
+ FTS_INFO("param invalid, need upgrade param");
+ return 2;
+ }
+
+ ret = fts_param_get_ver_in_host(upg, &ver_in_host);
+ if (ret < 0) {
+ FTS_ERROR("param version in host invalid");
+ return ret;
+ }
+
+ ret = fts_param_get_ver_in_tp(&ver_in_tp);
+ if (ret < 0) {
+ FTS_ERROR("get IDE param ver in tp fail");
+ return ret;
+ }
+
+ FTS_INFO("fw paramcfg version in tp:%x, host:%x",
+ ver_in_tp, ver_in_host);
+ if (ver_in_tp != ver_in_host) {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+static int fts_fwupg_get_ver_in_tp(u8 *ver)
+{
+ int ret = 0;
+
+ if (NULL == ver) {
+ FTS_ERROR("ver is NULL");
+ return -EINVAL;
+ }
+
+ ret = fts_read_reg(FTS_REG_FW_VER, ver);
+ if (ret < 0) {
+ FTS_ERROR("read fw ver from tp fail");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fts_fwupg_get_ver_in_host(struct fts_upgrade *upg, u8 *ver)
+{
+ if ((!upg) || (!upg->func) || (!upg->fw) || (!ver)) {
+ FTS_ERROR("fts_data/upgrade/func/fw/ver is NULL");
+ return -EINVAL;
+ }
+
+ if (upg->fw_length < upg->func->fwveroff) {
+ FTS_ERROR("fw len(0x%0x) < fw ver offset(0x%x)",
+ upg->fw_length, upg->func->fwveroff);
+ return -EINVAL;
+ }
+
+ FTS_INFO("fw version offset:0x%x", upg->func->fwveroff);
+ *ver = upg->fw[upg->func->fwveroff];
+ return 0;
+}
+
+static bool fts_fwupg_need_upgrade(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ bool fwvalid = false;
+ u8 fw_ver_in_host = 0;
+ u8 fw_ver_in_tp = 0;
+
+ fwvalid = fts_fwupg_check_fw_valid();
+ if (fwvalid) {
+ ret = fts_fwupg_get_ver_in_host(upg, &fw_ver_in_host);
+ if (ret < 0) {
+ FTS_ERROR("get fw ver in host fail");
+ return false;
+ }
+
+ ret = fts_fwupg_get_ver_in_tp(&fw_ver_in_tp);
+ if (ret < 0) {
+ FTS_ERROR("get fw ver in tp fail");
+ return false;
+ }
+
+ FTS_INFO("fw version in tp:%x, host:%x", fw_ver_in_tp, fw_ver_in_host);
+ if (fw_ver_in_tp != fw_ver_in_host) {
+ return true;
+ }
+ } else {
+ FTS_INFO("fw invalid, need upgrade fw");
+ return true;
+ }
+
+ return false;
+}
+
+/************************************************************************
+ * Name: fts_fw_upgrade
+ * Brief: fw upgrade main entry, run in following steps
+ * 1. check fw version(A6), not equal, will upgrade app(+param)
+ * 2. if fw version equal, will check ide, will upgrade app(+param)
+ * in the follow situation
+ * a. host&tp IDE's type are not equal, will upgrade app+param
+ * b. host&tp are both IDE's type, and param's version are not
+ * equal, will upgrade param
* Input:
* Output:
- * Return: 0 - no upgrade
+ * Return: return 0 if success, otherwise return error code
***********************************************************************/
-int fts_ctpm_auto_upgrade(struct i2c_client *client)
+int fts_fwupg_upgrade(struct fts_upgrade *upg)
{
- u8 uc_tp_fm_ver = 0;
- int i_ret = 0;
- int bUpgradeFlag = false;
- u8 uc_upgrade_times = 0;
+ int ret = 0;
+ bool upgrade_flag = false;
+ int upgrade_count = 0;
+ u8 ver = 0;
- FTS_DEBUG("[UPGRADE]**********check upgrade need or not**********");
- bUpgradeFlag = fts_ctpm_check_need_upgrade(client);
- FTS_DEBUG("[UPGRADE]**********bUpgradeFlag = 0x%x**********",
- bUpgradeFlag);
+ FTS_INFO("fw auto upgrade function");
+ if ((NULL == upg) || (NULL == upg->func)) {
+ FTS_ERROR("upg/upg->func is null");
+ return -EINVAL;
+ }
- if (bUpgradeFlag <= 0) {
- FTS_DEBUG("[UPGRADE]**********No Upgrade, exit**********");
- return 0;
- }
+ upgrade_flag = fts_fwupg_need_upgrade(upg);
+ FTS_INFO("fw upgrade flag:%d", upgrade_flag);
+ do {
+ upgrade_count++;
+ if (upgrade_flag) {
+ FTS_INFO("upgrade fw app(times:%d)", upgrade_count);
+ if (upg->func->upgrade) {
+ ret = upg->func->upgrade(upg->fw, upg->fw_length);
+ if (ret < 0) {
+ fts_fwupg_reset_in_boot();
+ } else {
+ fts_fwupg_get_ver_in_tp(&ver);
+ FTS_INFO("success upgrade to fw version %02x", ver);
+ break;
+ }
+ } else {
+ FTS_ERROR("upgrade func/upgrade is null, return immediately");
+ ret = -ENODATA;
+ break;
+ }
+ } else {
+ if (upg->func->param_upgrade) {
+ ret = fts_param_need_upgrade(upg);
+ if (ret <= 0) {
+ FTS_INFO("param don't need upgrade");
+ break;
+ } else if (1 == ret) {
+ FTS_INFO("force upgrade fw app(times:%d)", upgrade_count);
+ if (upg->func->upgrade) {
+ ret = upg->func->upgrade(upg->fw, upg->fw_length);
+ if (ret < 0) {
+ fts_fwupg_reset_in_boot();
+ } else {
+ break;
+ }
+ }
+ } else if (2 == ret) {
+ FTS_INFO("upgrade param area(times:%d)", upgrade_count);
+ ret = upg->func->param_upgrade(upg->fw, upg->fw_length);
+ if (ret < 0) {
+ fts_fwupg_reset_in_boot();
+ } else {
+ fts_param_get_ver_in_tp(&ver);
+ FTS_INFO("success upgrade to fw param version %02x", ver);
+ break;
+ }
+ } else
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (upgrade_count < 2);
- /* FW Upgrade */
- do {
- uc_upgrade_times++;
- FTS_DEBUG("[UPGRADE]*********star upgrade(%d)*************",
- uc_upgrade_times);
-
- i_ret = fts_ctpm_fw_upgrade(client);
- if (i_ret == 0) {
- /* upgrade success */
- fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
- FTS_DEBUG("[UPGRADE] Success upgrade to ver 0x%x",
- uc_tp_fm_ver);
-
- fts_ctpm_auto_clb(client);
- break;
- }
-
- /* upgrade fail, reset to run ROM BOOT..
- * if app in flash is ok, TP will work success
- */
- FTS_ERROR("[UPGRADE]*****upgrade fail, reset now*****");
- fts_ctpm_rom_or_pram_reset(client);
-
- /* if upgrade fail, upgrade again. then return */
- } while (uc_upgrade_times < 2);
-
- return i_ret;
+ return ret;
}
-#endif
-#if FTS_AUTO_UPGRADE_EN
-static void fts_ctpm_update_work_func(struct work_struct *work)
+/************************************************************************
+ * fts_fwupg_auto_upgrade - upgrade main entry
+ ***********************************************************************/
+static void fts_fwupg_auto_upgrade(struct fts_upgrade *upg)
{
- int i_ret = 0;
+ int ret = 0;
- FTS_DEBUG("[UPGRADE]*****FTS enter upgrade*******");
- fts_irq_disable();
+ FTS_INFO("********************FTS enter upgrade********************");
+ if (!upg || !upg->ts_data) {
+ FTS_ERROR("upg/ts_data is null");
+ return ;
+ }
- /* esd check */
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(DISABLE);
+ ret = fts_fwupg_upgrade(upg);
+ if (ret < 0)
+ FTS_ERROR("**********tp fw(app/param) upgrade failed**********");
+ else
+ FTS_INFO("**********tp fw(app/param) no upgrade/upgrade success**********");
+
+#if FTS_AUTO_LIC_UPGRADE_EN
+ ret = fts_lic_upgrade(upg);
+ if (ret < 0)
+ FTS_ERROR("**********lcd init code upgrade failed**********");
+ else
+ FTS_INFO("**********lcd init code no upgrade/upgrade success**********");
#endif
- i_ret = fts_ctpm_auto_upgrade(fts_i2c_client);
- if (i_ret < 0)
- FTS_ERROR("[UPGRADE]**********TP FW upgrade failed**********");
+ FTS_INFO("********************FTS exit upgrade********************");
+}
-#if FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN
- msleep(2000);
+static int fts_fwupg_get_vendorid(struct fts_upgrade *upg, int *vid)
+{
+ int ret = 0;
+ bool fwvalid = false;
+ u8 vendor_id = 0;
+ u8 module_id = 0;
+ u32 fwcfg_addr = 0;
+ u8 cfgbuf[FTS_HEADER_LEN] = { 0 };
- /* lcd_cfg upgrade */
- i_ret = fts_ctpm_lcd_cfg_upgrade(fts_i2c_client);
- if (i_ret < 0)
- FTS_ERROR("[UPGRADE]**********LCD cfg upgrade failed*********");
-#endif
+ FTS_INFO("read vendor id from tp");
+ if ((!upg) || (!upg->func) || (!upg->ts_data) || (!vid)) {
+ FTS_ERROR("upgrade/func/ts_data/vid is null");
+ return -EINVAL;
+ }
-#if FTS_ESDCHECK_EN
- fts_esdcheck_switch(ENABLE);
-#endif
- fts_irq_enable();
+ fwvalid = fts_fwupg_check_fw_valid();
+ if (fwvalid) {
+ ret = fts_read_reg(FTS_REG_VENDOR_ID, &vendor_id);
+ if (upg->ts_data->ic_info.is_incell)
+ ret = fts_read_reg(FTS_REG_MODULE_ID, &module_id);
+ } else {
+ fwcfg_addr = upg->func->fwcfgoff;
+ ret = fts_flash_read(fwcfg_addr, cfgbuf, FTS_HEADER_LEN);
+ vendor_id = cfgbuf[FTS_CONIFG_VENDORID_OFF];
+ if (upg->ts_data->ic_info.is_incell) {
+ if ((cfgbuf[FTS_CONIFG_MODULEID_OFF] +
+ cfgbuf[FTS_CONIFG_MODULEID_OFF + 1]) == 0xFF)
+ module_id = cfgbuf[FTS_CONIFG_MODULEID_OFF];
+ }
+ }
- FTS_DEBUG("[UPGRADE]**********FTS exit upgrade*************");
+ if (ret < 0) {
+ FTS_ERROR("fail to get vendor id from tp");
+ return ret;
+ }
+
+ *vid = (int)((module_id << 8) + vendor_id);
+ return 0;
+}
+
+static int fts_fwupg_get_module_info(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ int i = 0;
+ struct upgrade_module *info = &module_list[0];
+
+ if (!upg || !upg->ts_data) {
+ FTS_ERROR("upg/ts_data is null");
+ return -EINVAL;
+ }
+
+ if (FTS_GET_MODULE_NUM > 1) {
+ /* support multi modules, must read correct module id(vendor id) */
+ ret = fts_fwupg_get_vendorid(upg, &upg->module_id);
+ if (ret < 0) {
+ FTS_ERROR("get vendor id failed");
+ return ret;
+ }
+ FTS_INFO("module id:%04x", upg->module_id);
+ for (i = 0; i < FTS_GET_MODULE_NUM; i++) {
+ info = &module_list[i];
+ if (upg->module_id == info->id) {
+ FTS_INFO("module id match, get module info pass");
+ break;
+ }
+ }
+ if (i >= FTS_GET_MODULE_NUM) {
+ FTS_ERROR("no module id match, don't get file");
+ return -ENODATA;
+ }
+ }
+
+ upg->module_info = info;
+ return 0;
+}
+
+static int fts_get_fw_file_via_request_firmware(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ const struct firmware *fw = NULL;
+ u8 *tmpbuf = NULL;
+ char fwname[FILE_NAME_LENGTH] = { 0 };
+
+ if (!upg || !upg->ts_data || !upg->ts_data->dev) {
+ FTS_ERROR("upg/ts_data/dev is null");
+ return -EINVAL;
+ }
+
+ snprintf(fwname, FILE_NAME_LENGTH, "%s%s.bin", \
+ FTS_FW_NAME_PREX_WITH_REQUEST, \
+ upg->module_info->vendor_name);
+
+ ret = request_firmware(&fw, fwname, upg->ts_data->dev);
+ if (0 == ret) {
+ FTS_INFO("firmware(%s) request successfully", fwname);
+ tmpbuf = vmalloc(fw->size);
+ if (NULL == tmpbuf) {
+ FTS_ERROR("fw buffer vmalloc fail");
+ ret = -ENOMEM;
+ } else {
+ memcpy(tmpbuf, fw->data, fw->size);
+ upg->fw = tmpbuf;
+ upg->fw_length = fw->size;
+ upg->fw_from_request = 1;
+ }
+ } else {
+ FTS_INFO("firmware(%s) request fail,ret=%d", fwname, ret);
+ }
+
+ if (fw != NULL) {
+ release_firmware(fw);
+ fw = NULL;
+ }
+
+ return ret;
+}
+
+static int fts_get_fw_file_via_i(struct fts_upgrade *upg)
+{
+ upg->fw = upg->module_info->fw_file;
+ upg->fw_length = upg->module_info->fw_len;
+ upg->fw_from_request = 0;
+
+ return 0;
}
/*****************************************************************************
- * Name: fts_ctpm_upgrade_init
- * Brief:
+ * Name: fts_fwupg_get_fw_file
+ * Brief: get fw image/file,
+ * If support muitl modules, please set FTS_GET_MODULE_NUM, and FTS_-
+ * MODULE_ID/FTS_MODULE_NAME;
+ * If get fw via .i file, please set FTS_FW_REQUEST_SUPPORT=0, and F-
+ * TS_MODULE_ID; will use module id to distingwish different modules;
+ * If get fw via reques_firmware(), please set FTS_FW_REQUEST_SUPPORT
+ * =1, and FTS_MODULE_NAME; fw file name will be composed of "focalt-
+ * ech_ts_fw_" & FTS_VENDOR_NAME;
+ *
+ * If have flash, module_id=vendor_id, If non-flash,module_id need
+ * transfer from LCD driver(gpio or lcm_id or ...);
+ * Input:
+ * Output:
+ * Return: return 0 if success, otherwise return error code
+ *****************************************************************************/
+static int fts_fwupg_get_fw_file(struct fts_upgrade *upg)
+{
+ int ret = 0;
+ bool get_fw_i_flag = false;
+
+ FTS_DEBUG("get upgrade fw file");
+ if (!upg || !upg->ts_data) {
+ FTS_ERROR("upg/ts_data is null");
+ return -EINVAL;
+ }
+
+ ret = fts_fwupg_get_module_info(upg);
+ if ((ret < 0) || (!upg->module_info)) {
+ FTS_ERROR("get module info fail");
+ return ret;
+ }
+
+ if (FTS_FW_REQUEST_SUPPORT) {
+ ret = fts_get_fw_file_via_request_firmware(upg);
+ if (ret != 0) {
+ get_fw_i_flag = true;
+ }
+ } else {
+ get_fw_i_flag = true;
+ }
+
+ if (get_fw_i_flag) {
+ ret = fts_get_fw_file_via_i(upg);
+ }
+
+ upg->lic = upg->fw;
+ upg->lic_length = upg->fw_length;
+
+ FTS_INFO("upgrade fw file len:%d", upg->fw_length);
+ if ((upg->fw_length < FTS_MIN_LEN)
+ || (upg->fw_length > FTS_MAX_LEN_FILE)) {
+ FTS_ERROR("fw file len(%d) fail", upg->fw_length);
+ return -ENODATA;
+ }
+
+ return ret;
+}
+
+static void fts_fwupg_init_ic_detail(struct fts_upgrade *upg)
+{
+ if (upg && upg->func && upg->func->init) {
+ upg->func->init(upg->fw, upg->fw_length);
+ }
+}
+
+/*****************************************************************************
+ * Name: fts_fwupg_work
+ * Brief: 1. get fw image/file
+ * 2. ic init if have
+ * 3. call upgrade main function(fts_fwupg_auto_upgrade)
* Input:
* Output:
* Return:
*****************************************************************************/
-void fts_ctpm_upgrade_init(void)
+static void fts_fwupg_work(struct work_struct *work)
{
- FTS_FUNC_ENTER();
+ int ret = 0;
+ struct fts_upgrade *upg = fwupgrade;
- touch_wq = create_singlethread_workqueue("touch_wq");
- if (touch_wq) {
- INIT_WORK(&fw_update_work, fts_ctpm_update_work_func);
- queue_work(touch_wq, &fw_update_work);
- } else
- FTS_ERROR("[UPGRADE]create_singlethread_workqueue failed\n");
+#if !FTS_AUTO_UPGRADE_EN
+ FTS_INFO("FTS_AUTO_UPGRADE_EN is disabled, not upgrade when power on");
+ return ;
+#endif
- FTS_FUNC_EXIT();
+ FTS_INFO("fw upgrade work function");
+ if (!upg || !upg->ts_data) {
+ FTS_ERROR("upg/ts_data is null");
+ return ;
+ }
+
+ upg->ts_data->fw_loading = 1;
+ fts_irq_disable();
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(DISABLE);
+#endif
+
+ /* get fw */
+ ret = fts_fwupg_get_fw_file(upg);
+ if (ret < 0) {
+ FTS_ERROR("get file fail, can't upgrade");
+ } else {
+ /* ic init if have */
+ fts_fwupg_init_ic_detail(upg);
+ /* run auto upgrade */
+ fts_fwupg_auto_upgrade(upg);
+ }
+
+#if FTS_ESDCHECK_EN
+ fts_esdcheck_switch(ENABLE);
+#endif
+ fts_irq_enable();
+ upg->ts_data->fw_loading = 0;
}
-/*****************************************************************************
- * Name: fts_ctpm_upgrade_exit
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-void fts_ctpm_upgrade_exit(void)
+int fts_fwupg_init(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
- destroy_workqueue(touch_wq);
- FTS_FUNC_EXIT();
+ int i = 0;
+ int j = 0;
+ int ic_stype = 0;
+ struct upgrade_func *func = upgrade_func_list[0];
+ int func_count = sizeof(upgrade_func_list) / sizeof(upgrade_func_list[0]);
+
+ FTS_INFO("fw upgrade init function");
+
+ if (!ts_data || !ts_data->ts_workqueue) {
+ FTS_ERROR("ts_data/workqueue is NULL, can't run upgrade function");
+ return -EINVAL;
+ }
+
+ if (0 == func_count) {
+ FTS_ERROR("no upgrade function in tp driver");
+ return -ENODATA;
+ }
+
+ fwupgrade = (struct fts_upgrade *)kzalloc(sizeof(*fwupgrade), GFP_KERNEL);
+ if (NULL == fwupgrade) {
+ FTS_ERROR("malloc memory for upgrade fail");
+ return -ENOMEM;
+ }
+
+ ic_stype = ts_data->ic_info.ids.type;
+ if (1 == func_count) {
+ fwupgrade->func = func;
+ } else {
+ for (i = 0; i < func_count; i++) {
+ func = upgrade_func_list[i];
+ for (j = 0; j < FTX_MAX_COMPATIBLE_TYPE; j++) {
+ if (0 == func->ctype[j])
+ break;
+ else if (func->ctype[j] == ic_stype) {
+ FTS_INFO("match upgrade function,type:%x", (int)func->ctype[j]);
+ fwupgrade->func = func;
+ }
+ }
+ }
+ }
+
+ if (NULL == fwupgrade->func) {
+ FTS_ERROR("no upgrade function match, can't upgrade");
+ kfree(fwupgrade);
+ fwupgrade = NULL;
+ return -ENODATA;
+ }
+
+ fwupgrade->ts_data = ts_data;
+ INIT_WORK(&ts_data->fwupg_work, fts_fwupg_work);
+ queue_work(ts_data->ts_workqueue, &ts_data->fwupg_work);
+
+ return 0;
}
-#endif /* #if FTS_AUTO_UPGRADE_EN */
+int fts_fwupg_exit(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
+ if (fwupgrade) {
+ if (fwupgrade->fw_from_request) {
+ vfree(fwupgrade->fw);
+ fwupgrade->fw = NULL;
+ }
+
+ kfree(fwupgrade);
+ fwupgrade = NULL;
+ }
+ FTS_FUNC_EXIT();
+ return 0;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash.h b/drivers/input/touchscreen/focaltech_touch/focaltech_flash.h
index d1acff2..cb53404 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash.h
@@ -1,137 +1,205 @@
/************************************************************************
- * Copyright (C) 2010-2017, Focaltech Systems (R)£¬All Rights Reserved.
- *
- * File Name: focaltech_flash.h
- *
- * Author: fupeipei
- *
- * Created: 2016-08-07
- *
- * Abstract:
- *
- ************************************************************************/
+* Copyright (C) 2012-2019, Focaltech Systems (R)£¬All Rights Reserved.
+*
+* File Name: focaltech_flash.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-07
+*
+* Abstract:
+*
+************************************************************************/
#ifndef __LINUX_FOCALTECH_FLASH_H__
#define __LINUX_FOCALTECH_FLASH_H__
/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "focaltech_flash/focaltech_upgrade_common.h"
+* 1.Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-#define FTS_REG_ECC 0xCC
-#define FTS_RST_CMD_REG2 0xBC
-#define FTS_READ_ID_REG 0x90
-#define FTS_ERASE_APP_REG 0x61
-#define FTS_ERASE_PARAMS_CMD 0x63
-#define FTS_FW_WRITE_CMD 0xBF
-#define FTS_REG_RESET_FW 0x07
-#define FTS_RST_CMD_REG1 0xFC
-#define LEN_FLASH_ECC_MAX 0xFFFE
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_CMD_RESET 0x07
+#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR 0xAD
+#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR_LEN 4
+#define FTS_ROMBOOT_CMD_WRITE 0xAE
+#define FTS_ROMBOOT_CMD_START_APP 0x08
+#define FTS_DELAY_PRAMBOOT_START 10
+#define FTS_ROMBOOT_CMD_ECC 0xCC
+#define FTS_PRAM_SADDR 0x000000
+#define FTS_DRAM_SADDR 0xD00000
-#define FTS_PACKET_LENGTH 128
-#define FTS_SETTING_BUF_LEN 128
+#define FTS_CMD_READ 0x03
+#define FTS_CMD_READ_DELAY 1
+#define FTS_CMD_READ_LEN 4
+#define FTS_CMD_FLASH_TYPE 0x05
+#define FTS_CMD_FLASH_MODE 0x09
+#define FLASH_MODE_WRITE_FLASH_VALUE 0x0A
+#define FLASH_MODE_UPGRADE_VALUE 0x0B
+#define FLASH_MODE_LIC_VALUE 0x0C
+#define FLASH_MODE_PARAM_VALUE 0x0D
+#define FTS_CMD_ERASE_APP 0x61
+#define FTS_REASE_APP_DELAY 1350
+#define FTS_ERASE_SECTOR_DELAY 60
+#define FTS_RETRIES_REASE 50
+#define FTS_RETRIES_DELAY_REASE 200
+#define FTS_CMD_FLASH_STATUS 0x6A
+#define FTS_CMD_FLASH_STATUS_LEN 2
+#define FTS_CMD_FLASH_STATUS_NOP 0x0000
+#define FTS_CMD_FLASH_STATUS_ECC_OK 0xF055
+#define FTS_CMD_FLASH_STATUS_ERASE_OK 0xF0AA
+#define FTS_CMD_FLASH_STATUS_WRITE_OK 0x1000
+#define FTS_CMD_ECC_INIT 0x64
+#define FTS_CMD_ECC_CAL 0x65
+#define FTS_CMD_ECC_CAL_LEN 6
+#define FTS_RETRIES_ECC_CAL 10
+#define FTS_RETRIES_DELAY_ECC_CAL 50
+#define FTS_CMD_ECC_READ 0x66
+#define FTS_CMD_DATA_LEN 0xB0
+#define FTS_CMD_APP_DATA_LEN_INCELL 0x7A
+#define FTS_CMD_DATA_LEN_LEN 4
+#define FTS_CMD_WRITE 0xBF
+#define FTS_RETRIES_WRITE 100
+#define FTS_RETRIES_DELAY_WRITE 1
+#define FTS_CMD_WRITE_LEN 6
+#define FTS_DELAY_READ_ID 20
+#define FTS_DELAY_UPGRADE_RESET 80
+#define PRAMBOOT_MIN_SIZE 0x120
+#define PRAMBOOT_MAX_SIZE (64*1024)
+#define FTS_FLASH_PACKET_LENGTH 32 /* max=128 */
+#define FTS_MAX_LEN_ECC_CALC 0xFFFE /* must be even */
+#define FTS_MIN_LEN 0x120
+#define FTS_MAX_LEN_FILE (128 * 1024)
+#define FTS_MAX_LEN_APP (64 * 1024)
+#define FTS_MAX_LEN_SECTOR (4 * 1024)
+#define FTS_CONIFG_VENDORID_OFF 0x04
+#define FTS_CONIFG_MODULEID_OFF 0x1E
+#define FTS_CONIFG_PROJECTID_OFF 0x20
+#define FTS_APPINFO_OFF 0x100
+#define FTS_APPINFO_APPLEN_OFF 0x00
+#define FTS_APPINFO_APPLEN2_OFF 0x12
+#define FTS_REG_UPGRADE 0xFC
+#define FTS_REG_UPGRADE2 0xBC
+#define FTS_UPGRADE_AA 0xAA
+#define FTS_UPGRADE_55 0x55
+#define FTS_DELAY_UPGRADE_AA 10
+#define FTS_UPGRADE_LOOP 30
+#define FTS_HEADER_LEN 32
+#define FTS_FW_BIN_FILEPATH "/sdcard/"
+#define FTS_FW_IDE_SIG "IDE_"
+#define FTS_FW_IDE_SIG_LEN 4
+#define MAX_MODULE_VENDOR_NAME_LEN 16
-#define FTS_UPGRADE_LOOP 30
-#define AUTO_CLB_NEED 1
-#define AUTO_CLB_NONEED 0
-#define FTS_UPGRADE_AA 0xAA
-#define FTS_UPGRADE_55 0x55
-#define FTXXXX_INI_FILEPATH_CONFIG "/sdcard/"
+#define FTS_ROMBOOT_CMD_ECC_NEW_LEN 7
+#define FTS_ECC_FINISH_TIMEOUT 100
+#define FTS_ROMBOOT_CMD_ECC_FINISH 0xCE
+#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_A5 0xA5
+#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_00 0x00
+#define FTS_ROMBOOT_CMD_ECC_READ 0xCD
+#define AL2_FCS_COEF ((1 << 15) + (1 << 10) + (1 << 3))
+
+#define FTS_APP_INFO_OFFSET 0x100
enum FW_STATUS {
- FTS_RUN_IN_ERROR,
- FTS_RUN_IN_APP,
- FTS_RUN_IN_ROM,
- FTS_RUN_IN_PRAM,
- FTS_RUN_IN_BOOTLOADER
+ FTS_RUN_IN_ERROR,
+ FTS_RUN_IN_APP,
+ FTS_RUN_IN_ROM,
+ FTS_RUN_IN_PRAM,
+ FTS_RUN_IN_BOOTLOADER,
};
-enum FILE_SIZE_TYPE {
- FW_SIZE,
- FW2_SIZE,
- FW3_SIZE,
- PRAMBOOT_SIZE,
- LCD_CFG_SIZE
+enum FW_FLASH_MODE {
+ FLASH_MODE_APP,
+ FLASH_MODE_LIC,
+ FLASH_MODE_PARAM,
+ FLASH_MODE_ALL,
};
-/* pramboot */
-#define FTS_PRAMBOOT_8716 "include/pramboot/FT8716_Pramboot_V0.5_20160723.i"
-#define FTS_PRAMBOOT_E716 "include/pramboot/FT8716_Pramboot_V0.5_20160723.i"
-#define FTS_PRAMBOOT_8736 "include/pramboot/FT8736_Pramboot_V0.4_20160627.i"
-#define FTS_PRAMBOOT_8607 "include/pramboot/FT8607_Pramboot_V0.3_20160727.i"
-#define FTS_PRAMBOOT_8606 "include/pramboot/FT8606_Pramboot_V0.7_20150507.i"
-
-/* ic types */
-#if (FTS_CHIP_TYPE == _FT8716)
-#define FTS_UPGRADE_PRAMBOOT FTS_PRAMBOOT_8716
-#elif (FTS_CHIP_TYPE == _FTE716)
-#define FTS_UPGRADE_PRAMBOOT FTS_PRAMBOOT_E716
-#elif (FTS_CHIP_TYPE == _FT8736)
-#define FTS_UPGRADE_PRAMBOOT FTS_PRAMBOOT_8736
-#elif (FTS_CHIP_TYPE == _FT8607)
-#define FTS_UPGRADE_PRAMBOOT FTS_PRAMBOOT_8607
-#elif (FTS_CHIP_TYPE == _FT8606)
-#define FTS_UPGRADE_PRAMBOOT FTS_PRAMBOOT_8606
-#endif
-
-/* remove pramboot */
-#undef FTS_UPGRADE_PRAMBOOT
+enum ECC_CHECK_MODE {
+ ECC_CHECK_MODE_XOR,
+ ECC_CHECK_MODE_CRC16,
+};
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
/* IC info */
-
-struct fts_upgrade_fun {
- int (*get_i_file)(struct i2c_client *, int);
- int (*get_app_bin_file_ver)(struct i2c_client *, char *);
- int (*get_app_i_file_ver)(void);
- int (*upgrade_with_app_i_file)(struct i2c_client *);
- int (*upgrade_with_app_bin_file)(struct i2c_client *, char *);
- int (*upgrade_with_lcd_cfg_i_file)(struct i2c_client *);
- int (*upgrade_with_lcd_cfg_bin_file)(struct i2c_client *, char *);
+struct upgrade_func {
+ u64 ctype[FTX_MAX_COMPATIBLE_TYPE];
+ u32 fwveroff;
+ u32 fwcfgoff;
+ u32 appoff;
+ u32 licoff;
+ u32 paramcfgoff;
+ u32 paramcfgveroff;
+ u32 paramcfg2off;
+ int pram_ecc_check_mode;
+ int fw_ecc_check_mode;
+ bool new_return_value_from_ic;
+ bool appoff_handle_in_ic;
+ bool is_reset_register_BC;
+ bool read_boot_id_need_reset;
+ bool hid_supported;
+ bool pramboot_supported;
+ u8 *pramboot;
+ u32 pb_length;
+ int (*init)(u8 *, u32);
+ int (*upgrade)(u8 *, u32);
+ int (*get_hlic_ver)(u8 *);
+ int (*lic_upgrade)(u8 *, u32);
+ int (*param_upgrade)(u8 *, u32);
+ int (*force_upgrade)(u8 *, u32);
};
-extern struct fts_upgrade_fun fts_updatefun;
+
+struct upgrade_setting_nf {
+ u8 rom_idh;
+ u8 rom_idl;
+ u16 reserved;
+ u32 app2_offset;
+ u32 ecclen_max;
+ u8 eccok_val;
+ u8 upgsts_boot;
+ u8 delay_init;
+ bool spi_pe;
+ bool half_length;
+ bool fd_check;
+ bool drwr_support;
+};
+
+struct upgrade_module {
+ int id;
+ char vendor_name[MAX_MODULE_VENDOR_NAME_LEN];
+ u8 *fw_file;
+ u32 fw_len;
+};
+
+struct fts_upgrade {
+ struct fts_ts_data *ts_data;
+ struct upgrade_module *module_info;
+ struct upgrade_func *func;
+ struct upgrade_setting_nf *setting_nf;
+ int module_id;
+ bool fw_from_request;
+ u8 *fw;
+ u32 fw_length;
+ u8 *lic;
+ u32 lic_length;
+};
/*****************************************************************************
- * Static variables
- *****************************************************************************/
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+extern struct upgrade_func upgrade_func_ft5452;
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-extern u8 CTPM_FW[];
-extern u8 CTPM_FW2[];
-extern u8 CTPM_FW3[];
-extern u8 aucFW_PRAM_BOOT[];
-extern u8 CTPM_LCD_CFG[];
-extern u8 *g_fw_file;
-extern int g_fw_len;
-extern struct fts_upgrade_fun fts_updatefun_curr;
-extern struct ft_chip_t chip_types;
-
-#if FTS_AUTO_UPGRADE_EN
-extern struct workqueue_struct *touch_wq;
-extern struct work_struct fw_update_work;
+* Static function prototypes
+*****************************************************************************/
+int fts_fwupg_reset_in_boot(void);
+int fts_fwupg_enter_into_boot(void);
+int fts_fwupg_erase(u32 delay);
+int fts_fwupg_ecc_cal(u32 saddr, u32 len);
+int fts_flash_write_buf(u32 saddr, u8 *buf, u32 len, u32 delay);
+int fts_fwupg_upgrade(struct fts_upgrade *upg);
#endif
-
-void fts_ctpm_upgrade_init(void);
-void fts_ctpm_upgrade_exit(void);
-void fts_ctpm_upgrade_delay(u32 i);
-void fts_ctpm_get_upgrade_array(void);
-int fts_ctpm_auto_upgrade(struct i2c_client *client);
-int fts_fw_upgrade(struct device *dev, bool force);
-int fts_ctpm_auto_clb(struct i2c_client *client);
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-u32 fts_getsize(u8 fw_type);
-int fts_ctpm_i2c_hid2std(struct i2c_client *client);
-void fts_ctpm_rom_or_pram_reset(struct i2c_client *client);
-enum FW_STATUS fts_ctpm_get_pram_or_rom_id(struct i2c_client *client);
-#endif
-
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/Makefile b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/Makefile
index 9b3a4bb..43deb4a 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/Makefile
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/Makefile
@@ -1,17 +1 @@
-#
-# Makefile for the focaltech touchscreen drivers.
-#
-
-# Each configuration option enables a list of files.
-
-
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft5x46.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft5822.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft6336gu.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft8006.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft8606.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft8607.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft8716.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft8736.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_idc.o
-obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_test.o
\ No newline at end of file
+obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_upgrade_ft3518.o
\ No newline at end of file
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_common.h b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_common.h
deleted file mode 100644
index e3b00e5..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_common.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/************************************************************************
- * Copyright (C) 2010-2017, Focaltech Systems (R)£¬All Rights Reserved.
- *
- * File Name: focaltech_upgrade_common.h
- *
- * Author: fupeipei
- *
- * Created: 2016-08-16
- *
- * Abstract:
- *
- ************************************************************************/
-#ifndef __LINUX_FOCALTECH_UPGRADE_COMMON_H__
-#define __LINUX_FOCALTECH_UPGRADE_COMMON_H__
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_flash.h"
-
-/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-
-/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-int fts_ctpm_erase_flash(struct i2c_client *client);
-int fts_ctpm_pramboot_ecc(struct i2c_client *client);
-bool fts_ctpm_check_run_state(struct i2c_client *client, int state);
-void fts_ctpm_start_pramboot(struct i2c_client *client);
-int fts_ctpm_start_fw_upgrade(struct i2c_client *client);
-bool fts_ctpm_check_in_pramboot(struct i2c_client *client);
-int fts_ctpm_upgrade_idc_init(struct i2c_client *client);
-int fts_ctpm_write_app_for_idc(struct i2c_client *client,
- u32 length, u8 *readbuf);
-int fts_ctpm_upgrade_ecc(struct i2c_client *client, u32 startaddr, u32 length);
-int fts_ctpm_write_pramboot_for_idc(struct i2c_client *client,
- u32 length, u8 *readbuf);
-int fts_writeflash(struct i2c_client *client, u32 writeaddr,
- u32 length, u8 *readbuf, u32 cnt);
-bool fts_check_app_bin_valid_idc(u8 *pbt_buf);
-
-int fts_ctpm_get_app_ver(void);
-int fts_ctpm_fw_upgrade(struct i2c_client *client);
-int fts_ctpm_lcd_cfg_upgrade(struct i2c_client *client);
-
-#endif
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft3518.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft3518.c
new file mode 100644
index 0000000..b4869dc
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft3518.c
@@ -0,0 +1,186 @@
+/*
+ *
+ * FocalTech fts TouchScreen driver.
+ *
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+/*****************************************************************************
+*
+* File Name: focaltech_upgrade_ft5452.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-15
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+/*****************************************************************************
+* 1.Included header files
+*****************************************************************************/
+#include "../focaltech_flash.h"
+
+/************************************************************************
+* Name: fts_ft5452_upgrade
+* Brief:
+* Input:
+* Output:
+* Return: return 0 if success, otherwise return error code
+***********************************************************************/
+static int fts_ft5452_upgrade(u8 *buf, u32 len)
+{
+ int ret = 0;
+ u32 start_addr = 0;
+ u8 cmd[4] = { 0 };
+ int ecc_in_host = 0;
+ int ecc_in_tp = 0;
+
+ int i = 0;
+ u8 wbuf[7] = { 0 };
+ u8 reg_val[4] = {0};
+
+ if (NULL == buf) {
+ FTS_ERROR("fw buf is null");
+ return -EINVAL;
+ }
+
+ if ((len < FTS_MIN_LEN) || (len > (60 * 1024))) {
+ FTS_ERROR("fw buffer len(%x) fail", len);
+ return -EINVAL;
+ }
+
+ /* enter into upgrade environment */
+ ret = fts_fwupg_enter_into_boot();
+ if (ret < 0) {
+ FTS_ERROR("enter into pramboot/bootloader fail,ret=%d", ret);
+ goto fw_reset;
+ }
+
+ cmd[0] = FTS_CMD_FLASH_MODE;
+ cmd[1] = FLASH_MODE_UPGRADE_VALUE;
+ ret = fts_write(cmd, 2);
+ if (ret < 0) {
+ FTS_ERROR("upgrade mode(09) cmd write fail");
+ goto fw_reset;
+ }
+
+ cmd[0] = FTS_CMD_DATA_LEN;
+ cmd[1] = BYTE_OFF_16(len);
+ cmd[2] = BYTE_OFF_8(len);
+ cmd[3] = BYTE_OFF_0(len);
+ ret = fts_write(cmd, FTS_CMD_DATA_LEN_LEN);
+ if (ret < 0) {
+ FTS_ERROR("data len cmd write fail");
+ goto fw_reset;
+ }
+
+ ret = fts_fwupg_erase(FTS_REASE_APP_DELAY);
+ if (ret < 0) {
+ FTS_ERROR("erase cmd write fail");
+ goto fw_reset;
+ }
+
+ /* write app */
+ start_addr = upgrade_func_ft5452.appoff;
+ ecc_in_host = fts_flash_write_buf(start_addr, buf, len, 1);
+ if (ecc_in_host < 0 ) {
+ FTS_ERROR("lcd initial code write fail");
+ goto fw_reset;
+ }
+
+ FTS_INFO( "**********read out checksum**********");
+
+ /* check sum init */
+ wbuf[0] = FTS_CMD_ECC_INIT;
+ ret = fts_write(wbuf, 1);
+ if (ret < 0) {
+ FTS_ERROR("ecc init cmd write fail");
+ return ret;
+ }
+
+ /* send commond to start checksum */
+ wbuf[0] = FTS_CMD_ECC_CAL;
+ wbuf[1] = BYTE_OFF_16(start_addr);
+ wbuf[2] = BYTE_OFF_8(start_addr);
+ wbuf[3] = BYTE_OFF_0(start_addr);
+
+ wbuf[4] = BYTE_OFF_16(len);
+ wbuf[5] = BYTE_OFF_8(len);
+ wbuf[6] = BYTE_OFF_0(len);
+
+ FTS_DEBUG("ecc calc startaddr:0x%04x, len:%d", start_addr, len);
+ ret = fts_write(wbuf, 7);
+ if (ret < 0) {
+ FTS_ERROR("ecc calc cmd write fail");
+ return ret;
+ }
+
+ msleep(len / 256);
+
+ /* read status if check sum is finished */
+ for (i = 0; i < FTS_RETRIES_ECC_CAL; i++) {
+ wbuf[0] = FTS_CMD_FLASH_STATUS;
+ reg_val[0] = reg_val[1] = 0x00;
+ fts_read(wbuf, 1, reg_val, 2);
+ FTS_DEBUG("[UPGRADE]: reg_val[0]=%02x reg_val[0]=%02x!!", reg_val[0], reg_val[1]);
+ if ((0xF0 == reg_val[0]) && (0x55 == reg_val[1])) {
+ break;
+ }
+ msleep(FTS_RETRIES_DELAY_ECC_CAL);
+ }
+
+ /* read out check sum */
+ wbuf[0] = FTS_CMD_ECC_READ;
+ ret = fts_read(wbuf, 1, reg_val, 1);
+ if (ret < 0) {
+ FTS_ERROR( "ecc read cmd write fail");
+ return ret;
+ }
+ ecc_in_tp = reg_val[0];
+
+ FTS_INFO("ecc in tp:%x, host:%x", ecc_in_tp, ecc_in_host);
+ if (ecc_in_tp != ecc_in_host) {
+ FTS_ERROR("ecc check fail");
+ goto fw_reset;
+ }
+
+ FTS_INFO("upgrade success, reset to normal boot");
+ ret = fts_fwupg_reset_in_boot();
+ if (ret < 0) {
+ FTS_ERROR("reset to normal boot fail");
+ }
+
+ msleep(200);
+ return 0;
+
+fw_reset:
+ FTS_INFO("upgrade fail, reset to normal boot");
+ ret = fts_fwupg_reset_in_boot();
+ if (ret < 0) {
+ FTS_ERROR("reset to normal boot fail");
+ }
+ return -EIO;
+}
+
+struct upgrade_func upgrade_func_ft5452 = {
+ .ctype = {0x81},
+ .fwveroff = 0x010E,
+ .fwcfgoff = 0x1FFB0,
+ .appoff = 0x0000,
+ .pramboot_supported = false,
+ .hid_supported = true,
+ .upgrade = fts_ft5452_upgrade,
+};
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5822.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5822.c
deleted file mode 100644
index 2133c06..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5822.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft5822.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (IC_SERIALS == 0x01)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (60 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10A)
-#define APP_FILE_VENDORID_MAPPING (0x108)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0xFFB0)
-#define CONFIG_VENDOR_ID_OFFSET (0x4)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ft5822_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ft5822_get_app_i_file_ver(void);
-static int fts_ft5822_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ft5822_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ft5822_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
-
- .get_i_file = fts_ft5822_get_i_file,
- .get_app_bin_file_ver = fts_ft5822_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ft5822_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ft5822_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ft5822_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ft5822_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ft5822_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 reg_val[2] = {0};
- u32 i = 0;
- u8 rw_buf[10];
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- rw_buf[0] = FTS_UPGRADE_55;
- rw_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, rw_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*check run in bootloader or not*/
- usleep_range(1000, 2000);
- rw_buf[0] = FTS_READ_ID_REG;
- rw_buf[1] = rw_buf[2] = rw_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, rw_buf, 4, reg_val, 2);
-
- FTS_DEBUG("[UPGRADE]: ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == chip_types.bootloader_idh)
- && (reg_val[1] == chip_types.bootloader_idl)) {
- FTS_DEBUG("[UPGRADE]: read bootloader id ok!!");
- break;
- }
-
- FTS_ERROR("[UPGRADE]: read bootloader id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP)
- return -EIO;
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- usleep_range(10000, 20000); /*must wait, otherwise read vendor id fail*/
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
-
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
-
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ft5822_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ft5822_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid)
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- else
- ret = fts_ft5822_get_vendor_id_flash(client, &vendor_id);
-
- FTS_DEBUG("[UPGRADE] tp_vendor_id=%x", vendor_id);
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
-
- FTS_INFO("[UPGRADE]tp vendor id:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ft5822_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft5822_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ft5822_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft5822_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-#define AL2_FCS_COEF ((1 << 7) + (1 << 6) + (1 << 5))
-/*****************************************************************************
- * Name: ecc_calc
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static u8 ecc_calc(u8 *pbt_buf, u16 start, u16 length)
-{
- u8 cFcs = 0;
- u16 i, j;
-
- for (i = 0; i < length; i++) {
- cFcs ^= pbt_buf[start++];
- for (j = 0; j < 8; j++) {
- if (cFcs & 1)
- cFcs = (u8)((cFcs >> 1) ^ AL2_FCS_COEF);
- else
- cFcs >>= 1;
- }
- }
- return cFcs;
-}
-
-/*****************************************************************************
- * Name: fts_check_app_bin_valid
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static bool fts_check_app_bin_valid(u8 *pbt_buf)
-{
- u8 ecc1;
- u8 ecc2;
- u8 ecc3;
- u8 ecc4;
- u16 len1;
- u16 len2;
- u8 cal_ecc1;
- u8 cal_ecc2;
- u16 usAddrInfo;
-
- /* 1. First Byte */
- if (pbt_buf[0] != 0x02) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- the first byte(%x) error",
- pbt_buf[0]);
- return false;
- }
-
- usAddrInfo = 0x100;
-
- /* 2.len */
- len1 = pbt_buf[usAddrInfo++] << 8;
- len1 += pbt_buf[usAddrInfo++];
-
- len2 = pbt_buf[usAddrInfo++] << 8;
- len2 += pbt_buf[usAddrInfo++];
-
- if ((len1 + len2) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- LENGTH(%04x) XOR error",
- len1);
- return false;
- }
-
- /* 3.ecc */
- ecc1 = pbt_buf[usAddrInfo++];
- ecc2 = pbt_buf[usAddrInfo++];
- ecc3 = pbt_buf[usAddrInfo++];
- ecc4 = pbt_buf[usAddrInfo++];
-
- if (((ecc1 + ecc2) != 0xFF) || ((ecc3 + ecc4) != 0xFF)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC(%x %x) XOR error",
- ecc1, ecc2);
- return false;
- }
-
- cal_ecc1 = ecc_calc(pbt_buf, 0x0, 0x100);
- cal_ecc2 = ecc_calc(pbt_buf, 0x100 + 0x20, len1 - (0x100 + 0x20));
- if ((ecc1 != cal_ecc1) || (ecc3 != cal_ecc2)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC calc error");
- return false;
- }
- return true;
-}
-
-/************************************************************************
- * Name: fts_ft5822_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ft5822_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u8 reg_val[4] = {0};
- u32 i = 0;
- u32 packet_number;
- u32 j = 0;
- u32 temp;
- u32 length;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 upgrade_ecc;
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- /*********Step 1:Reset CTPM *****/
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
- usleep_range(10000, 20000);
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
- msleep(200);
-
- /*********Step 2:Enter upgrade mode *****/
- fts_ctpm_i2c_hid2std(client);
- usleep_range(5000, 10000);
-
- auc_i2c_write_buf[0] = FTS_UPGRADE_55;
- auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*********Step 3:Check bootloader ID *****/
- usleep_range(1000, 2000);
- auc_i2c_write_buf[0] = FTS_READ_ID_REG;
- auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
- auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- FTS_DEBUG("[UPGRADE]:ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == chip_types.bootloader_idh)
- && (reg_val[1] == chip_types.bootloader_idl)) {
- FTS_DEBUG("[UPGRADE]: read bootload id ok!!");
- break;
- }
-
- FTS_ERROR("[UPGRADE]: read bootload id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP) {
- FTS_ERROR("[UPGRADE]:failed writing 0x55 and 0xaa:i = %d!!", i);
- return -EIO;
- }
-
- /*Step 4:erase app and panel paramenter area*/
- FTS_DEBUG("[UPGRADE]: erase app and panel paramenter area!!");
- auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1350);
- for (i = 0; i < 15; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- if ((reg_val[0] == 0xF0) && (reg_val[1] == 0xAA))
- break;
- msleep(50);
- }
- FTS_DEBUG("[UPGRADE]:erase app area reg_val[0] = %x reg_val[1] = %x!!",
- reg_val[0], reg_val[1]);
-
- auc_i2c_write_buf[0] = 0xB0;
- auc_i2c_write_buf[1] = (u8) ((dw_length >> 16) & 0xFF);
- auc_i2c_write_buf[2] = (u8) ((dw_length >> 8) & 0xFF);
- auc_i2c_write_buf[3] = (u8) (dw_length & 0xFF);
- fts_i2c_write(client, auc_i2c_write_buf, 4);
-
- /*********Step 5:write firmware(FW) to ctpm flash*********/
- upgrade_ecc = 0;
- FTS_DEBUG("[UPGRADE]: write FW to ctpm flash!!");
- temp = 0;
- packet_number = (dw_length) / FTS_PACKET_LENGTH;
- packet_buf[0] = FTS_FW_WRITE_CMD;
- packet_buf[1] = 0x00;
-
- for (j = 0; j < packet_number; j++) {
- temp = j * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- length = FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (length >> 8);
- packet_buf[5] = (u8) length;
- for (i = 0; i < FTS_PACKET_LENGTH; i++) {
- packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
-
- fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
- usleep_range(10000, 20000);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
- break;
- FTS_DEBUG("[UPGRADE]: reg_val[0] = %x reg_val[1] = %x",
- reg_val[0], reg_val[1]);
- /* msleep(1); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- if ((dw_length) % FTS_PACKET_LENGTH > 0) {
- temp = packet_number * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- temp = (dw_length) % FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = pbt_buf[packet_number
- * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, temp + 6);
- usleep_range(10000, 20000);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((0x1000 + ((packet_number * FTS_PACKET_LENGTH)
- /((dw_length) % FTS_PACKET_LENGTH)))
- == (((reg_val[0]) << 8) | reg_val[1]))
- break;
- FTS_DEBUG("[UPGRADE]: reg_val[0] = %x!!", reg_val[0]);
- FTS_DEBUG("[UPGRADE]: reg_val[1] = %x!!", reg_val[1]);
- FTS_DEBUG("[UPGRADE]: reg_val[2] = %x!!",
- (((packet_number * FTS_PACKET_LENGTH)
- /((dw_length) % FTS_PACKET_LENGTH))+0x1000));
- /* msleep(1); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- msleep(50);
-
- /*********Step 6: read out checksum***********************/
- /*send the opration head */
- FTS_DEBUG("[UPGRADE]: read out checksum!!");
- auc_i2c_write_buf[0] = 0x64;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- temp = 0;
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(temp >> 16);
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = dw_length;
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(dw_length/256);
-
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- FTS_DEBUG("[UPGRADE]: reg_val[0]=%02x reg_val[0]=%02x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == 0xF0) && (reg_val[1] == 0x55))
- break;
- usleep_range(1000, 2000);
- }
- auc_i2c_write_buf[0] = 0x66;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
-
- FTS_DEBUG("[UPGRADE]: checksum %x %x!!", reg_val[0], upgrade_ecc);
-
- FTS_DEBUG("[UPGRADE]: reset the new FW!!");
- auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(200);
-
- fts_ctpm_i2c_hid2std(client);
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ft5822_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ft5822_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ft5822_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ft5822_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ft5822_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- pbt_buf = (u8 *)fw->data;
- if (pbt_buf[APP_FILE_CHIPID_MAPPING] != chip_types.chip_idh) {
- FTS_ERROR("[UPGRADE]: chip id error, app.bin upgrade failed!!");
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = fts_check_app_bin_valid(pbt_buf);
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ft5822_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* FT5822 */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5x46.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5x46.c
deleted file mode 100644
index 77f3c58..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft5x46.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft5x46.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (IC_SERIALS == 0x02)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (60 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define CONFIG_START_ADDR (0xD780)
-#define CONFIG_VENDOR_ID_OFFSET (0x04)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ft5x46_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ft5x46_get_app_i_file_ver(void);
-static int fts_ft5x46_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ft5x46_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ft5x46_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
-
- .get_i_file = fts_ft5x46_get_i_file,
- .get_app_bin_file_ver = fts_ft5x46_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ft5x46_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ft5x46_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ft5x46_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ft5x46_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ft5x46_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 reg_val[2] = {0};
- u32 i = 0;
- u8 rw_buf[10];
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- rw_buf[0] = FTS_UPGRADE_55;
- rw_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, rw_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*check run in bootloader or not*/
- usleep_range(1000, 2000);
- rw_buf[0] = FTS_READ_ID_REG;
- rw_buf[1] = rw_buf[2] = rw_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, rw_buf, 4, reg_val, 2);
-
- FTS_DEBUG("[UPGRADE]:ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == chip_types.bootloader_idh)
- && (reg_val[1] == chip_types.bootloader_idl)) {
- FTS_DEBUG("[UPGRADE]: read bootloader id ok!!");
- break;
- }
-
- FTS_ERROR("[UPGRADE]: read bootloader id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP)
- return -EIO;
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- usleep_range(10000, 20000); /*must wait, otherwise read vendor id fail*/
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ft5x46_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ft5x46_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid)
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- else
- ret = fts_ft5x46_get_vendor_id_flash(client, &vendor_id);
-
- FTS_DEBUG("[UPGRADE] tp_vendor_id=%x", vendor_id);
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
-
- FTS_INFO("[UPGRADE]tp vendor id:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ft5x46_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft5x46_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size > 2)
- fw_ver = fw->data[fw->size - 2];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ft5x46_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft5x46_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[fwsize-2];
-}
-
-#define AL2_FCS_COEF ((1 << 7) + (1 << 6) + (1 << 5))
-/*****************************************************************************
- * Name: ecc_calc
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static u8 ecc_calc(u8 *pbt_buf, u16 start, u16 length)
-{
- u8 cFcs = 0;
- u16 i, j;
-
- for (i = 0; i < length; i++) {
- cFcs ^= pbt_buf[start++];
- for (j = 0; j < 8; j++) {
- if (cFcs & 1)
- cFcs = (u8)((cFcs >> 1) ^ AL2_FCS_COEF);
- else
- cFcs >>= 1;
- }
- }
- return cFcs;
-}
-
-/*****************************************************************************
- * Name: fts_check_app_bin_valid
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static bool fts_check_app_bin_valid(u8 *pbt_buf, u32 dw_length)
-{
- u8 ecc1;
- u8 ecc2;
- u16 len1;
- u16 len2;
- u8 cal_ecc;
- u16 usAddrInfo;
-
- /* 1. First Byte */
- if (pbt_buf[0] != 0x02) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- the first byte(%x) error",
- pbt_buf[0]);
- return false;
- }
-
- usAddrInfo = dw_length - 8;
-
- /* 2.len */
- len1 = pbt_buf[usAddrInfo++] << 8;
- len1 += pbt_buf[usAddrInfo++];
-
- len2 = pbt_buf[usAddrInfo++] << 8;
- len2 += pbt_buf[usAddrInfo++];
-
- if ((len1 + len2) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- LENGTH(%04x) XOR error",
- len1);
- return false;
- }
-
- /* 3.ecc */
- ecc1 = pbt_buf[usAddrInfo++];
- ecc2 = pbt_buf[usAddrInfo++];
-
- if ((ecc1 + ecc2) != 0xFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC(%x) XOR error", ecc1);
- return false;
- }
-
- cal_ecc = ecc_calc(pbt_buf, 0x0, len1);
-
- if (ecc1 != cal_ecc) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC calc error");
- return false;
- }
- return true;
-}
-
-
-/************************************************************************
- * Name: fts_ft5x46_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ft5x46_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u8 reg_val[4] = {0};
- u32 i = 0;
- u32 packet_number;
- u32 j = 0;
- u32 temp;
- u32 length;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 upgrade_ecc;
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- /*********Step 1:Reset CTPM *****/
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
- usleep_range(10000, 20000);
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
- msleep(200);
-
- /*********Step 2:Enter upgrade mode *****/
- fts_ctpm_i2c_hid2std(client);
- usleep_range(5000, 10000);
-
- auc_i2c_write_buf[0] = FTS_UPGRADE_55;
- auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*********Step 3:Check bootloader ID *****/
- usleep_range(1000, 2000);
- auc_i2c_write_buf[0] = FTS_READ_ID_REG;
- auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
- auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- FTS_DEBUG("[UPGRADE]: ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == chip_types.bootloader_idh)
- && (reg_val[1] == chip_types.bootloader_idl)) {
- FTS_DEBUG("[UPGRADE]: read bootload id ok!!");
- break;
- }
-
- FTS_ERROR("[UPGRADE]: read bootload id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP) {
- FTS_ERROR("[UPGRADE]:failed writing 0x55 and 0xaa:i = %d!!", i);
- return -EIO;
- }
-
- /*Step 4:erase app and panel paramenter area*/
- FTS_DEBUG("[UPGRADE]: erase app and panel paramenter area!!");
- auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1350);
- for (i = 0; i < 15; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- if ((reg_val[0] == 0xF0) && (reg_val[1] == 0xAA))
- break;
- msleep(50);
- }
- FTS_DEBUG("[UPGRADE]:erase app area reg_val[0] = %x reg_val[1] = %x!!",
- reg_val[0], reg_val[1]);
-
- auc_i2c_write_buf[0] = 0xB0;
- auc_i2c_write_buf[1] = (u8) ((dw_length >> 16) & 0xFF);
- auc_i2c_write_buf[2] = (u8) ((dw_length >> 8) & 0xFF);
- auc_i2c_write_buf[3] = (u8) (dw_length & 0xFF);
- fts_i2c_write(client, auc_i2c_write_buf, 4);
-
- /*********Step 5:write firmware(FW) to ctpm flash*********/
- upgrade_ecc = 0;
- FTS_DEBUG("[UPGRADE]: write FW to ctpm flash!!");
- temp = 0;
- packet_number = (dw_length) / FTS_PACKET_LENGTH;
- packet_buf[0] = FTS_FW_WRITE_CMD;
- packet_buf[1] = 0x00;
-
- for (j = 0; j < packet_number; j++) {
- temp = j * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- length = FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (length >> 8);
- packet_buf[5] = (u8) length;
- for (i = 0; i < FTS_PACKET_LENGTH; i++) {
- packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
- usleep_range(10000, 20000);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
- break;
- FTS_DEBUG("[UPGRADE]:reg_val[0] = %x reg_val[1] = %x!!",
- reg_val[0], reg_val[1]);
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- if ((dw_length) % FTS_PACKET_LENGTH > 0) {
- temp = packet_number * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- temp = (dw_length) % FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = pbt_buf[packet_number
- * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, temp + 6);
- usleep_range(10000, 20000);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((0x1000 + ((packet_number * FTS_PACKET_LENGTH)
- /((dw_length) % FTS_PACKET_LENGTH))) ==
- (((reg_val[0]) << 8) | reg_val[1]))
- break;
- FTS_DEBUG("[UPGRADE]: reg_val[0] = %x!!", reg_val[0]);
- FTS_DEBUG("[UPGRADE]: reg_val[1] = %x!!", reg_val[1]);
- FTS_DEBUG("[UPGRADE]: reg_val[2] = 0x%x!!",
- (((packet_number * FTS_PACKET_LENGTH)
- /((dw_length) % FTS_PACKET_LENGTH))+0x1000));
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- msleep(50);
-
- /*********Step 6: read out checksum***********************/
- /*send the opration head */
- FTS_DEBUG("[UPGRADE]: read out checksum!!");
- auc_i2c_write_buf[0] = 0x64;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- temp = 0;
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(temp >> 16);
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = dw_length;
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(dw_length/256);
-
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- FTS_DEBUG("[UPGRADE]: reg_val[0]=%02x reg_val[0]=%02x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == 0xF0) && (reg_val[1] == 0x55))
- break;
- usleep_range(1000, 2000);
- }
- auc_i2c_write_buf[0] = 0x66;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
- FTS_DEBUG("[UPGRADE]: checksum %x %x!!", reg_val[0], upgrade_ecc);
-
- FTS_DEBUG("[UPGRADE]: reset the new FW!!");
- auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(200);
-
- fts_ctpm_i2c_hid2std(client);
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ft5x46_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ft5x46_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ft5x46_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ft5x46_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ft5x46_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- pbt_buf = (u8 *)fw->data;
- ecc_ok = fts_check_app_bin_valid(pbt_buf, fw->size);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ft5x46_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* FT5X46 */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft6336gu.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft6336gu.c
deleted file mode 100644
index 7516ab2..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft6336gu.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft6336GU.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if ((IC_SERIALS == 0x03) || (IC_SERIALS == 0x04))
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (60 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10A)
-#define APP_FILE_VENDORID_MAPPING (0x10C)
-#define CONFIG_START_ADDR (0x7B0)
-#define CONFIG_VENDOR_ID_OFFSET (0x4)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-
-#define APP_LEN 0x00
-#define APP_LEN_NE 0x02
-#define APP_P1_ECC 0x04
-#define APP_P1_ECC_NE 0x05
-#define APP_P2_ECC 0x06
-#define APP_P2_ECC_NE 0x07
-
-#define APP1_START 0x00
-#define APP1_LEN 0x100
-#define APP_VERIF_ADDR (APP1_START + APP1_LEN)
-#define APP_VERIF_LEN 0x20
-#define APP1_ECC_ADDR (APP_VERIF_ADDR + APP_P1_ECC)
-#define APP2_START (APP_VERIF_ADDR + APP_VERIF_LEN)
-#define APP2_ECC_ADDR (APP_VERIF_ADDR + APP_P2_ECC)
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ft6x36gu_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ft6x36gu_get_app_i_file_ver(void);
-static int fts_ft6x36gu_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ft6x36gu_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ft6x36gu_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
-
- .get_i_file = fts_ft6x36gu_get_i_file,
- .get_app_bin_file_ver = fts_ft6x36gu_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ft6x36gu_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ft6x36gu_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ft6x36gu_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ft6x36gu_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ft6x36gu_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 reg_val[2] = {0};
- u32 i = 0;
- u8 rw_buf[10];
- int i_ret;
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- rw_buf[0] = FTS_UPGRADE_55;
- rw_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, rw_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*check run in bootloader or not*/
- usleep_range(1000, 2000);
- rw_buf[0] = FTS_READ_ID_REG;
- rw_buf[1] = rw_buf[2] = rw_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, rw_buf, 4, reg_val, 2);
-
- FTS_DEBUG("[UPGRADE]: ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
- if ((reg_val[0] == chip_types.bootloader_idh)
- && (reg_val[1] == chip_types.bootloader_idl)) {
- FTS_DEBUG("[UPGRADE]: read bootloader id ok!! ");
- break;
- }
- FTS_ERROR("[UPGRADE]: read bootloader id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP)
- return -EIO;
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- usleep_range(10000, 20000); /*must wait, otherwise read vendor id fail*/
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ft6x36gu_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ft6x36gu_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = -EIO;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid)
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- else
- ret = fts_ft6x36gu_get_vendor_id_flash(client, &vendor_id);
-
- FTS_DEBUG("[UPGRADE] tp_vendor_id=%x", vendor_id);
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
-
- FTS_INFO("[UPGRADE]tp vendor id:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ft6x36gu_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft6x36gu_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ft6x36gu_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ft6x36gu_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/*****************************************************************************
- * Name: fts_check_app_bin_valid
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static bool fts_check_app_bin_valid(u8 *buf)
-{
- int i;
- u16 len;
- u16 len_neg;
- u16 ecc2_len = 0;
- u8 cal_ecc = 0;
- u8 cal_ecc2 = 0;
-
- FTS_INFO("[UPGRADE] Check APP.BIN ECC");
-
- /* 1. start code byte */
- if (buf[0] != 0x02) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- the first byte(%x) error",
- buf[0]);
- return false;
- }
-
- /* 2. len */
- len = ((u16)buf[APP_VERIF_ADDR + APP_LEN] << 8)
- + buf[APP_VERIF_ADDR + APP_LEN + 1];
- len_neg = (u16)(buf[APP_VERIF_ADDR + APP_LEN_NE] << 8)
- + buf[APP_VERIF_ADDR + APP_LEN_NE + 1];
- if ((len ^ len_neg) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- LENGTH(%04x) XOR error",
- len);
- return false;
- }
-
- /* 3. ecc */
- if (((buf[APP1_ECC_ADDR] ^ buf[APP1_ECC_ADDR+1]) != 0xFF)
- || ((buf[APP2_ECC_ADDR] ^ buf[APP2_ECC_ADDR+1]) != 0xFF)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC(%x %x) XOR error",
- buf[APP1_ECC_ADDR], buf[APP2_ECC_ADDR]);
- return false;
- }
-
- /* APP1 */
- for (i = 0; i < APP1_LEN; i++)
- cal_ecc ^= buf[APP1_START+i];
- /* APP2 */
- ecc2_len = ((u16)buf[APP_VERIF_ADDR+0x10] << 8)
- + buf[APP_VERIF_ADDR+0x11];
- ecc2_len = len - APP1_LEN - APP_VERIF_LEN - ecc2_len;
- for (i = 0; i < ecc2_len; i++)
- cal_ecc2 ^= buf[APP2_START+i];
-
- if ((cal_ecc != buf[APP1_ECC_ADDR])
- || (cal_ecc2 != buf[APP2_ECC_ADDR])) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC(%x %x) calc error",
- cal_ecc, cal_ecc2);
- return false;
- }
-
- return true;
-}
-
-
-/************************************************************************
- * Name: fts_ft6x36gu_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ft6x36gu_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u8 reg_val[2] = {0};
- u32 i = 0;
- u32 packet_number;
- u32 j;
- u32 temp;
- u32 length;
- u32 fw_length;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 upgrade_ecc;
-
- FTS_FUNC_ENTER();
-
- /*if the first byte of app is not 0x02,
- *the app is invaild, can not upgrade
- */
- if (pbt_buf[0] != 0x02) {
- FTS_ERROR("[UPGRADE]: app first byte != 0x02. cannot upgrade!");
- return -EINVAL;
- }
-
- /*check app length*/
- if (dw_length > 0x11f) {
- fw_length = ((u32)pbt_buf[0x100]<<8) + pbt_buf[0x101];
- if (dw_length < fw_length) {
- FTS_ERROR("[UPGRADE]: Fw length error!!");
- return -EINVAL;
- }
- } else {
- FTS_ERROR("[UPGRADE]: Fw length error!!");
- return -EINVAL;
- }
-
- /*send upgrade commond*/
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- /*send 0xAA and 0x55 to fw(0xFC reg), and start upgrade*/
- fts_i2c_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_AA);
- usleep_range(10000, 20000);
- fts_i2c_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_55);
- usleep_range(10000, 20000);
-
- /*upgrade init in ROM*/
- auc_i2c_write_buf[0] = FTS_UPGRADE_55;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- auc_i2c_write_buf[0] = FTS_UPGRADE_AA;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- usleep_range(10000, 20000);
-
- /*check run in ROM now*/
- auc_i2c_write_buf[0] = FTS_READ_ID_REG;
- auc_i2c_write_buf[1] = auc_i2c_write_buf[2]
- = auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = 0x00;
- reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
-
- if (reg_val[0] == chip_types.bootloader_idh
- && reg_val[1] == chip_types.bootloader_idl)
- break;
- }
-
- if (i >= FTS_UPGRADE_LOOP) {
- FTS_ERROR("[UPGRADE]: get bootload id error !!");
- return -EIO;
- }
-
- /*erase app in flash*/
- FTS_INFO("[UPGRADE]: erase app!!");
- auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(2000);
-
- for (i = 0; i < 200; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- auc_i2c_write_buf[1] = 0x00;
- auc_i2c_write_buf[2] = 0x00;
- auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = 0x00;
- reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- if (0xb0 == reg_val[0] && 0x02 == reg_val[1]) {
- FTS_INFO("[UPGRADE]: erase app finished!!");
- break;
- }
- msleep(50);
- }
-
- /*write app to flash*/
- upgrade_ecc = 0;
- FTS_INFO("[UPGRADE]: write app to flash!!");
-
- dw_length = fw_length;
- packet_number = (dw_length) / FTS_PACKET_LENGTH;
- packet_buf[0] = FTS_FW_WRITE_CMD;
- packet_buf[1] = 0x00;
-
- for (j = 0; j < packet_number; j++) {
- temp = j * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- length = FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (length >> 8);
- packet_buf[5] = (u8) length;
-
- for (i = 0; i < FTS_PACKET_LENGTH; i++) {
- packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
-
- fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- auc_i2c_write_buf[1] = 0x00;
- auc_i2c_write_buf[2] = 0x00;
- auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = 0x00;
- reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- if (0xb0 == (reg_val[0] & 0xf0) && (0x03 + (j % 0x0ffd))
- == (((reg_val[0] & 0x0f) << 8) | reg_val[1]))
- break;
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- if ((dw_length) % FTS_PACKET_LENGTH > 0) {
- temp = packet_number * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- temp = (dw_length) % FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
-
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = pbt_buf[packet_number
- * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
-
- fts_i2c_write(client, packet_buf, temp + 6);
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- auc_i2c_write_buf[1] = 0x00;
- auc_i2c_write_buf[2] = 0x00;
- auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = 0x00;
- reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- if (0xb0 == (reg_val[0] & 0xf0) && (0x03 + (j % 0x0ffd))
- == (((reg_val[0] & 0x0f) << 8) | reg_val[1]))
- break;
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- /*read out checksum*/
- FTS_INFO("[UPGRADE]: read out checksum!!");
- auc_i2c_write_buf[0] = FTS_REG_ECC;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- /*check sum error, upgrade fail*/
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error : FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
- FTS_INFO("[UPGRADE]: ecc ok!!");
-
- /*upgrade success, reset the new FW*/
- FTS_INFO("[UPGRADE]: reset the new FW!!");
- auc_i2c_write_buf[0] = 0x07;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ft6x36gu_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ft6x36gu_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ft6x36gu_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ft6x36gu_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ft6x36gu_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- pbt_buf = (u8 *)fw->data;
- ecc_ok = fts_check_app_bin_valid(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ft6x36gu_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* FT6x36GU */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8006.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8006.c
deleted file mode 100644
index 246d2b9..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8006.c
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft8006.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (FTS_CHIP_TYPE == _FT8006)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (93 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10E)
-#define APP_FILE_VENDORID_MAPPING (0x10C)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0xF80)
-#define CONFIG_START_ADDR_LEN (0x80)
-#define CONFIG_VENDOR_ID_OFFSET (0x04)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-#define LCD_CFG_MAX_SIZE (4 * 1024)
-#define LCD_CFG_MIN_SIZE (8)
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ctpm_get_app_i_file_ver(void);
-static int fts_ctpm_get_app_bin_file_ver(char *firmware_name);
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-static int fts_ctpm_fw_upgrade_with_lcd_cfg_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_lcd_cfg_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
-
- .get_i_file = fts_ctpm_get_i_file,
- .get_app_bin_file_ver = fts_ctpm_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ctpm_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ctpm_fw_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ctpm_fw_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = fts_ctpm_fw_upgrade_with_lcd_cfg_i_file,
- .upgrade_with_lcd_cfg_bin_file =
- fts_ctpm_fw_upgrade_with_lcd_cfg_bin_file,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ctpm_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ctpm_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- bool inbootloader = false;
- u8 rw_buf[10];
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*Enter upgrade mode*/
- fts_ctpm_i2c_hid2std(client);
- usleep_range(10000, 20000);
-
- inbootloader = fts_ctpm_check_run_state(client, FTS_RUN_IN_BOOTLOADER);
- if (!inbootloader) {
- FTS_ERROR("[UPGRADE]: not run in bootloader, upgrade fail!!");
- return -EIO;
- }
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- /* must wait, otherwise read vendor id wrong */
- usleep_range(10000, 20000);
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ft5x46_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid)
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- else
- ret = fts_ctpm_get_vendor_id_flash(client, &vendor_id);
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
- FTS_INFO("[UPGRADE] vendor id tp=%x", vendor_id);
- FTS_INFO("[UPGRADE] vendor id driver:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
-
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_bin_file_ver(char *firmware_name)
-{
- u8 *pbt_buf = NULL;
- int fwsize = 0;
- int fw_ver = 0;
-
- FTS_FUNC_ENTER();
-
- fwsize = fts_GetFirmwareSize(firmware_name);
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return -EIO;
- }
-
- pbt_buf = kmalloc(fwsize + 1, GFP_KERNEL);
- if (fts_ReadFirmware(firmware_name, pbt_buf)) {
- FTS_ERROR("[UPGRADE]: request_firmware failed!!");
- kfree(pbt_buf);
- return -EIO;
- }
-
- fw_ver = pbt_buf[APP_FILE_VER_MAPPING];
-
- kfree(pbt_buf);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u8 reg_val[4] = {0};
- u32 i = 0;
- u32 packet_number;
- u32 j = 0;
- u32 temp;
- u32 length;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 upgrade_ecc;
- int i_ret = 0;
- bool inbootloader = false;
-
- fts_ctpm_i2c_hid2std(client);
-
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*Enter upgrade mode*/
- fts_ctpm_i2c_hid2std(client);
- usleep_range(10000, 20000);
-
- inbootloader = fts_ctpm_check_run_state(client, FTS_RUN_IN_BOOTLOADER);
- if (!inbootloader) {
- FTS_ERROR("[UPGRADE]: not run in bootloader, upgrade fail!!");
- return -EIO;
- }
-
- /*send upgrade type to reg 0x09: 0x0B: upgrade; 0x0A: download*/
- auc_i2c_write_buf[0] = 0x09;
- auc_i2c_write_buf[1] = 0x0B;
- fts_i2c_write(client, auc_i2c_write_buf, 2);
-
- /*
- * All.bin <= 128K
- * APP.bin <= 94K
- * LCD_CFG <= 4K
- */
- auc_i2c_write_buf[0] = 0xB0;
- auc_i2c_write_buf[1] = (u8) ((dw_length >> 16) & 0xFF);
- auc_i2c_write_buf[2] = (u8) ((dw_length >> 8) & 0xFF);
- auc_i2c_write_buf[3] = (u8) (dw_length & 0xFF);
- fts_i2c_write(client, auc_i2c_write_buf, 4);
-
-
- /*erase the app erea in flash*/
- i_ret = fts_ctpm_erase_flash(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: erase flash error!!");
- return i_ret;
- }
-
- /*write FW to ctpm flash*/
- upgrade_ecc = 0;
- FTS_DEBUG("[UPGRADE]: write FW to ctpm flash!!");
- temp = 0;
- packet_number = (dw_length) / FTS_PACKET_LENGTH;
- packet_buf[0] = FTS_FW_WRITE_CMD;
-
- for (j = 0; j < packet_number; j++) {
- temp = 0x5000 + j * FTS_PACKET_LENGTH;
- packet_buf[1] = (u8) (temp >> 16);
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- length = FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (length >> 8);
- packet_buf[5] = (u8) length;
- for (i = 0; i < FTS_PACKET_LENGTH; i++) {
- packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
- /* usleep_range(1000, 2000); */
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((j + 0x1000 + (0x5000/FTS_PACKET_LENGTH))
- == (((reg_val[0]) << 8) | reg_val[1]))
- break;
-
- if (i > 15) {
- usleep_range(1000, 2000);
- FTS_DEBUG("[UPGRADE]: write flash:host :%x!!",
- (j + 0x1000
- + (0x5000/FTS_PACKET_LENGTH)));
- FTS_DEBUG("[UPGRADE]: write flash:status :%x!!",
- (((reg_val[0]) << 8) | reg_val[1]));
- }
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(10000);
- }
- }
-
- if ((dw_length) % FTS_PACKET_LENGTH > 0) {
- temp = 0x5000 + packet_number * FTS_PACKET_LENGTH;
- packet_buf[1] = (u8) (temp >> 16);
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- temp = (dw_length) % FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = pbt_buf[packet_number
- * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, temp + 6);
- /* usleep_range(1000, 2000); */
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((0x1000 + ((0x5000 + packet_number
- * FTS_PACKET_LENGTH)/((dw_length)
- % FTS_PACKET_LENGTH)))
- == (((reg_val[0]) << 8) | reg_val[1]))
- break;
-
- if (i > 15) {
- usleep_range(1000, 2000);
- FTS_DEBUG("[UPGRADE]: write flash:host :%x!!",
- (j + 0x1000
- + (0x5000/FTS_PACKET_LENGTH)));
- FTS_DEBUG("[UPGRADE]: write flash:status :%x!!",
- (((reg_val[0]) << 8) | reg_val[1]));
- }
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(10000);
- }
- }
-
- msleep(50);
-
- /*********Step 6: read out checksum***********************/
- /*send the opration head */
- FTS_DEBUG("[UPGRADE]: read out checksum!!");
- auc_i2c_write_buf[0] = 0x64;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- temp = 0x5000;
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(temp >> 16);
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = (64*1024-1);
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(dw_length/256);
-
- temp = (0x5000+(64*1024-1));
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(temp >> 16);
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = (dw_length-(64*1024-1));
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(dw_length/256);
-
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if (0xF0 == reg_val[0] && 0x55 == reg_val[1]) {
- FTS_DEBUG("[UPGRADE]: reg_val[0]=%02x reg_val[0]=%02x!",
- reg_val[0], reg_val[1]);
- break;
- }
- usleep_range(1000, 2000);
-
- }
- auc_i2c_write_buf[0] = 0x66;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
- FTS_DEBUG("[UPGRADE]: checksum %x %x!!", reg_val[0], upgrade_ecc);
-
- FTS_DEBUG("[UPGRADE]: reset the new FW!!");
- auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1000);
-
- fts_ctpm_i2c_hid2std(client);
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_lcd_cfg_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u8 reg_val[4] = {0};
- u8 cfg_backup[CONFIG_START_ADDR_LEN+1] = { 0 };
- u32 i = 0;
- u32 packet_number;
- u32 j = 0;
- u32 temp;
- u32 length;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 upgrade_ecc;
- int i_ret;
-
- fts_ctpm_i2c_hid2std(client);
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- /*write 0xaa to register FTS_RST_CMD_REG1 */
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
- usleep_range(10000, 20000);
-
- /*write 0x55 to register FTS_RST_CMD_REG1*/
- fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
- msleep(200);
-
- /*Enter upgrade mode*/
- fts_ctpm_i2c_hid2std(client);
-
- usleep_range(10000, 20000);
- auc_i2c_write_buf[0] = FTS_UPGRADE_55;
- auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: failed writing 0x55 and 0xaa!!");
- continue;
- }
-
- /*check run in bootloader or not*/
- usleep_range(1000, 2000);
- auc_i2c_write_buf[0] = FTS_READ_ID_REG;
- auc_i2c_write_buf[1] = auc_i2c_write_buf[2]
- = auc_i2c_write_buf[3] = 0x00;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
- FTS_DEBUG("[UPGRADE]:ID1 = 0x%x,ID2 = 0x%x!!",
- reg_val[0], reg_val[1]);
-
- if (reg_val[0] == chip_types.bootloader_idh
- && reg_val[1] == chip_types.bootloader_idl) {
- FTS_DEBUG("[UPGRADE]: read bootloader id ok!!");
- break;
- }
- FTS_DEBUG("[UPGRADE]: read bootloader id fail!!");
- }
-
- if (i >= FTS_UPGRADE_LOOP)
- return -EIO;
-
- /* Backup FW configuratin area */
- reg_val[0] = 0x03;
- reg_val[1] = (u8)((CONFIG_START_ADDR-1) >> 16);
- reg_val[2] = (u8)((CONFIG_START_ADDR-1) >> 8);
- reg_val[3] = (u8)((CONFIG_START_ADDR-1));
- i_ret = fts_i2c_read(client, reg_val, 4,
- cfg_backup, CONFIG_START_ADDR_LEN+1);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE] Read Config area error, don't upgrade");
- return -EIO;
- }
-
- /*send upgrade type to reg 0x09: 0x0B: upgrade; 0x0A: download*/
- auc_i2c_write_buf[0] = 0x09;
- auc_i2c_write_buf[1] = 0x0C;
- fts_i2c_write(client, auc_i2c_write_buf, 2);
-
- /*Step 4:erase app and panel paramenter area*/
- FTS_DEBUG("[UPGRADE]: erase app and panel paramenter area!!");
- auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1000);
-
- for (i = 0; i < 15; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
- break;
- msleep(50);
- }
- FTS_DEBUG("[UPGRADE]: erase app area reg_val = %x %x!!",
- reg_val[0], reg_val[1]);
-
- auc_i2c_write_buf[0] = 0xB0;
- auc_i2c_write_buf[1] = 0;
- auc_i2c_write_buf[2] = (u8) ((dw_length >> 8) & 0xFF);
- auc_i2c_write_buf[3] = (u8) (dw_length & 0xFF);
- fts_i2c_write(client, auc_i2c_write_buf, 4);
-
- /*write FW to ctpm flash*/
- upgrade_ecc = 0;
- FTS_DEBUG("[UPGRADE]: write FW to ctpm flash!!");
- temp = 0;
- packet_number = (dw_length) / FTS_PACKET_LENGTH;
- packet_buf[0] = FTS_FW_WRITE_CMD;
- packet_buf[1] = 0;
- for (j = 0; j < packet_number; j++) {
- temp = j * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- length = FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (length >> 8);
- packet_buf[5] = (u8) length;
- for (i = 0; i < FTS_PACKET_LENGTH; i++) {
- packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
- /* usleep_range(1000, 2000); */
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
- break;
-
- if (i > 15) {
- usleep_range(1000, 2000);
- FTS_DEBUG("[UPGRADE]: write flash:host : %x!",
- (j + 0x1000 +
- (0x5000/FTS_PACKET_LENGTH)),
- (((reg_val[0]) << 8) | reg_val[1]));
- FTS_DEBUG("[UPGRADE]: write flash:status : %x!",
- (((reg_val[0]) << 8) | reg_val[1]));
- }
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(10000);
- }
- }
-
- if ((dw_length) % FTS_PACKET_LENGTH > 0) {
- temp = packet_number * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- temp = (dw_length) % FTS_PACKET_LENGTH;
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = pbt_buf[packet_number
- * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, temp + 6);
- /* usleep_range(1000, 2000); */
-
- for (i = 0; i < 30; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((0x1000 + ((packet_number * FTS_PACKET_LENGTH)
- /((dw_length) % FTS_PACKET_LENGTH)))
- == (((reg_val[0]) << 8) | reg_val[1]))
- break;
-
- if (i > 15) {
- usleep_range(1000, 2000);
- FTS_DEBUG("[UPGRADE]: write flash:host : %x!",
- (j + 0x1000 +
- (0x5000/FTS_PACKET_LENGTH)),
- (((reg_val[0]) << 8) | reg_val[1]));
- FTS_DEBUG("[UPGRADE]: write flash:status : %x!",
- (((reg_val[0]) << 8) | reg_val[1]));
- }
- /* usleep_range(1000, 2000); */
- fts_ctpm_upgrade_delay(10000);
- }
- }
-
- /* Write Back FW configuratin area */
- packet_buf[0] = FTS_FW_WRITE_CMD;
- packet_buf[1] = (u8)(CONFIG_START_ADDR >> 16);
- packet_buf[2] = (u8)(CONFIG_START_ADDR >> 8);
- packet_buf[3] = (u8)(CONFIG_START_ADDR);
- packet_buf[4] = (u8)(CONFIG_START_ADDR_LEN >> 8);
- packet_buf[5] = (u8)(CONFIG_START_ADDR_LEN);
- memcpy(&packet_buf[6], &cfg_backup[1], CONFIG_START_ADDR_LEN);
- i_ret = fts_i2c_write(client, packet_buf, CONFIG_START_ADDR_LEN + 6);
- if (i_ret < 0)
- FTS_ERROR("[UPGRADE] Write Configuration area error");
-
- msleep(50);
-
- /*********Step 6: read out checksum***********************/
- /*send the opration head */
- FTS_DEBUG("[UPGRADE]: read out checksum!!");
- auc_i2c_write_buf[0] = 0x64;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- temp = 0x00;
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = 0;
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = dw_length;
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(dw_length/256);
-
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if (0xF0 == reg_val[0] && 0x55 == reg_val[1]) {
- FTS_DEBUG("[UPGRADE]:reg_val[0]=%02x reg_val[0]=%02x!",
- reg_val[0], reg_val[1]);
- break;
- }
- usleep_range(1000, 2000);
-
- }
- auc_i2c_write_buf[0] = 0x66;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
- FTS_DEBUG("[UPGRADE]: checksum %x %x!!", reg_val[0], upgrade_ecc);
-
- FTS_DEBUG("[UPGRADE]: reset the new FW!!");
- auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1000);
-
- fts_ctpm_i2c_hid2std(client);
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- fwsize = fts_GetFirmwareSize(firmware_name);
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- return -EIO;
- }
-
- pbt_buf = kmalloc(fwsize + 1, GFP_KERNEL);
- if (pbt_buf == NULL) {
- FTS_ERROR(" malloc pbt_buf failed ");
- goto ERROR_BIN;
- }
-
- if (fts_ReadFirmware(firmware_name, pbt_buf)) {
- FTS_ERROR("[UPGRADE]: request_firmware failed!!");
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = fts_check_app_bin_valid_idc(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, pbt_buf, fwsize);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
- kfree(pbt_buf);
- return i_ret;
-ERROR_BIN:
- kfree(pbt_buf);
- return -EIO;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_lcd_cfg_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_lcd_cfg_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- int lcd_cfg_size = 0;
-
- FTS_DEBUG("[UPGRADE]**********upgrade with lcd_cfg.i**********");
-
- lcd_cfg_size = fts_getsize(LCD_CFG_SIZE);
- if (lcd_cfg_size < LCD_CFG_MIN_SIZE
- || lcd_cfg_size > LCD_CFG_MAX_SIZE) {
- FTS_ERROR("[UPGRADE] lcd_cfg.i length(%x) error", lcd_cfg_size);
- return -EIO;
- }
-
- /*FW upgrade*/
- i_ret = fts_ctpm_lcd_cfg_upgrade_use_buf(client,
- CTPM_LCD_CFG, lcd_cfg_size);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] lcd_cfg.i upgrade fail, ret=%d", i_ret);
- else
- FTS_INFO("[UPGRADE] lcd_cfg.i upgrade succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_lcd_cfg_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_lcd_cfg_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int lcd_cfg_size = fts_GetFirmwareSize(firmware_name);
-
- FTS_DEBUG("[UPGRADE]**********upgrade with lcd_cfg.bin**********");
-
- if (lcd_cfg_size < LCD_CFG_MIN_SIZE
- || lcd_cfg_size > LCD_CFG_MAX_SIZE) {
- FTS_ERROR("[UPGRADE] lcd_cfg.bin length(%x) error",
- lcd_cfg_size);
- return -EIO;
- }
-
- pbt_buf = kmalloc(lcd_cfg_size + 1, GFP_KERNEL);
- if (fts_ReadFirmware(firmware_name, pbt_buf)) {
- FTS_ERROR("[UPGRADE]: request_firmware failed!!");
- goto ERROR_LCD_CFG_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = 1;
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE]: lcd_cfg.bin ecc ok!!");
- i_ret = fts_ctpm_lcd_cfg_upgrade_use_buf(client,
- pbt_buf, lcd_cfg_size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: lcd_cfg.bin upgrade failed!!");
- goto ERROR_LCD_CFG_BIN;
- } else {
- FTS_INFO("[UPGRADE]: lcd_cfg.bin upgrade succeed!!");
- }
- } else {
- FTS_ERROR("[UPGRADE]: lcd_cfg.bin ecc failed!!");
-
- }
-
- kfree(pbt_buf);
- return i_ret;
-
-ERROR_LCD_CFG_BIN:
- kfree(pbt_buf);
- return -EIO;
-}
-#endif /* #if (FTS_CHIP_TYPE == _FT8006) */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8606.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8606.c
deleted file mode 100644
index 3589ba5..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8606.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft8606.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (FTS_CHIP_TYPE == _FT8606)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (64 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10A)
-#define APP_FILE_VENDORID_MAPPING (0x108)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0x0780)
-#define CONFIG_VENDOR_ID_OFFSET (0x04)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-#define AL2_FCS_COEF ((1 << 7) + (1 << 6) + (1 << 5))
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ctpm_get_app_i_file_ver(void);
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length);
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
- .get_i_file = fts_ctpm_get_i_file,
- .get_app_bin_file_ver = fts_ctpm_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ctpm_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ctpm_fw_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ctpm_fw_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ctpm_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ctpm_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 rw_buf[10];
- int i_ret;
- int fw_len;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*check run in pramboot or not!
- *if not rum in pramboot, cannot upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- /* must wait, otherwise read vendor id wrong */
- usleep_range(10000, 20000);
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ctpm_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid) {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- } else {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- if ((ret < 0) || (vendor_id == 0xEF) || (vendor_id == 0xED)) {
- /* 8736 can't read vendor id from A8 command */
- ret = fts_ctpm_get_vendor_id_flash(client, &vendor_id);
- }
- }
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
- FTS_INFO("[UPGRADE] vendor id tp=%x", vendor_id);
- FTS_INFO("[UPGRADE] vendor id driver:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
-
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_pram
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- int i_ret;
- bool inrom = false;
-
- FTS_FUNC_ENTER();
-
- /*check the length of the pramboot*/
- if (dw_length > APP_FILE_MAX_SIZE || dw_length < APP_FILE_MIN_SIZE) {
- FTS_ERROR("[UPGRADE] pramboot length(%d) fail", dw_length);
- return -EIO;
- }
-
- /*send comond to FW, reset and start write pramboot*/
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*check run in rom or not! if run in rom, will write pramboot*/
- inrom = fts_ctpm_check_run_state(client, FTS_RUN_IN_ROM);
- if (!inrom) {
- FTS_ERROR("[UPGRADE]: not run in rom, write pramboot fail!!");
- return -EIO;
- }
-
- /*write pramboot to pram*/
- i_ret = fts_ctpm_write_pramboot_for_idc(client,
- dw_length, aucFW_PRAM_BOOT);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write pramboot fail!!");
- return i_ret;
- }
-
- /*read out checksum*/
- i_ret = fts_ctpm_pramboot_ecc(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write pramboot ecc error!!");
- return i_ret;
- }
-
- /*start pram*/
- fts_ctpm_start_pramboot(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_app
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_app(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u32 temp;
- int i_ret;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*upgrade init*/
- i_ret = fts_ctpm_upgrade_idc_init(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: upgrade init error, upgrade fail!!");
- return i_ret;
- }
-
- /*erase the app erea in flash*/
- i_ret = fts_ctpm_erase_flash(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: erase flash error!!");
- return i_ret;
- }
-
- /*start to write app*/
- i_ret = fts_ctpm_write_app_for_idc(client, dw_length, pbt_buf);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write app error!!");
- return i_ret;
- }
-
- /*read check sum*/
- temp = 0x1000;
- i_ret = fts_ctpm_upgrade_ecc(client, temp, dw_length);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: ecc error!!");
- return i_ret;
- }
-
- /*upgrade success, reset the FW*/
- fts_ctpm_rom_or_pram_reset(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/*****************************************************************************
- * Name: ecc_calc
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static u8 ecc_calc(u8 *pbt_buf, u16 start, u16 length)
-{
- u8 cFcs = 0;
- u16 i, j;
-
- for (i = 0; i < length; i++) {
- cFcs ^= pbt_buf[start++];
- for (j = 0; j < 8; j++) {
- if (cFcs & 1)
- cFcs = (u8)((cFcs >> 1) ^ AL2_FCS_COEF);
- else
- cFcs >>= 1;
- }
- }
- return cFcs;
-}
-
-
-/*****************************************************************************
- * Name: fts_8606_check_app_bin_valid
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static bool fts_8606_check_app_bin_valid(u8 *pbt_buf)
-{
- u8 ecc1;
- u8 ecc2;
- u8 ecc3;
- u8 ecc4;
- u16 len1;
- u16 len2;
- u8 cal_ecc1;
- u8 cal_ecc2;
- u16 usAddrInfo;
-
- /* 1. First Byte */
- if (pbt_buf[0] != 0x02) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- the first byte(%x) error",
- pbt_buf[0]);
- return false;
- }
-
- usAddrInfo = 0x100;
-
- /* 2.len */
- len1 = pbt_buf[usAddrInfo++] << 8;
- len1 += pbt_buf[usAddrInfo++];
-
- len2 = pbt_buf[usAddrInfo++] << 8;
- len2 += pbt_buf[usAddrInfo++];
-
- if ((len1 + len2) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- LENGTH(%04x) XOR error",
- len1);
- return false;
- }
-
- /* 3.ecc */
- ecc1 = pbt_buf[usAddrInfo++];
- ecc2 = pbt_buf[usAddrInfo++];
- ecc3 = pbt_buf[usAddrInfo++];
- ecc4 = pbt_buf[usAddrInfo++];
-
- if (((ecc1 + ecc2) != 0xFF) || ((ecc3 + ecc4) != 0xFF)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC(%x %x) XOR error",
- ecc1, ecc2);
- return false;
- }
-
- cal_ecc1 = ecc_calc(pbt_buf, 0x0, 0x100);
- cal_ecc2 = ecc_calc(pbt_buf, 0x100 + 0x20, len1 - (0x100 + 0x20));
- if ((ecc1 != cal_ecc1) || (ecc3 != cal_ecc2)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ECC calc error");
- return false;
- }
- return true;
-}
-
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- * success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 fwsize)
-{
- int i_ret = 0;
- int fw_len;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*write app*/
- i_ret = fts_ctpm_write_app(client, pbt_buf, fwsize);
-
- FTS_FUNC_EXIT();
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- pbt_buf = (u8 *)fw->data;
- if ((pbt_buf[APP_FILE_CHIPID_MAPPING] != chip_types.pramboot_idh)
- || (pbt_buf[APP_FILE_CHIPID_MAPPING+1]
- != chip_types.pramboot_idl)) {
- FTS_ERROR("[UPGRADE]: chip id error, app.bin upgrade failed!");
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = fts_8606_check_app_bin_valid(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* #if (FTS_CHIP_TYPE == _FT8606) */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8607.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8607.c
deleted file mode 100644
index 604edbd..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8607.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft8607.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (FTS_CHIP_TYPE == _FT8607)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (64 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10E)
-#define APP_FILE_VENDORID_MAPPING (0x10C)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0x0780)
-#define CONFIG_VENDOR_ID_OFFSET (0x04)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ctpm_get_app_i_file_ver(void);
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length);
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
- .get_i_file = fts_ctpm_get_i_file,
- .get_app_bin_file_ver = fts_ctpm_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ctpm_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ctpm_fw_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ctpm_fw_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ctpm_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ctpm_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 rw_buf[10];
- int i_ret;
- int fw_len;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- /* must wait, otherwise read vendor id wrong */
- usleep_range(10000, 20000);
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ctpm_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid) {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- } else {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- if ((ret < 0) || (vendor_id == 0xEF) || (vendor_id == 0xED)) {
- /* 8736 can't read vendor id from A8 command */
- ret = fts_ctpm_get_vendor_id_flash(client, &vendor_id);
- }
- }
-
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
- FTS_INFO("[UPGRADE] vendor id tp=%x", vendor_id);
- FTS_INFO("[UPGRADE] vendor id driver:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
-
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_pram
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- int i_ret;
- bool inrom = false;
-
- FTS_FUNC_ENTER();
-
- /*check the length of the pramboot*/
- if (dw_length > APP_FILE_MAX_SIZE || dw_length < APP_FILE_MIN_SIZE) {
- FTS_ERROR("[UPGRADE] pramboot length(%d) fail", dw_length);
- return -EIO;
- }
-
- /*send comond to FW, reset and start write pramboot*/
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*check run in rom or not! if run in rom, will write pramboot*/
- inrom = fts_ctpm_check_run_state(client, FTS_RUN_IN_ROM);
- if (!inrom) {
- FTS_ERROR("[UPGRADE]: not run in rom, write pramboot fail!!");
- return -EIO;
- }
-
- /*write pramboot to pram*/
- i_ret = fts_ctpm_write_pramboot_for_idc(client,
- dw_length, aucFW_PRAM_BOOT);
- if (i_ret < 0) {
- return i_ret;
- FTS_ERROR("[UPGRADE]: write pramboot fail!!");
- }
-
- /*read out checksum*/
- i_ret = fts_ctpm_pramboot_ecc(client);
- if (i_ret < 0) {
- return i_ret;
- FTS_ERROR("[UPGRADE]: write pramboot ecc error!!");
- }
-
- /*start pram*/
- fts_ctpm_start_pramboot(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_app
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_app(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u32 temp;
- int i_ret;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*upgrade init*/
- i_ret = fts_ctpm_upgrade_idc_init(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: upgrade init error, upgrade fail!!");
- return i_ret;
- }
-
- /*erase the app erea in flash*/
- i_ret = fts_ctpm_erase_flash(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: erase flash error!!");
- return i_ret;
- }
-
- /*start to write app*/
- i_ret = fts_ctpm_write_app_for_idc(client, dw_length, pbt_buf);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write app error!!");
- return i_ret;
- }
-
- /*read check sum*/
- temp = 0x1000;
- i_ret = fts_ctpm_upgrade_ecc(client, temp, dw_length);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: ecc error!!");
- return i_ret;
- }
-
- /*upgrade success, reset the FW*/
- fts_ctpm_rom_or_pram_reset(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- * success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 fwsize)
-{
- int i_ret = 0;
- int fw_len;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*write app*/
- i_ret = fts_ctpm_write_app(client, pbt_buf, fwsize);
-
- FTS_FUNC_EXIT();
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- pbt_buf = (u8 *)fw->data;
- if ((pbt_buf[APP_FILE_CHIPID_MAPPING] != chip_types.pramboot_idh)
- || (pbt_buf[APP_FILE_CHIPID_MAPPING+1]
- != chip_types.pramboot_idl)) {
- FTS_ERROR("[UPGRADE]: chip id error, app.bin upgrade failed!");
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = fts_check_app_bin_valid_idc(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* #if (FTS_CHIP_TYPE == _FT8607) */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8716.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8716.c
deleted file mode 100644
index 0df248b..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8716.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft8716.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-15
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if ((FTS_CHIP_TYPE == _FT8716) || (FTS_CHIP_TYPE == _FTE716))
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (64 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10E)
-#define APP_FILE_VENDORID_MAPPING (0x10C)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0x0000)
-#define CONFIG_VENDOR_ID_OFFSET (0x04)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ctpm_get_app_i_file_ver(void);
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length);
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
- .get_i_file = fts_ctpm_get_i_file,
- .get_app_bin_file_ver = fts_ctpm_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ctpm_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ctpm_fw_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ctpm_fw_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ctpm_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ctpm_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 rw_buf[10];
- int i_ret;
- int fw_len;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- /* must wait, otherwise read vendor id wrong */
- usleep_range(10000, 20000);
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ctpm_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = -EIO;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid) {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- } else {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- if ((ret < 0) || (vendor_id == 0xEF) || (vendor_id == 0xED)) {
- /* 8736 can't read vendor id from A8 command */
- ret = fts_ctpm_get_vendor_id_flash(client, &vendor_id);
- }
- }
-
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
- FTS_INFO("[UPGRADE] vendor id tp=%x", vendor_id);
- FTS_INFO("[UPGRADE] vendor id driver:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
-
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_pram
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- int i_ret;
- bool inrom = false;
-
- FTS_FUNC_ENTER();
-
- /*check the length of the pramboot*/
- if (dw_length > APP_FILE_MAX_SIZE || dw_length < APP_FILE_MIN_SIZE) {
- FTS_ERROR("[UPGRADE] pramboot length(%d) fail", dw_length);
- return -EIO;
- }
-
- /*send comond to FW, reset and start write pramboot*/
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*check run in rom or not! if run in rom, will write pramboot*/
- inrom = fts_ctpm_check_run_state(client, FTS_RUN_IN_ROM);
- if (!inrom) {
- FTS_ERROR("[UPGRADE]: not run in rom, write pramboot fail!!");
- return -EIO;
- }
-
- /*write pramboot to pram*/
- i_ret = fts_ctpm_write_pramboot_for_idc(client,
- dw_length, aucFW_PRAM_BOOT);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write pramboot fail!!");
- return i_ret;
- }
-
- /*read out checksum*/
- i_ret = fts_ctpm_pramboot_ecc(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write pramboot ecc error!!");
- return i_ret;
- }
-
- /*start pram*/
- fts_ctpm_start_pramboot(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_app
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_app(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u32 temp;
- int i_ret;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*upgrade init*/
- i_ret = fts_ctpm_upgrade_idc_init(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: upgrade init error, upgrade fail!!");
- return i_ret;
- }
-
- /*erase the app erea in flash*/
- i_ret = fts_ctpm_erase_flash(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: erase flash error!!");
- return i_ret;
- }
-
- /*start to write app*/
- i_ret = fts_ctpm_write_app_for_idc(client, dw_length, pbt_buf);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write app error!!");
- return i_ret;
- }
-
- /*read check sum*/
- temp = 0x1000;
- i_ret = fts_ctpm_upgrade_ecc(client, temp, dw_length);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: ecc error!!");
- return i_ret;
- }
-
- /*upgrade success, reset the FW*/
- fts_ctpm_rom_or_pram_reset(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- * success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 fwsize)
-{
- int i_ret = 0;
- int fw_len;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*write app*/
- i_ret = fts_ctpm_write_app(client, pbt_buf, fwsize);
-
- FTS_FUNC_EXIT();
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- pbt_buf = (u8 *)fw->data;
- ecc_ok = fts_check_app_bin_valid_idc(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* #if (FTS_CHIP_TYPE == _FT8716) */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8736.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8736.c
deleted file mode 100644
index 6f6544e..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_ft8736.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_ft8736.c
- *
- * Author: fupeipei
- *
- * Created: 2016-10-25
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (FTS_CHIP_TYPE == _FT8736)
-#include "../focaltech_flash.h"
-#include "focaltech_upgrade_common.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define APP_FILE_MAX_SIZE (64 * 1024)
-#define APP_FILE_MIN_SIZE (8)
-#define APP_FILE_VER_MAPPING (0x10E)
-#define APP_FILE_VENDORID_MAPPING (0x10C)
-#define APP_FILE_CHIPID_MAPPING (0x11E)
-#define CONFIG_START_ADDR (0x0F80)
-#define CONFIG_VENDOR_ID_OFFSET (0x4)
-#define CONFIG_PROJECT_ID_OFFSET (0x20)
-#define CONFIG_VENDOR_ID_ADDR (CONFIG_START_ADDR+CONFIG_VENDOR_ID_OFFSET)
-#define CONFIG_PROJECT_ID_ADDR (CONFIG_START_ADDR+CONFIG_PROJECT_ID_OFFSET)
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid);
-static int fts_ctpm_get_app_i_file_ver(void);
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name);
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length);
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client);
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name);
-
-struct fts_upgrade_fun fts_updatefun = {
- .get_i_file = fts_ctpm_get_i_file,
- .get_app_bin_file_ver = fts_ctpm_get_app_bin_file_ver,
- .get_app_i_file_ver = fts_ctpm_get_app_i_file_ver,
- .upgrade_with_app_i_file = fts_ctpm_fw_upgrade_with_app_i_file,
- .upgrade_with_app_bin_file = fts_ctpm_fw_upgrade_with_app_bin_file,
- .upgrade_with_lcd_cfg_i_file = NULL,
- .upgrade_with_lcd_cfg_bin_file = NULL,
-};
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_GET_VENDOR_ID_NUM != 0)
-/************************************************************************
- * Name: fts_ctpm_get_vendor_id_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-static int fts_ctpm_get_vendor_id_flash(struct i2c_client *client,
- u8 *vendor_id)
-{
- u8 rw_buf[10];
- int i_ret;
- int fw_len;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /* initialization 0x05 0x80 */
- i_ret = fts_ctpm_upgrade_idc_init(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: upgrade init error, upgrade fail!!");
- return i_ret;
- }
-
- /*read vendor id*/
- rw_buf[0] = 0x03;
- rw_buf[1] = 0x00;
- rw_buf[2] = (u8)(CONFIG_VENDOR_ID_ADDR >> 8);
- rw_buf[3] = (u8)(CONFIG_VENDOR_ID_ADDR);
- i_ret = fts_i2c_write(client, rw_buf, 4);
- /* must wait, otherwise read vendor id wrong */
- usleep_range(10000, 20000);
- i_ret = fts_i2c_read(client, NULL, 0, vendor_id, 1);
- if (i_ret < 0)
- return -EIO;
- FTS_DEBUG("Vendor ID from Flash:%x", *vendor_id);
- return 0;
-}
-#endif
-
-/************************************************************************
- * Name: fts_ctpm_get_i_file
- * Brief: get .i file
- * Input:
- * Output:
- * Return: 0 - ok
- * <0 - fail
- ***********************************************************************/
-static int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
-{
- int ret = 0;
-
-#if (FTS_GET_VENDOR_ID_NUM != 0)
- u8 vendor_id = 0;
-
- if (fw_valid) {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- } else {
- ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
- if ((ret < 0) || (vendor_id == 0xEF) || (vendor_id == 0xED)) {
- /* 8736 can't read vendor id from A8 command */
- ret = fts_ctpm_get_vendor_id_flash(client, &vendor_id);
- }
- }
-
- if (ret < 0) {
- FTS_ERROR("Get upgrade file fail because of Vendor ID wrong");
- return ret;
- }
- FTS_INFO("[UPGRADE] vendor id tp=%x", vendor_id);
- FTS_INFO("[UPGRADE] vendor id driver:%x, FTS_VENDOR_ID:%02x %02x %02x",
- vendor_id, FTS_VENDOR_1_ID, FTS_VENDOR_2_ID, FTS_VENDOR_3_ID);
-
- ret = 0;
- switch (vendor_id) {
-#if (FTS_GET_VENDOR_ID_NUM >= 1)
- case FTS_VENDOR_1_ID:
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 2)
- case FTS_VENDOR_2_ID:
- g_fw_file = CTPM_FW2;
- g_fw_len = fts_getsize(FW2_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW2, SIZE:%x", g_fw_len);
- break;
-#endif
-#if (FTS_GET_VENDOR_ID_NUM >= 3)
- case FTS_VENDOR_3_ID:
- g_fw_file = CTPM_FW3;
- g_fw_len = fts_getsize(FW3_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW3, SIZE:%x", g_fw_len);
- break;
-#endif
- default:
- FTS_ERROR("[UPGRADE]Vendor ID check fail, get fw file fail");
- ret = -EIO;
- break;
- }
-#else
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-#endif
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_bin_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_bin_file_ver(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- int fw_ver = 0;
- int ret;
-
- FTS_FUNC_ENTER();
-
- ret = request_firmware(&fw, firmware_name, &client->dev);
- if (ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE)
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw->size);
- else
- fw_ver = fw->data[APP_FILE_VER_MAPPING];
-
- release_firmware(fw);
- FTS_FUNC_EXIT();
-
- return fw_ver;
-}
-
-/************************************************************************
- * Name: fts_ctpm_get_app_i_file_ver
- * Brief: get .i file version
- * Input: no
- * Output: no
- * Return: fw version
- ***********************************************************************/
-static int fts_ctpm_get_app_i_file_ver(void)
-{
- int fwsize = g_fw_len;
-
- if (fwsize < APP_FILE_MIN_SIZE || fwsize > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fwsize);
- return 0;
- }
-
- return g_fw_file[APP_FILE_VER_MAPPING];
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_pram
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_pram(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- int i_ret;
- bool inrom = false;
-
- FTS_FUNC_ENTER();
-
- /*check the length of the pramboot*/
- if (dw_length > APP_FILE_MAX_SIZE || dw_length < APP_FILE_MIN_SIZE) {
- FTS_ERROR("[UPGRADE] pramboot length(%d) fail", dw_length);
- return -EIO;
- }
-
- /*send comond to FW, reset and start write pramboot*/
- i_ret = fts_ctpm_start_fw_upgrade(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: send upgrade cmd to FW error!!");
- return i_ret;
- }
-
- /*check run in rom or not! if run in rom, will write pramboot*/
- inrom = fts_ctpm_check_run_state(client, FTS_RUN_IN_ROM);
- if (!inrom) {
- FTS_ERROR("[UPGRADE]: not run in rom, write pramboot fail!!");
- return -EIO;
- }
-
- /*write pramboot to pram*/
- i_ret = fts_ctpm_write_pramboot_for_idc(client,
- dw_length, aucFW_PRAM_BOOT);
- if (i_ret < 0) {
- return i_ret;
- FTS_ERROR("[UPGRADE]: write pramboot fail!!");
- }
-
- /*read out checksum*/
- i_ret = fts_ctpm_pramboot_ecc(client);
- if (i_ret < 0) {
- return i_ret;
- FTS_ERROR("[UPGRADE]: write pramboot ecc error!!");
- }
-
- /*start pram*/
- fts_ctpm_start_pramboot(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_app
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-static int fts_ctpm_write_app(struct i2c_client *client,
- u8 *pbt_buf, u32 dw_length)
-{
- u32 temp;
- int i_ret;
- bool inpram = false;
-
- FTS_FUNC_ENTER();
-
- /*check run in pramboot or not!
- *if not rum in pramboot, can not upgrade
- */
- inpram = fts_ctpm_check_run_state(client, FTS_RUN_IN_PRAM);
- if (!inpram) {
- FTS_ERROR("[UPGRADE]: not run in pram, upgrade fail!!");
- return -EIO;
- }
-
- /*upgrade init*/
- i_ret = fts_ctpm_upgrade_idc_init(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: upgrade init error, upgrade fail!!");
- return i_ret;
- }
-
- /*erase the app erea in flash*/
- i_ret = fts_ctpm_erase_flash(client);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: erase flash error!!");
- return i_ret;
- }
-
- /*start to write app*/
- i_ret = fts_ctpm_write_app_for_idc(client, dw_length, pbt_buf);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: write app error!!");
- return i_ret;
- }
-
- /*read check sum*/
- temp = 0x1000;
- i_ret = fts_ctpm_upgrade_ecc(client, temp, dw_length);
- if (i_ret < 0) {
- FTS_ERROR("[UPGRADE]: ecc error!!");
- return i_ret;
- }
-
- /*upgrade success, reset the FW*/
- fts_ctpm_rom_or_pram_reset(client);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_use_buf
- * Brief: fw upgrade
- * Input: i2c info, file buf, file len
- * Output: no
- * Return: fail <0
- * success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_use_buf(struct i2c_client *client,
- u8 *pbt_buf, u32 fwsize)
-{
- int i_ret = 0;
- int fw_len;
-
- FTS_FUNC_ENTER();
-
- /*write pramboot*/
- fw_len = fts_getsize(PRAMBOOT_SIZE);
- FTS_DEBUG("[UPGRADE]: pramboot size : %d!!", fw_len);
- i_ret = fts_ctpm_write_pram(client, aucFW_PRAM_BOOT, fw_len);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: write pram failed!!");
- return -EIO;
- }
-
- /*write app*/
- i_ret = fts_ctpm_write_app(client, pbt_buf, fwsize);
-
- FTS_FUNC_EXIT();
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_i_file
- * Brief: upgrade with *.i file
- * Input: i2c info
- * Output:
- * Return: fail < 0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_i_file(struct i2c_client *client)
-{
- int i_ret = 0;
- u32 fw_len;
- u8 *fw_buf;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.i**********");
-
- fw_len = g_fw_len;
- fw_buf = g_fw_file;
- if (fw_len < APP_FILE_MIN_SIZE || fw_len > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: FW length(%x) error", fw_len);
- return -EIO;
- }
-
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, fw_buf, fw_len);
- if (i_ret != 0)
- FTS_ERROR("[UPGRADE] upgrade app.i failed");
- else
- FTS_INFO("[UPGRADE]: upgrade app.i succeed");
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_fw_upgrade_with_app_bin_file
- * Brief: upgrade with *.bin file
- * Input: i2c info, file name
- * Output: no
- * Return: success =0
- ***********************************************************************/
-static int fts_ctpm_fw_upgrade_with_app_bin_file(struct i2c_client *client,
- char *firmware_name)
-{
- const struct firmware *fw = NULL;
- u8 *pbt_buf = NULL;
- int i_ret = 0;
- bool ecc_ok = false;
- int fwsize = 0;
-
- FTS_INFO("[UPGRADE]**********start upgrade with app.bin**********");
-
- i_ret = request_firmware(&fw, firmware_name, &client->dev);
- if (i_ret) {
- FTS_ERROR("[UPGRADE]: failed to get fw %s\n", firmware_name);
- return i_ret;
- }
-
- if (fw->size < APP_FILE_MIN_SIZE || fw->size > APP_FILE_MAX_SIZE) {
- FTS_ERROR("[UPGRADE]: app.bin length(%x) error, upgrade fail",
- fwsize);
- goto ERROR_BIN;
- }
-
- pbt_buf = (u8 *)fw->data;
- if ((pbt_buf[APP_FILE_CHIPID_MAPPING] != chip_types.pramboot_idh)
- || (pbt_buf[APP_FILE_CHIPID_MAPPING+1]
- != chip_types.pramboot_idl)) {
- FTS_ERROR("[UPGRADE]: chip id error, app.bin upgrade failed!");
- goto ERROR_BIN;
- }
-
- /*check the app.bin invalid or not*/
- ecc_ok = fts_check_app_bin_valid_idc(pbt_buf);
-
- if (ecc_ok) {
- FTS_INFO("[UPGRADE] app.bin ecc ok");
- i_ret = fts_ctpm_fw_upgrade_use_buf(client, pbt_buf, fw->size);
- if (i_ret != 0) {
- FTS_ERROR("[UPGRADE]: upgrade app.bin failed");
- goto ERROR_BIN;
- } else {
- FTS_INFO("[UPGRADE]: upgrade app.bin succeed");
- }
- } else {
- FTS_ERROR("[UPGRADE] app.bin ecc failed");
- goto ERROR_BIN;
- }
-
-ERROR_BIN:
- release_firmware(fw);
- return i_ret;
-}
-#endif /* #if (FTS_CHIP_TYPE == _FT8736) */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_idc.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_idc.c
deleted file mode 100644
index c91d7c80..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_idc.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_idc.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-22
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-
-#if (FTS_CHIP_IDC == 1)
-#include "../focaltech_flash.h"
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-static u8 upgrade_ecc;
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-
-/************************************************************************
- * Name: fts_ctpm_upgrade_idc_init
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_upgrade_idc_init(struct i2c_client *client)
-{
- int i_ret = 0;
- u8 reg_val_id[4] = {0};
- u8 auc_i2c_write_buf[10];
-
- FTS_INFO("[UPGRADE]**********Upgrade setting Init**********");
-
- /*read flash ID*/
- auc_i2c_write_buf[0] = 0x05;
- reg_val_id[0] = 0x00;
- i_ret = fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val_id, 1);
- if (i_ret < 0)
- return -EIO;
-
- /*set flash clk*/
- auc_i2c_write_buf[0] = 0x05;
- auc_i2c_write_buf[1] = reg_val_id[0];/* 0x80; */
- auc_i2c_write_buf[2] = 0x00;
- fts_i2c_write(client, auc_i2c_write_buf, 3);
-
- /*send upgrade type to reg 0x09: 0x0B: upgrade; 0x0A: download*/
- auc_i2c_write_buf[0] = 0x09;
- auc_i2c_write_buf[1] = 0x0B;
- fts_i2c_write(client, auc_i2c_write_buf, 2);
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_start_pramboot
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-void fts_ctpm_start_pramboot(struct i2c_client *client)
-{
- u8 auc_i2c_write_buf[10];
-
- FTS_INFO("[UPGRADE]**********start pramboot**********");
- auc_i2c_write_buf[0] = 0x08;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(20);
-}
-
-/************************************************************************
- * Name: fts_ctpm_start_fw_upgrade
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_start_fw_upgrade(struct i2c_client *client)
-{
- int i_ret = 0;
-
- /*send the soft upgrade commond to FW, and start upgrade*/
- FTS_INFO("[UPGRADE]***send 0xAA and 0x55 to FW, start upgrade***\n");
-
- i_ret = fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
- msleep(20);
- i_ret = fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
- msleep(200);
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_check_run_state
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-bool fts_ctpm_check_run_state(struct i2c_client *client, int rstate)
-{
- int i = 0;
- enum FW_STATUS cstate = FTS_RUN_IN_ERROR;
-
- for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
- cstate = fts_ctpm_get_pram_or_rom_id(client);
- FTS_DEBUG("[UPGRADE]: run state = %d", cstate);
-
- if (cstate == rstate)
- return true;
- msleep(20);
- }
-
- return false;
-}
-
-/************************************************************************
- * Name: fts_ctpm_pramboot_ecc
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_pramboot_ecc(struct i2c_client *client)
-{
- u8 auc_i2c_write_buf[10];
- u8 reg_val[4] = {0};
-
- FTS_FUNC_ENTER();
-
- /* read out checksum,
- * if pramboot checksum != host checksum, upgrade fail
- */
- FTS_INFO("[UPGRADE]******read out pramboot checksum******");
- auc_i2c_write_buf[0] = 0xcc;
- usleep_range(2000, 4000);
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- /*pramboot checksum != host checksum, upgrade fail*/
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: checksum fail:pramboot = %X, host = %X!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
-
- FTS_DEBUG("[UPGRADE]: checksum success:pramboot = %X, host = %X!!",
- reg_val[0], upgrade_ecc);
- msleep(100);
-
- FTS_FUNC_EXIT();
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_upgrade_ecc
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_upgrade_ecc(struct i2c_client *client, u32 startaddr, u32 length)
-{
- u32 i = 0;
- u8 auc_i2c_write_buf[10];
- u32 temp;
- u8 reg_val[4] = {0};
- int i_ret = 0;
-
- FTS_INFO("[UPGRADE]**********read out checksum**********");
-
- /*check sum init*/
- auc_i2c_write_buf[0] = 0x64;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(300);
-
- /*send commond to pramboot to start checksum*/
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(startaddr >> 16);
- auc_i2c_write_buf[2] = (u8)(startaddr >> 8);
- auc_i2c_write_buf[3] = (u8)(startaddr);
-
- if (length > LEN_FLASH_ECC_MAX)
- temp = LEN_FLASH_ECC_MAX;
- else
- temp = length;
-
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
- msleep(length/256);
-
- /*read status : if check sum is finished?*/
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
- break;
- usleep_range(1000, 2000);
-
- }
-
- if (length > LEN_FLASH_ECC_MAX) {
- temp = LEN_FLASH_ECC_MAX;
- auc_i2c_write_buf[0] = 0x65;
- auc_i2c_write_buf[1] = (u8)(temp >> 16);
- auc_i2c_write_buf[2] = (u8)(temp >> 8);
- auc_i2c_write_buf[3] = (u8)(temp);
- temp = length-LEN_FLASH_ECC_MAX;
- auc_i2c_write_buf[4] = (u8)(temp >> 8);
- auc_i2c_write_buf[5] = (u8)(temp);
- i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
-
- msleep(length/256);
-
- for (i = 0; i < 100; i++) {
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
- break;
- usleep_range(1000, 2000);
- }
- }
-
- /*read out check sum*/
- auc_i2c_write_buf[0] = 0x66;
- i_ret = fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
- /*if check sum fail, upgrade fail*/
- if (reg_val[0] != upgrade_ecc) {
- FTS_ERROR("[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
- return -EIO;
- }
-
- FTS_DEBUG("[UPGRADE]: ecc success : FW=%02x upgrade_ecc=%02x!!",
- reg_val[0], upgrade_ecc);
-
- upgrade_ecc = 0;
-
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_erase_flash
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_erase_flash(struct i2c_client *client)
-{
- u32 i = 0;
- u8 auc_i2c_write_buf[10];
- u8 reg_val[4] = {0};
-
- FTS_INFO("[UPGRADE]**********erase app now**********");
-
- /*send to erase flash*/
- auc_i2c_write_buf[0] = 0x61;
- fts_i2c_write(client, auc_i2c_write_buf, 1);
- msleep(1350);
-
- for (i = 0; i < 15; i++) {
- /* get the erase app status,
- * if get 0xF0AA£¬erase flash success
- */
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
- /*erase flash success*/
- if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
- break;
- msleep(50);
- }
-
- /*erase flash fail*/
- if ((0xF0 != reg_val[0] || 0xAA != reg_val[1]) && (i >= 15)) {
- FTS_ERROR("[UPGRADE]: erase app error.reset tp and reload FW!");
- return -EIO;
- }
-
- FTS_DEBUG("[UPGRADE]: erase app ok!!");
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_pramboot_for_idc
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_write_pramboot_for_idc(struct i2c_client *client,
- u32 length, u8 *readbuf)
-{
- u32 i = 0;
- u32 j;
- u32 temp;
- u32 packet_number;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
-
- upgrade_ecc = 0;
- FTS_INFO("[UPGRADE]**********write pramboot to pram**********");
-
- temp = 0;
- packet_number = (length) / FTS_PACKET_LENGTH;
- if ((length) % FTS_PACKET_LENGTH > 0)
- packet_number++;
-
- packet_buf[0] = 0xae;
- packet_buf[1] = 0x00;
-
- for (j = 0; j < packet_number; j++) {
- temp = j * FTS_PACKET_LENGTH;
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- if (j < (packet_number-1))
- temp = FTS_PACKET_LENGTH;
- else
- temp = (length) % FTS_PACKET_LENGTH;
-
- packet_buf[4] = (u8) (temp >> 8);
- packet_buf[5] = (u8) temp;
-
- for (i = 0; i < temp; i++) {
- packet_buf[6 + i] = readbuf[j * FTS_PACKET_LENGTH + i];
- upgrade_ecc ^= packet_buf[6 + i];
- }
- fts_i2c_write(client, packet_buf, temp + 6);
- }
-
- return 0;
-}
-
-/************************************************************************
- * Name: fts_ctpm_write_app_for_idc
- * Brief:
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_ctpm_write_app_for_idc(struct i2c_client *client,
- u32 length, u8 *readbuf)
-{
- u32 j;
- u32 i = 0;
- u32 packet_number;
- u32 temp;
- u32 writelenght;
- u8 packet_buf[FTS_PACKET_LENGTH + 6];
- u8 auc_i2c_write_buf[10];
- u8 reg_val[4] = {0};
-
- FTS_INFO("[UPGRADE]**********write app to flash**********");
-
- upgrade_ecc = 0;
-
- packet_number = (length) / FTS_PACKET_LENGTH;
- if (((length) % FTS_PACKET_LENGTH) > 0)
- packet_number++;
-
- packet_buf[0] = 0xbf;
-
- for (j = 0; j < packet_number; j++) {
- temp = 0x1000+j * FTS_PACKET_LENGTH;
-
- if (j < (packet_number-1))
- writelenght = FTS_PACKET_LENGTH;
- else
- writelenght = ((length) % FTS_PACKET_LENGTH);
-
- packet_buf[1] = (u8) (temp >> 16);
- packet_buf[2] = (u8) (temp >> 8);
- packet_buf[3] = (u8) temp;
- packet_buf[4] = (u8) (writelenght >> 8);
- packet_buf[5] = (u8) writelenght;
-
- for (i = 0; i < writelenght; i++) {
- packet_buf[6 + i] = readbuf[(temp - 0x1000+i)];
- upgrade_ecc ^= packet_buf[6 + i];
- }
-
- fts_i2c_write(client, packet_buf, (writelenght + 6));
-
- for (i = 0; i < 30; i++) {
- /* read status and check
- * if the app writing is finished
- */
- auc_i2c_write_buf[0] = 0x6a;
- reg_val[0] = reg_val[1] = 0x00;
- fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
-
- if ((j + 0x20+0x1000) == (((reg_val[0]) << 8)
- | reg_val[1]))
- break;
-
- fts_ctpm_upgrade_delay(1000);
- }
- }
-
- msleep(50);
-
- return 0;
-}
-
-#define APP_LEN 0x00
-#define APP_LEN_NE 0x02
-#define APP_P1_ECC 0x04
-#define APP_P1_ECC_NE 0x06
-#define APP_P2_ECC 0x08
-#define APP_P2_ECC_NE 0x0A
-#define APP_LEN_H 0x12
-#define APP_LEN_H_NE 0x14
-#define APP_BLR_ID 0x1C
-#define APP_BLR_ID_NE 0x1D
-#define PBOOT_ID_H 0x1E
-#define PBOOT_ID_L 0x1F
-
-#define AL2_FCS_COEF ((1 << 15) + (1 << 10) + (1 << 3))
-
-#if ((FTS_CHIP_TYPE == _FT8006) || (FTS_CHIP_TYPE == _FT8736))
-#define FW_CFG_TOTAL_SIZE 0x80
-#else
-#define FW_CFG_TOTAL_SIZE 0x00
-#endif
-#define APP1_START 0x00
-#define APP1_LEN 0x100
-#define APP_VERIF_ADDR (APP1_START + APP1_LEN)
-#define APP_VERIF_LEN 0x20
-#define APP1_ECC_ADDR (APP_VERIF_ADDR + APP_P1_ECC)
-#define APP2_START (APP_VERIF_ADDR + APP_VERIF_LEN + FW_CFG_TOTAL_SIZE)
-#define APP2_ECC_ADDR (APP_VERIF_ADDR + APP_P2_ECC)
-/*****************************************************************************
- * Name: DrvReadPram16
- * Brief: Get Word
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static u16 data_word(u8 *pbt_buf, u32 addr)
-{
- return (((u16)pbt_buf[addr]<<8) + pbt_buf[addr+1]);
-}
-
-/******************************************************************************
- * Name: GetCrc16
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static u16 crc_calc(u8 *pbt_buf, u32 addr, u16 length)
-{
- u16 cFcs = 0;
- u16 i, j;
-
- FTS_DEBUG("[UPGRADE][ECC] : %04x data:%04x, len:%04x!!",
- (addr), data_word(pbt_buf, (addr)), length);
- for (i = 0; i < length; i++) {
- cFcs ^= data_word(pbt_buf, (addr+i*2));
- for (j = 0; j < 16; j++) {
- if (cFcs & 1)
- cFcs = (u16)((cFcs >> 1) ^ AL2_FCS_COEF);
- else
- cFcs >>= 1;
- }
- }
-
- return cFcs;
-}
-
-/*****************************************************************************
- * Name: task_check_mem
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static bool ecc_check(u8 *pbt_buf, u32 star_addr, u32 len, u16 ecc_addr)
-{
- u16 ecc1;
- u16 ecc2;
- u16 cal_ecc;
-
- ecc1 = data_word(pbt_buf, ecc_addr);
- ecc2 = data_word(pbt_buf, ecc_addr+2);
-
- if ((ecc1 + ecc2) != 0xFFFF)
- return false;
-
- cal_ecc = crc_calc(pbt_buf, star_addr, (len/2));
-
- FTS_DEBUG("[UPGRADE][ECC] : ecc1 = %x, cal_ecc = %x", ecc1, cal_ecc);
- if (ecc1 != cal_ecc) {
- FTS_DEBUG("[UPGRADE][ECC] : ecc error!!");
- return false;
- }
-
- return true;
-}
-
-/*****************************************************************************
- * Name: fts_check_app_bin_valid_idc
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-bool fts_check_app_bin_valid_idc(u8 *pbt_buf)
-{
- u32 len;
-#if (FTS_CHIP_TYPE != _FT8006)
- /* 1. First Byte */
- if (pbt_buf[0] != 0x02) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- the first byte(%x) error",
- pbt_buf[0]);
- return false;
- }
-#endif
- /* 2 PART1 ECC */
- if (!ecc_check(pbt_buf, APP1_START, APP1_LEN, APP1_ECC_ADDR)) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- ecc1 error");
- return false;
- }
-
- /* 3. PART2 ECC */
- if ((data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN)
- + data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN_NE)) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- Length XOR error");
- return false;
- }
-
- len = data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN);
-#if (FTS_CHIP_TYPE == _FT8006)
- if ((data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN_H)
- + data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN_H_NE)) != 0xFFFF) {
- FTS_DEBUG("[UPGRADE]APP.BIN Verify- Length2 XOR error");
- return false;
- }
-
- len += ((u32)data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN_H) << 16);
-#endif
- FTS_DEBUG("%x %x %x %x", APP2_START, len,
- ((u32)data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN_H) << 16),
- data_word(pbt_buf, APP_VERIF_ADDR+APP_LEN));
-
- len -= APP2_START;
-
- return ecc_check(pbt_buf, APP2_START, len, APP2_ECC_ADDR);
-}
-
-
-#endif /* IDC */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
deleted file mode 100644
index aa4c9cf..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *
- * FocalTech fts TouchScreen driver.
- *
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_upgrade_test.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-22
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
-
-/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
-#include "../focaltech_core.h"
-#include "../focaltech_flash.h"
-#include <linux/timer.h>
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-#define FTS_GET_UPGRADE_TIME 0
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-
-#define FTS_DEBUG_UPGRADE(fmt, args...) do {\
- pr_err("[FTS][UPGRADE]:################\n");\
- pr_err("[FTS][UPGRADE]: "fmt"\n", ##args);\
- pr_err("[FTS][UPGRADE]:################\n");\
- } while (0)\
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-#if (FTS_UPGRADE_STRESS_TEST)
-/************************************************************************
- * Name: fts_ctpm_auto_upgrade_pingpong
- * Brief: 0
- * Input: 0
- * Output: 0
- * Return: 0
- ***********************************************************************/
-static int fts_ctpm_auto_upgrade_pingpong(struct i2c_client *client)
-{
- u8 uc_tp_fm_ver;
- int i_ret = 0;
- u8 uc_upgrade_times = 0;
-
- FTS_FUNC_ENTER();
-
- /* pingpong test mode, need upgrade */
- FTS_INFO("[UPGRADE]: pingpong test mode, need upgrade!!");
- do {
- uc_upgrade_times++;
-
- /* fw upgrade */
- i_ret = fts_ctpm_fw_upgrade(client);
-
- if (i_ret == 0) {
- /* upgrade success */
- fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
- FTS_DEBUG("[UPGRADE]: upgrade to new version 0x%x",
- uc_tp_fm_ver);
- } else {
- /* upgrade fail */
- /* if upgrade fail, reset to run ROM.
- * if app in flash is ok. TP will work success
- */
- FTS_INFO("[UPGRADE]: upgrade fail, reset now!!");
- fts_ctpm_rom_or_pram_reset(client);
- }
- /* if upgrade fail, upgrade again. then return */
- } while ((i_ret != 0) && (uc_upgrade_times < 2));
-
- FTS_FUNC_EXIT();
- return i_ret;
-}
-
-/************************************************************************
- * Name: fts_ctpm_auto_upgrade
- * Brief: 0
- * Input: 0
- * Output: 0
- * Return: 0
- ***********************************************************************/
-void fts_ctpm_display_upgrade_time(bool start_time)
-{
-#if FTS_GET_UPGRADE_TIME
- static struct timeval tpend;
- static struct timeval tpstart;
- static int timeuse;
-
- if (start_time) {
- do_gettimeofday(&tpstart);
- } else {
- do_gettimeofday(&tpend);
- timeuse = 1000000 * (tpend.tv_sec-tpstart.tv_sec)
- + tpend.tv_usec-tpstart.tv_usec;
- timeuse /= 1000000;
- FTS_DEBUG("[UPGRADE]: upgrade success : Use time: %d Seconds!!",
- timeuse);
- }
-#endif
-}
-
-/************************************************************************
- * Name: fts_ctpm_auto_upgrade
- * Brief: 0
- * Input: 0
- * Output: 0
- * Return: 0
- ***********************************************************************/
-int fts_ctpm_auto_upgrade(struct i2c_client *client)
-{
- int i_ret = 0;
- static int uc_ErrorTimes;
- static int uc_UpgradeTimes;
-
-
- device_init_wakeup(&client->dev, 1);
- pm_stay_awake(&client->dev);
-
- /* (FTS_GET_VENDOR_ID_NUM == 0) */
- g_fw_file = CTPM_FW;
- g_fw_len = fts_getsize(FW_SIZE);
- FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
-
- do {
- uc_UpgradeTimes++;
-
- FTS_DEBUG_UPGRADE("start to upgrade %d times !!",
- uc_UpgradeTimes);
-
- fts_ctpm_display_upgrade_time(true);
-
- i_ret = fts_ctpm_auto_upgrade_pingpong(client);
- if (i_ret == 0)
- fts_ctpm_display_upgrade_time(false);
- else
- uc_ErrorTimes++;
-
- FTS_DEBUG_UPGRADE("upgrade %d times, error %d times!!",
- uc_UpgradeTimes, uc_ErrorTimes);
- } while (uc_UpgradeTimes < (FTS_UPGRADE_TEST_NUMBER));
-
- pm_relax(&client->dev);
- device_init_wakeup(&client->dev, 0);
-
- return 0;
-}
-#endif
-
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
index d24cd8a..6faa074 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
+ * Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,635 +16,525 @@
*/
/*****************************************************************************
- *
- * File Name: focaltech_gestrue.c
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-08
- *
- * Abstract:
- *
- * Reference:
- *
- *****************************************************************************/
+*
+* File Name: focaltech_gestrue.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
/*****************************************************************************
- * 1.Included header files
- *****************************************************************************/
+* 1.Included header files
+*****************************************************************************/
#include "focaltech_core.h"
-#if FTS_GESTURE_EN
+
/******************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-#define KEY_GESTURE_U KEY_U
-#define KEY_GESTURE_UP KEY_UP
-#define KEY_GESTURE_DOWN KEY_DOWN
+* Private constant and macro definitions using #define
+*****************************************************************************/
#define KEY_GESTURE_LEFT KEY_LEFT
#define KEY_GESTURE_RIGHT KEY_RIGHT
+#define KEY_GESTURE_UP KEY_UP
+#define KEY_GESTURE_DOWN KEY_DOWN
+#define KEY_GESTURE_DOUBLE_TAP KEY_WAKEUP // double tap to wake
#define KEY_GESTURE_O KEY_O
-#define KEY_GESTURE_E KEY_E
-#define KEY_GESTURE_M KEY_M
-#define KEY_GESTURE_L KEY_L
#define KEY_GESTURE_W KEY_W
+#define KEY_GESTURE_M KEY_M
+#define KEY_GESTURE_E KEY_E
+#define KEY_GESTURE_C KEY_C
+#define KEY_GESTURE_L KEY_L
#define KEY_GESTURE_S KEY_S
#define KEY_GESTURE_V KEY_V
-#define KEY_GESTURE_C KEY_C
#define KEY_GESTURE_Z KEY_Z
#define GESTURE_LEFT 0x20
#define GESTURE_RIGHT 0x21
#define GESTURE_UP 0x22
#define GESTURE_DOWN 0x23
-#define GESTURE_DOUBLECLICK 0x24
+#define GESTURE_DOUBLE_TAP 0x24
#define GESTURE_O 0x30
#define GESTURE_W 0x31
#define GESTURE_M 0x32
#define GESTURE_E 0x33
+#define GESTURE_C 0x34
#define GESTURE_L 0x44
#define GESTURE_S 0x46
#define GESTURE_V 0x54
-#define GESTURE_Z 0x41
-#define GESTURE_C 0x34
-#define FTS_GESTRUE_POINTS 255
-#define FTS_GESTRUE_POINTS_HEADER 8
+#define GESTURE_Z 0x65
-#define GESTURE_SMALL_AREA 0x25 /* TP Coverage < 50% */
-#define GESTURE_LARGE_AREA 0x26 /* TP Coverage > 50% */
+#define PAGESIZE 512
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
/*
- * header - byte0:gesture id
- * byte1:pointnum
- * byte2~7:reserved
- * coordinate_x - All gesture point x coordinate
- * coordinate_y - All gesture point y coordinate
- * mode - 1:enable gesture function(default)
- * - 0:disable
- * active - 1:enter into gesture(suspend)
- * 0:gesture disable or resume
- */
+* gesture_id - mean which gesture is recognised
+* point_num - points number of this gesture
+* coordinate_x - All gesture point x coordinate
+* coordinate_y - All gesture point y coordinate
+* mode - gesture enable/disable, need enable by host
+* - 1:enable gesture function(default) 0:disable
+* active - gesture work flag,
+* always set 1 when suspend, set 0 when resume
+*/
struct fts_gesture_st {
- u8 header[FTS_GESTRUE_POINTS_HEADER];
- u16 coordinate_x[FTS_GESTRUE_POINTS];
- u16 coordinate_y[FTS_GESTRUE_POINTS];
- u8 mode;
- u8 active;
+ u8 gesture_id;
+ u8 point_num;
+ u16 coordinate_x[FTS_GESTURE_POINTS_MAX];
+ u16 coordinate_y[FTS_GESTURE_POINTS_MAX];
};
/*****************************************************************************
- * Static variables
- *****************************************************************************/
+* Static variables
+*****************************************************************************/
static struct fts_gesture_st fts_gesture_data;
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+uint32_t gestures_enabled;
/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-static ssize_t fts_gesture_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-static ssize_t fts_gesture_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-static ssize_t fts_gesture_buf_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-static ssize_t fts_gesture_buf_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
+* Static function prototypes
+*****************************************************************************/
+static ssize_t fts_gesture_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ u8 val = 0;
+ struct fts_ts_data *ts_data = fts_data;
+
+ mutex_lock(&ts_data->input_dev->mutex);
+ fts_read_reg(FTS_REG_GESTURE_EN, &val);
+ count = snprintf(buf, PAGE_SIZE, "Gesture Mode:%s\n",
+ ts_data->gesture_mode ? "On" : "Off");
+ count += snprintf(buf + count, PAGE_SIZE, "Reg(0xD0)=%d\n", val);
+ mutex_unlock(&ts_data->input_dev->mutex);
+
+ return count;
+}
+
+static ssize_t fts_gesture_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct fts_ts_data *ts_data = fts_data;
+
+ mutex_lock(&ts_data->input_dev->mutex);
+ if (FTS_SYSFS_ECHO_ON(buf)) {
+ FTS_DEBUG("enable gesture");
+ ts_data->gesture_mode = ENABLE;
+ } else if (FTS_SYSFS_ECHO_OFF(buf)) {
+ FTS_DEBUG("disable gesture");
+ ts_data->gesture_mode = DISABLE;
+ }
+ mutex_unlock(&ts_data->input_dev->mutex);
+
+ return count;
+}
+
+static ssize_t fts_gesture_buf_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ int i = 0;
+ struct input_dev *input_dev = fts_data->input_dev;
+ struct fts_gesture_st *gesture = &fts_gesture_data;
+
+ mutex_lock(&input_dev->mutex);
+ count = snprintf(buf, PAGE_SIZE, "Gesture ID:%d\n", gesture->gesture_id);
+ count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum:%d\n",
+ gesture->point_num);
+ count += snprintf(buf + count, PAGE_SIZE, "Gesture Points Buffer:\n");
+
+ /* save point data,max:6 */
+ for (i = 0; i < FTS_GESTURE_POINTS_MAX; i++) {
+ count += snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i,
+ gesture->coordinate_x[i], gesture->coordinate_y[i]);
+ if ((i + 1) % 4 == 0)
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ }
+ count += snprintf(buf + count, PAGE_SIZE, "\n");
+ mutex_unlock(&input_dev->mutex);
+
+ return count;
+}
+
+static ssize_t fts_gesture_buf_store(
+ struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return -EPERM;
+}
+
/* sysfs gesture node
- * read example: cat fts_gesture_mode ---read gesture mode
- * write example:echo 01 > fts_gesture_mode ---write gesture mode to 01
+ * read example: cat fts_gesture_mode ---read gesture mode
+ * write example:echo 1 > fts_gesture_mode --- write gesture mode to 1
*
*/
-static DEVICE_ATTR(fts_gesture_mode, 0644,
- fts_gesture_show, fts_gesture_store);
+static DEVICE_ATTR(fts_gesture_mode, S_IRUGO | S_IWUSR, fts_gesture_show,
+ fts_gesture_store);
/*
- * read example: cat fts_gesture_buf ---read gesture buf
+ * read example: cat fts_gesture_buf --- read gesture buf
*/
-static DEVICE_ATTR(fts_gesture_buf, 0644,
- fts_gesture_buf_show, fts_gesture_buf_store);
+static DEVICE_ATTR(fts_gesture_buf, S_IRUGO | S_IWUSR,
+ fts_gesture_buf_show, fts_gesture_buf_store);
+
static struct attribute *fts_gesture_mode_attrs[] = {
-
-
- &dev_attr_fts_gesture_mode.attr,
- &dev_attr_fts_gesture_buf.attr,
- NULL,
+ &dev_attr_fts_gesture_mode.attr,
+ &dev_attr_fts_gesture_buf.attr,
+ NULL,
};
static struct attribute_group fts_gesture_group = {
-
- .attrs = fts_gesture_mode_attrs,
+ .attrs = fts_gesture_mode_attrs,
};
-/************************************************************************
- * Name: fts_gesture_show
- * Brief:
- * Input: device, device attribute, char buf
- * Output:
- * Return:
- ***********************************************************************/
-static ssize_t fts_gesture_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static int fts_create_gesture_sysfs(struct device *dev)
{
- int count;
- u8 val;
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ int ret = 0;
- mutex_lock(&fts_input_dev->mutex);
- fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val);
- count = snprintf(buf, PAGE_SIZE, "Gesture Mode: %s\n",
- fts_gesture_data.mode ? "On" : "Off");
- count += snprintf(buf + count, PAGE_SIZE - count,
- "Reg(0xD0) = %d\n", val);
- mutex_unlock(&fts_input_dev->mutex);
+ ret = sysfs_create_group(&dev->kobj, &fts_gesture_group);
+ if (ret) {
+ FTS_ERROR("gesture sys node create fail");
+ sysfs_remove_group(&dev->kobj, &fts_gesture_group);
+ return ret;
+ }
- return count;
+ return 0;
}
-/************************************************************************
- * Name: fts_gesture_store
- * Brief:
- * Input: device, device attribute, char buf, char count
- * Output:
- * Return:
- ***********************************************************************/
-static ssize_t fts_gesture_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- mutex_lock(&fts_input_dev->mutex);
-
- if (FTS_SYSFS_ECHO_ON(buf)) {
- FTS_INFO("[GESTURE]enable gesture");
- fts_gesture_data.mode = ENABLE;
- } else if (FTS_SYSFS_ECHO_OFF(buf)) {
- FTS_INFO("[GESTURE]disable gesture");
- fts_gesture_data.mode = DISABLE;
- }
-
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-
-/************************************************************************
- * Name: fts_gesture_buf_show
- * Brief:
- * Input: device, device attribute, char buf
- * Output:
- * Return:
- ***********************************************************************/
-static ssize_t fts_gesture_buf_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int count;
- int i = 0;
-
- mutex_lock(&fts_input_dev->mutex);
- count = snprintf(buf, PAGE_SIZE, "Gesture ID: 0x%x\n",
- fts_gesture_data.header[0]);
- count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum: %d\n",
- fts_gesture_data.header[1]);
- count += snprintf(buf + count, PAGE_SIZE, "Gesture Point Buf:\n");
-
- for (i = 0; i < fts_gesture_data.header[1]; i++) {
- count += snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ",
- i, fts_gesture_data.coordinate_x[i],
- fts_gesture_data.coordinate_y[i]);
- if ((i + 1)%4 == 0)
- count += snprintf(buf + count, PAGE_SIZE, "\n");
- }
- count += snprintf(buf + count, PAGE_SIZE, "\n");
- mutex_unlock(&fts_input_dev->mutex);
-
- return count;
-}
-
-/************************************************************************
- * Name: fts_gesture_buf_store
- * Brief:
- * Input: device, device attribute, char buf, char count
- * Output:
- * Return:
- ***********************************************************************/
-static ssize_t fts_gesture_buf_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- /* place holder for future use */
- return -EPERM;
-}
-
-/*****************************************************************************
- * Name: fts_create_gesture_sysfs
- * Brief:
- * Input:
- * Output:
- * Return: 0-success or others-error
- *****************************************************************************/
-int fts_create_gesture_sysfs(struct i2c_client *client)
-{
- int ret = 0;
-
- ret = sysfs_create_group(&client->dev.kobj, &fts_gesture_group);
- if (ret != 0) {
- FTS_ERROR("[GESTURE]fts_gesture_group(sysfs) create failed!");
- sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
- return ret;
- }
- return 0;
-}
-
-/*****************************************************************************
- * Name: fts_gesture_report
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
{
- int gesture;
+ int gesture;
- FTS_FUNC_ENTER();
- FTS_DEBUG("fts gesture_id==0x%x ", gesture_id);
- switch (gesture_id) {
- case GESTURE_LEFT:
- gesture = KEY_GESTURE_LEFT;
- break;
- case GESTURE_RIGHT:
- gesture = KEY_GESTURE_RIGHT;
- break;
- case GESTURE_UP:
- gesture = KEY_GESTURE_UP;
- break;
- case GESTURE_DOWN:
- gesture = KEY_GESTURE_DOWN;
- break;
- case GESTURE_DOUBLECLICK:
- gesture = KEY_GESTURE_U;
- break;
- case GESTURE_O:
- gesture = KEY_GESTURE_O;
- break;
- case GESTURE_W:
- gesture = KEY_GESTURE_W;
- break;
- case GESTURE_M:
- gesture = KEY_GESTURE_M;
- break;
- case GESTURE_E:
- gesture = KEY_GESTURE_E;
- break;
- case GESTURE_L:
- gesture = KEY_GESTURE_L;
- break;
- case GESTURE_S:
- gesture = KEY_GESTURE_S;
- break;
- case GESTURE_V:
- gesture = KEY_GESTURE_V;
- break;
- case GESTURE_Z:
- gesture = KEY_GESTURE_Z;
- break;
- case GESTURE_C:
- gesture = KEY_GESTURE_C;
- break;
- default:
- gesture = -1;
- break;
- }
-
- /* report event key */
- if (gesture != -1) {
- FTS_DEBUG("Gesture Code=%d", gesture);
- input_report_key(input_dev, gesture, 1);
- input_sync(input_dev);
- input_report_key(input_dev, gesture, 0);
- input_sync(input_dev);
- }
-
- FTS_FUNC_EXIT();
-}
-
-/************************************************************************
- * Name: fts_gesture_readdata
- * Brief: read data from TP register
- * Input:
- * Output:
- * Return: fail <0
- ***********************************************************************/
-static int fts_gesture_read_buffer(struct i2c_client *client,
- u8 *buf, int read_bytes)
-{
- int remain_bytes;
- int ret;
- int i;
-
- if (read_bytes <= I2C_BUFFER_LENGTH_MAXINUM) {
- ret = fts_i2c_read(client, buf, 1, buf, read_bytes);
- } else {
- ret = fts_i2c_read(client, buf, 1,
- buf, I2C_BUFFER_LENGTH_MAXINUM);
- remain_bytes = read_bytes - I2C_BUFFER_LENGTH_MAXINUM;
- for (i = 1; remain_bytes > 0; i++) {
- if (remain_bytes <= I2C_BUFFER_LENGTH_MAXINUM)
- ret = fts_i2c_read(client, buf, 0, buf
- + I2C_BUFFER_LENGTH_MAXINUM * i,
- remain_bytes);
- else
- ret = fts_i2c_read(client, buf, 0, buf
- + I2C_BUFFER_LENGTH_MAXINUM * i,
- I2C_BUFFER_LENGTH_MAXINUM);
- remain_bytes -= I2C_BUFFER_LENGTH_MAXINUM;
- }
- }
-
- return ret;
-}
-
-/************************************************************************
- * Name: fts_gesture_fw
- * Brief: Check IC's gesture recognise by FW or not
- * Input:
- * Output:
- * Return: 1- FW 0- Driver
- ***********************************************************************/
-static int fts_gesture_fw(void)
-{
- int ret = 0;
-
- switch (chip_types.chip_idh) {
- case 0x54:
- case 0x58:
- case 0x64:
- case 0x87:
- case 0x86:
- case 0x80:
- case 0xE7:
- ret = 1;
- break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-/************************************************************************
- * Name: fts_gesture_readdata
- * Brief: read data from TP register
- * Input:
- * Output:
- * Return: fail <0
- ***********************************************************************/
-int fts_gesture_readdata(struct i2c_client *client)
-{
- u8 buf[FTS_GESTRUE_POINTS * 4] = { 0 };
- int ret = -1;
- int i = 0;
- int gestrue_id = 0;
- int read_bytes = 0;
- u8 pointnum;
-
- FTS_FUNC_ENTER();
- /* init variable before read gesture point */
- memset(fts_gesture_data.header, 0, FTS_GESTRUE_POINTS_HEADER);
- memset(fts_gesture_data.coordinate_x, 0,
- FTS_GESTRUE_POINTS * sizeof(u16));
- memset(fts_gesture_data.coordinate_y, 0,
- FTS_GESTRUE_POINTS * sizeof(u16));
-
- buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
- ret = fts_i2c_read(client, buf, 1, buf, FTS_GESTRUE_POINTS_HEADER);
- if (ret < 0) {
- FTS_ERROR("[GESTURE]Read gesture header data failed!!");
- FTS_FUNC_EXIT();
- return ret;
- }
-
- memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
- gestrue_id = buf[0];
- pointnum = buf[1];
-
- if (gestrue_id == GESTURE_SMALL_AREA) {
- FTS_INFO("[GESTURE] Wakeup gesture.");
- input_report_key(fts_input_dev, KEY_POWER, 1);
- input_sync(fts_input_dev);
- input_report_key(fts_input_dev, KEY_POWER, 0);
- input_sync(fts_input_dev);
-
- } else if (gestrue_id == GESTURE_LARGE_AREA) {
- FTS_INFO("[GESTURE] Large object detected.");
- } else if (fts_gesture_fw()) {
- /* FW recognize gesture */
- read_bytes = ((int)pointnum) * 4 + 2;
- buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
- FTS_DEBUG("[GESTURE]PointNum=%d", pointnum);
- ret = fts_gesture_read_buffer(client, buf, read_bytes);
- if (ret < 0) {
- FTS_ERROR("[GESTURE]Read gesture touch data failed!!");
- FTS_FUNC_EXIT();
- return ret;
- }
-
- fts_gesture_report(fts_input_dev, gestrue_id);
- for (i = 0; i < pointnum; i++) {
- fts_gesture_data.coordinate_x[i] =
- (((s16) buf[0 + (4 * i + 2)]) & 0x0F) << 8
- | (((s16) buf[1 + (4 * i + 2)]) & 0xFF);
- fts_gesture_data.coordinate_y[i] =
- (((s16) buf[2 + (4 * i + 2)]) & 0x0F) << 8
- | (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
- }
-
-
- } else {
- FTS_ERROR("[GESTURE]IC 0x%x need lib to support gestures.",
- chip_types.chip_idh);
- }
-
- FTS_FUNC_EXIT();
-
- return 0;
+ FTS_DEBUG("gesture_id:0x%x", gesture_id);
+ switch (gesture_id) {
+ case GESTURE_LEFT:
+ gesture = KEY_GESTURE_LEFT;
+ break;
+ case GESTURE_RIGHT:
+ gesture = KEY_GESTURE_RIGHT;
+ break;
+ case GESTURE_UP:
+ gesture = KEY_GESTURE_UP;
+ break;
+ case GESTURE_DOWN:
+ gesture = KEY_GESTURE_DOWN;
+ break;
+ case GESTURE_DOUBLE_TAP:
+ gesture = KEY_GESTURE_DOUBLE_TAP;
+ break;
+ case GESTURE_O:
+ gesture = KEY_GESTURE_O;
+ break;
+ case GESTURE_W:
+ gesture = KEY_GESTURE_W;
+ break;
+ case GESTURE_M:
+ gesture = KEY_GESTURE_M;
+ break;
+ case GESTURE_E:
+ gesture = KEY_GESTURE_E;
+ break;
+ case GESTURE_L:
+ gesture = KEY_GESTURE_L;
+ break;
+ case GESTURE_S:
+ gesture = KEY_GESTURE_S;
+ break;
+ case GESTURE_V:
+ gesture = KEY_GESTURE_V;
+ break;
+ case GESTURE_Z:
+ gesture = KEY_GESTURE_Z;
+ break;
+ case GESTURE_C:
+ gesture = KEY_GESTURE_C;
+ break;
+ default:
+ gesture = -1;
+ break;
+ }
+ /* report event key */
+ if (gesture != -1) {
+ FTS_DEBUG("Gesture Code=%d", gesture);
+ input_report_key(input_dev, gesture, 1);
+ input_sync(input_dev);
+ input_report_key(input_dev, gesture, 0);
+ input_sync(input_dev);
+ }
}
/*****************************************************************************
- * Name: fts_gesture_recovery
- * Brief: recovery gesture state when reset or power on
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-void fts_gesture_recovery(struct i2c_client *client)
+* Name: fts_gesture_readdata
+* Brief: Read information about gesture: enable flag/gesture points..., if ges-
+* ture enable, save gesture points' information, and report to OS.
+* It will be called this function every intrrupt when FTS_GESTURE_EN = 1
+*
+* gesture data length: 1(enable) + 1(reserve) + 2(header) + 6 * 4
+* Input: ts_data - global struct data
+* data - gesture data buffer if non-flash, else NULL
+* Output:
+* Return: 0 - read gesture data successfully, the report data is gesture data
+* 1 - tp not in suspend/gesture not enable in TP FW
+* -Exx - error
+*****************************************************************************/
+int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data)
{
- if (fts_gesture_data.mode && fts_gesture_data.active) {
- fts_i2c_write_reg(client, 0xD1, 0xff);
- fts_i2c_write_reg(client, 0xD2, 0xff);
- fts_i2c_write_reg(client, 0xD5, 0xff);
- fts_i2c_write_reg(client, 0xD6, 0xff);
- fts_i2c_write_reg(client, 0xD7, 0xff);
- fts_i2c_write_reg(client, 0xD8, 0xff);
- fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, ENABLE);
- }
+ int ret = 0;
+ int i = 0;
+ int index = 0;
+ u8 buf[FTS_GESTURE_DATA_LEN] = { 0 };
+ struct input_dev *input_dev = ts_data->input_dev;
+ struct fts_gesture_st *gesture = &fts_gesture_data;
+
+ if (!ts_data->suspended || !ts_data->gesture_mode) {
+ return 1;
+ }
+
+ msleep(40);
+
+ ret = fts_read_reg(FTS_REG_GESTURE_EN, &buf[0]);
+ if ((ret < 0) || (buf[0] != ENABLE)) {
+ FTS_DEBUG("gesture not enable in fw, don't process gesture");
+ return 1;
+ }
+
+ msleep(20);
+
+ buf[2] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
+ ret = fts_read(&buf[2], 1, &buf[2], FTS_GESTURE_DATA_LEN - 2);
+ if (ret < 0) {
+ FTS_ERROR("read gesture header data fail");
+ return ret;
+ }
+
+ gesture->gesture_id = buf[2];
+ gesture->point_num = buf[3];
+ FTS_DEBUG("gesture_id=%d, point_num=%d",
+ gesture->gesture_id, gesture->point_num);
+
+ if ((gesture->gesture_id & gestures_enabled) == 0) {
+ FTS_DEBUG("gesture is not enabled, not processing gesture");
+ return 1;
+ }
+
+ /* init variable before read gesture point */
+ memset(gesture->coordinate_x, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
+ memset(gesture->coordinate_y, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
+
+ /* save point data,max:6 */
+ for (i = 0; i < FTS_GESTURE_POINTS_MAX; i++) {
+ index = 4 * i + 4;
+ gesture->coordinate_x[i] = (u16)(((buf[0 + index] & 0x0F) << 8)
+ + buf[1 + index]);
+ gesture->coordinate_y[i] = (u16)(((buf[2 + index] & 0x0F) << 8)
+ + buf[3 + index]);
+ }
+
+ /* report gesture to OS */
+ fts_gesture_report(input_dev, gesture->gesture_id);
+ return 0;
}
-/*****************************************************************************
- * Name: fts_gesture_suspend
- * Brief:
- * Input:
- * Output: None
- * Return: None
- *****************************************************************************/
-int fts_gesture_suspend(struct i2c_client *i2c_client)
+void fts_gesture_recovery(struct fts_ts_data *ts_data)
{
- int i;
- u8 state;
-
- FTS_FUNC_ENTER();
-
- /* gesture not enable, return immediately */
- if (fts_gesture_data.mode == 0) {
- FTS_DEBUG("gesture is disabled");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
-
- for (i = 0; i < 5; i++) {
- fts_i2c_write_reg(i2c_client, 0xd1, 0xff);
- fts_i2c_write_reg(i2c_client, 0xd2, 0xff);
- fts_i2c_write_reg(i2c_client, 0xd5, 0xff);
- fts_i2c_write_reg(i2c_client, 0xd6, 0xff);
- fts_i2c_write_reg(i2c_client, 0xd7, 0xff);
- fts_i2c_write_reg(i2c_client, 0xd8, 0xff);
- fts_i2c_write_reg(i2c_client, FTS_REG_GESTURE_EN, 0x01);
- usleep_range(1000, 2000);
- fts_i2c_read_reg(i2c_client, FTS_REG_GESTURE_EN, &state);
- if (state == 1)
- break;
- }
-
- if (i >= 5) {
- FTS_ERROR("[GESTURE]Enter into gesture(suspend) failed!\n");
- FTS_FUNC_EXIT();
- return -EAGAIN;
- }
-
- fts_gesture_data.active = 1;
- FTS_DEBUG("[GESTURE]Enter into gesture(suspend) successfully!");
- FTS_FUNC_EXIT();
- return 0;
+ if (ts_data->gesture_mode && ts_data->suspended) {
+ FTS_DEBUG("gesture recovery...");
+ fts_write_reg(0xD1, 0xFF);
+ fts_write_reg(0xD2, 0xFF);
+ fts_write_reg(0xD5, 0xFF);
+ fts_write_reg(0xD6, 0xFF);
+ fts_write_reg(0xD7, 0xFF);
+ fts_write_reg(0xD8, 0xFF);
+ fts_write_reg(FTS_REG_GESTURE_EN, ENABLE);
+ }
}
-/*****************************************************************************
- * Name: fts_gesture_resume
- * Brief:
- * Input:
- * Output: None
- * Return: None
- *****************************************************************************/
-int fts_gesture_resume(struct i2c_client *client)
+int fts_gesture_suspend(struct fts_ts_data *ts_data)
{
- int i;
- u8 state;
+ int i = 0;
+ u8 state = 0xFF;
- FTS_FUNC_ENTER();
+ FTS_FUNC_ENTER();
+ if (enable_irq_wake(ts_data->irq)) {
+ FTS_DEBUG("enable_irq_wake(irq:%d) fail", ts_data->irq);
+ }
- /* gesture not enable, return immediately */
- if (fts_gesture_data.mode == 0) {
- FTS_DEBUG("gesture is disabled");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
+ for (i = 0; i < 5; i++) {
+ fts_write_reg(0xD1, 0xFF);
+ fts_write_reg(0xD2, 0xFF);
+ fts_write_reg(0xD5, 0xFF);
+ fts_write_reg(0xD6, 0xFF);
+ fts_write_reg(0xD7, 0xFF);
+ fts_write_reg(0xD8, 0xFF);
+ fts_write_reg(FTS_REG_GESTURE_EN, ENABLE);
+ msleep(1);
+ fts_read_reg(FTS_REG_GESTURE_EN, &state);
+ if (state == ENABLE)
+ break;
+ }
- if (fts_gesture_data.active == 0) {
- FTS_DEBUG("gesture is unactive");
- FTS_FUNC_EXIT();
- return -EINVAL;
- }
+ if (i >= 5)
+ FTS_ERROR("make IC enter into gesture(suspend) fail,state:%x", state);
+ else
+ FTS_INFO("Enter into gesture(suspend) successfully");
- fts_gesture_data.active = 0;
- for (i = 0; i < 5; i++) {
- fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, 0x00);
- usleep_range(1000, 2000);
- fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state);
- if (state == 0)
- break;
- }
-
- if (i >= 5)
- FTS_ERROR("[GESTURE]Clear gesture(resume) failed!\n");
-
- FTS_FUNC_EXIT();
-
- return 0;
+ FTS_FUNC_EXIT();
+ return 0;
}
-/*****************************************************************************
- * Name: fts_gesture_init
- * Brief:
- * Input:
- * Output: None
- * Return: None
- *****************************************************************************/
-int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client)
+int fts_gesture_resume(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
- input_set_capability(input_dev, EV_KEY, KEY_POWER);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_U);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z);
- input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C);
+ int i = 0;
+ u8 state = 0xFF;
- __set_bit(KEY_GESTURE_RIGHT, input_dev->keybit);
- __set_bit(KEY_GESTURE_LEFT, input_dev->keybit);
- __set_bit(KEY_GESTURE_UP, input_dev->keybit);
- __set_bit(KEY_GESTURE_DOWN, input_dev->keybit);
- __set_bit(KEY_GESTURE_U, input_dev->keybit);
- __set_bit(KEY_GESTURE_O, input_dev->keybit);
- __set_bit(KEY_GESTURE_E, input_dev->keybit);
- __set_bit(KEY_GESTURE_M, input_dev->keybit);
- __set_bit(KEY_GESTURE_W, input_dev->keybit);
- __set_bit(KEY_GESTURE_L, input_dev->keybit);
- __set_bit(KEY_GESTURE_S, input_dev->keybit);
- __set_bit(KEY_GESTURE_V, input_dev->keybit);
- __set_bit(KEY_GESTURE_C, input_dev->keybit);
- __set_bit(KEY_GESTURE_Z, input_dev->keybit);
+ FTS_FUNC_ENTER();
+ if (disable_irq_wake(ts_data->irq)) {
+ FTS_DEBUG("disable_irq_wake(irq:%d) fail", ts_data->irq);
+ }
- fts_create_gesture_sysfs(client);
- fts_gesture_data.mode = 1;
- fts_gesture_data.active = 0;
- FTS_FUNC_EXIT();
+ for (i = 0; i < 5; i++) {
+ fts_write_reg(FTS_REG_GESTURE_EN, DISABLE);
+ msleep(1);
+ fts_read_reg(FTS_REG_GESTURE_EN, &state);
+ if (state == DISABLE)
+ break;
+ }
- return 0;
+ if (i >= 5)
+ FTS_ERROR("make IC exit gesture(resume) fail,state:%x", state);
+ else
+ FTS_INFO("resume from gesture successfully");
+
+ FTS_FUNC_EXIT();
+ return 0;
}
-/************************************************************************
- * Name: fts_gesture_exit
- * Brief: call when driver removed
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_gesture_exit(struct i2c_client *client)
-{
- FTS_FUNC_ENTER();
- sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
- FTS_FUNC_EXIT();
+#define GESTURE_ATTR(name, flag)\
+ static ssize_t name##_enable_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)\
+ {\
+ int ret = 0;\
+ char page[PAGESIZE];\
+ ret = sprintf(page, "%d\n", (gestures_enabled & flag) != 0);\
+ ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page));\
+ return ret;\
+ }\
+ static ssize_t name##_enable_write_func(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)\
+ {\
+ int ret, write_flag = 0;\
+ char page[PAGESIZE] = {0};\
+ ret = copy_from_user(page, user_buf, count);\
+ ret = sscanf(page, "%d", &write_flag);\
+ if (write_flag) {\
+ gestures_enabled |= flag;\
+ } else {\
+ gestures_enabled &= ~flag;\
+ }\
+ return count;\
+ }\
+ static const struct file_operations name##_enable_proc_fops = {\
+ .write = name##_enable_write_func,\
+ .read = name##_enable_read_func,\
+ .open = simple_open,\
+ .owner = THIS_MODULE,\
+ };
- return 0;
+GESTURE_ATTR(double_tap, GESTURE_DOUBLE_TAP);
+
+#undef GESTURE_ATTR
+
+#define CREATE_PROC_NODE(PARENT, NAME, MODE)\
+ node = proc_create(#NAME, MODE, PARENT, &NAME##_proc_fops);\
+ if (node == NULL) {\
+ ret = -ENOMEM;\
+ FTS_ERROR("Couldn't create " #NAME " in " #PARENT "\n");\
+ }
+
+#define CREATE_GESTURE_NODE(NAME)\
+ CREATE_PROC_NODE(touchpanel, NAME##_enable, 0666)
+
+static int fts_gesture_proc_init(void) {
+ int ret = 0;
+ struct proc_dir_entry *node = NULL;
+ struct proc_dir_entry *touchpanel = NULL;
+
+ touchpanel = proc_mkdir("touchpanel", NULL);
+ if (touchpanel == NULL) {
+ ret = -ENOMEM;
+ FTS_ERROR("Couldn't create touchpanel proc directory\n");
+ }
+
+ CREATE_GESTURE_NODE(double_tap);
+
+ return ret;
}
-#endif
+
+#undef CREATE_GESTURE_NODE
+#undef CREATE_PROC_NODE
+
+int fts_gesture_init(struct fts_ts_data *ts_data)
+{
+ struct input_dev *input_dev = ts_data->input_dev;
+
+ FTS_FUNC_ENTER();
+
+ // enable double tap gesture by default
+ gestures_enabled = GESTURE_DOUBLE_TAP;
+
+ input_set_capability(input_dev, EV_KEY, KEY_POWER);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOUBLE_TAP);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z);
+ input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C);
+
+ __set_bit(KEY_GESTURE_RIGHT, input_dev->keybit);
+ __set_bit(KEY_GESTURE_LEFT, input_dev->keybit);
+ __set_bit(KEY_GESTURE_UP, input_dev->keybit);
+ __set_bit(KEY_GESTURE_DOWN, input_dev->keybit);
+ __set_bit(KEY_GESTURE_DOUBLE_TAP, input_dev->keybit);
+ __set_bit(KEY_GESTURE_O, input_dev->keybit);
+ __set_bit(KEY_GESTURE_E, input_dev->keybit);
+ __set_bit(KEY_GESTURE_M, input_dev->keybit);
+ __set_bit(KEY_GESTURE_W, input_dev->keybit);
+ __set_bit(KEY_GESTURE_L, input_dev->keybit);
+ __set_bit(KEY_GESTURE_S, input_dev->keybit);
+ __set_bit(KEY_GESTURE_V, input_dev->keybit);
+ __set_bit(KEY_GESTURE_C, input_dev->keybit);
+ __set_bit(KEY_GESTURE_Z, input_dev->keybit);
+
+ fts_create_gesture_sysfs(ts_data->dev);
+
+ memset(&fts_gesture_data, 0, sizeof(struct fts_gesture_st));
+ ts_data->gesture_mode = FTS_GESTURE_EN;
+
+ fts_gesture_proc_init();
+
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+int fts_gesture_exit(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
+ sysfs_remove_group(&ts_data->dev->kobj, &fts_gesture_group);
+ FTS_FUNC_EXIT();
+ return 0;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
index fabedbf..f2e335c 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,191 +16,178 @@
*/
/************************************************************************
- *
- * File Name: focaltech_i2c.c
- *
- * Author: fupeipei
- *
- * Created: 2016-08-04
- *
- * Abstract: i2c communication with TP
- *
- * Version: v1.0
- *
- * Revision History:
- * v1.0:
- * First release. By fupeipei 2016-08-04
- ************************************************************************/
+*
+* File Name: focaltech_i2c.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-04
+*
+* Abstract: i2c communication with TP
+*
+* Version: v1.0
+*
+* Revision History:
+*
+************************************************************************/
/*****************************************************************************
- * Included header files
- *****************************************************************************/
+* Included header files
+*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define I2C_RETRY_NUMBER 3
+#define I2C_BUF_LENGTH 256
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-static DEFINE_MUTEX(i2c_rw_access);
+* Static variables
+*****************************************************************************/
/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
+* Global variable or extern global variabls/functions
+*****************************************************************************/
/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
+* Static function prototypes
+*****************************************************************************/
/*****************************************************************************
- * functions body
- *****************************************************************************/
-
-/************************************************************************
- * Name: fts_i2c_read
- * Brief: i2c read
- * Input: i2c info, write buf, write len, read buf, read len
- * Output: get data in the 3rd buf
- * Return: fail <0
- ***********************************************************************/
-int fts_i2c_read(struct i2c_client *client, char *writebuf,
- int writelen, char *readbuf, int readlen)
+* functions body
+*****************************************************************************/
+int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
{
- int ret = -EIO;
+ int ret = 0;
+ int i = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct i2c_msg msg_list[2];
+ struct i2c_msg *msg = NULL;
+ int msg_num = 0;
- mutex_lock(&i2c_rw_access);
+ /* must have data when read */
+ if (!ts_data || !ts_data->client || !data || !datalen
+ || (datalen >= I2C_BUF_LENGTH) || (cmdlen >= I2C_BUF_LENGTH)) {
+ FTS_ERROR("fts_data/client/cmdlen(%d)/data/datalen(%d) is invalid",
+ cmdlen, datalen);
+ return -EINVAL;
+ }
- if (readlen > 0) {
- if (writelen > 0) {
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = writelen,
- .buf = writebuf,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = readlen,
- .buf = readbuf,
- },
- };
- ret = i2c_transfer(client->adapter, msgs, 2);
- if (ret < 0)
- FTS_ERROR("[IIC]: i2c_write error %d!!", ret);
- } else {
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = readlen,
- .buf = readbuf,
- },
- };
- ret = i2c_transfer(client->adapter, msgs, 1);
- if (ret < 0)
- FTS_ERROR("[IIC]: i2c_read error %d!!", ret);
- }
- }
+ mutex_lock(&ts_data->bus_lock);
+ memset(&msg_list[0], 0, sizeof(struct i2c_msg));
+ memset(&msg_list[1], 0, sizeof(struct i2c_msg));
+ memcpy(ts_data->bus_tx_buf, cmd, cmdlen);
+ msg_list[0].addr = ts_data->client->addr;
+ msg_list[0].flags = 0;
+ msg_list[0].len = cmdlen;
+ msg_list[0].buf = ts_data->bus_tx_buf;
+ msg_list[1].addr = ts_data->client->addr;
+ msg_list[1].flags = I2C_M_RD;
+ msg_list[1].len = datalen;
+ msg_list[1].buf = ts_data->bus_rx_buf;
+ if (cmd && cmdlen) {
+ msg = &msg_list[0];
+ msg_num = 2;
+ } else {
+ msg = &msg_list[1];
+ msg_num = 1;
+ }
- mutex_unlock(&i2c_rw_access);
+ for (i = 0; i < I2C_RETRY_NUMBER; i++) {
+ ret = i2c_transfer(ts_data->client->adapter, msg, msg_num);
+ if (ret < 0) {
+ FTS_ERROR("i2c_transfer(read) fail,ret:%d", ret);
+ } else {
+ memcpy(data, ts_data->bus_rx_buf, datalen);
+ break;
+ }
+ }
- return ret;
+ mutex_unlock(&ts_data->bus_lock);
+ return ret;
}
-/************************************************************************
- * Name: fts_i2c_write
- * Brief: i2c write
- * Input: i2c info, write buf, write len
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-int fts_i2c_write(struct i2c_client *client, char *writebuf, int writelen)
+int fts_write(u8 *writebuf, u32 writelen)
{
- int ret = 0;
+ int ret = 0;
+ int i = 0;
+ struct fts_ts_data *ts_data = fts_data;
+ struct i2c_msg msgs;
- mutex_lock(&i2c_rw_access);
+ if (!ts_data || !ts_data->client || !writebuf || !writelen
+ || (writelen >= I2C_BUF_LENGTH)) {
+ FTS_ERROR("fts_data/client/data/datalen(%d) is invalid", writelen);
+ return -EINVAL;
+ }
- if (writelen > 0) {
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = writelen,
- .buf = writebuf,
- },
- };
- ret = i2c_transfer(client->adapter, msgs, 1);
- if (ret < 0)
- FTS_ERROR("[IIC]: i2c_write error, ret=%d", ret);
- }
-
- mutex_unlock(&i2c_rw_access);
-
- return ret;
+ mutex_lock(&ts_data->bus_lock);
+ memset(&msgs, 0, sizeof(struct i2c_msg));
+ memcpy(ts_data->bus_tx_buf, writebuf, writelen);
+ msgs.addr = ts_data->client->addr;
+ msgs.flags = 0;
+ msgs.len = writelen;
+ msgs.buf = ts_data->bus_tx_buf;
+ for (i = 0; i < I2C_RETRY_NUMBER; i++) {
+ ret = i2c_transfer(ts_data->client->adapter, &msgs, 1);
+ if (ret < 0) {
+ FTS_ERROR("i2c_transfer(write) fail,ret:%d", ret);
+ } else {
+ break;
+ }
+ }
+ mutex_unlock(&ts_data->bus_lock);
+ return ret;
}
-/************************************************************************
- * Name: fts_i2c_write_reg
- * Brief: write register
- * Input: i2c info, reg address, reg value
- * Output: no
- * Return: fail <0
- ***********************************************************************/
-int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue)
+int fts_read_reg(u8 addr, u8 *value)
{
- u8 buf[2] = {0};
-
- buf[0] = regaddr;
- buf[1] = regvalue;
- return fts_i2c_write(client, buf, sizeof(buf));
+ return fts_read(&addr, 1, value, 1);
}
-/************************************************************************
- * Name: fts_i2c_read_reg
- * Brief: read register
- * Input: i2c info, reg address, reg value
- * Output: get reg value
- * Return: fail <0
- ***********************************************************************/
-int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue)
+int fts_write_reg(u8 addr, u8 value)
{
- return fts_i2c_read(client, ®addr, 1, regvalue, 1);
+ u8 buf[2] = { 0 };
+
+ buf[0] = addr;
+ buf[1] = value;
+ return fts_write(buf, sizeof(buf));
}
-/************************************************************************
- * Name: fts_i2c_init
- * Brief: fts i2c init
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_i2c_init(void)
+int fts_bus_init(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
+ FTS_FUNC_ENTER();
+ ts_data->bus_tx_buf = kzalloc(I2C_BUF_LENGTH, GFP_KERNEL);
+ if (NULL == ts_data->bus_tx_buf) {
+ FTS_ERROR("failed to allocate memory for bus_tx_buf");
+ return -ENOMEM;
+ }
- FTS_FUNC_EXIT();
- return 0;
-}
-/************************************************************************
- * Name: fts_i2c_exit
- * Brief: fts i2c exit
- * Input:
- * Output:
- * Return:
- ***********************************************************************/
-int fts_i2c_exit(void)
-{
- FTS_FUNC_ENTER();
-
- FTS_FUNC_EXIT();
- return 0;
+ ts_data->bus_rx_buf = kzalloc(I2C_BUF_LENGTH, GFP_KERNEL);
+ if (NULL == ts_data->bus_rx_buf) {
+ FTS_ERROR("failed to allocate memory for bus_rx_buf");
+ return -ENOMEM;
+ }
+ FTS_FUNC_EXIT();
+ return 0;
}
+int fts_bus_exit(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
+ if (ts_data && ts_data->bus_tx_buf) {
+ kfree(ts_data->bus_tx_buf);
+ ts_data->bus_tx_buf = NULL;
+ }
+
+ if (ts_data && ts_data->bus_rx_buf) {
+ kfree(ts_data->bus_rx_buf);
+ ts_data->bus_rx_buf = NULL;
+ }
+ FTS_FUNC_EXIT();
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
index eca1c2b..1296af1 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
@@ -2,7 +2,7 @@
*
* FocalTech TouchScreen driver.
*
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -16,140 +16,120 @@
*/
/*****************************************************************************
- *
- * File Name: focaltech_point_report_check.c
- *
- * Author: WangTao
- *
- * Created: 2016-11-16
- *
- * Abstract: point report check function
- *
- * Version: v1.0
- *
- * Revision History:
- * v1.0:
- * First release. By WangTao 2016-11-16
- *****************************************************************************/
+*
+* File Name: focaltech_point_report_check.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-11-16
+*
+* Abstract: point report check function
+*
+* Version: v1.0
+*
+* Revision History:
+*
+*****************************************************************************/
/*****************************************************************************
- * Included header files
- *****************************************************************************/
+* Included header files
+*****************************************************************************/
#include "focaltech_core.h"
#if FTS_POINT_REPORT_CHECK_EN
/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-#define POINT_REPORT_CHECK_WAIT_TIME 200 /* ms */
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define POINT_REPORT_CHECK_WAIT_TIME 200 /* unit:ms */
/*****************************************************************************
- * Private enumerations, structures and unions using typedef
- *****************************************************************************/
-
+* functions body
+*****************************************************************************/
/*****************************************************************************
- * Static variables
- *****************************************************************************/
-static struct delayed_work fts_point_report_check_work;
-static struct workqueue_struct *fts_point_report_check_workqueue;
-
-/*****************************************************************************
- * Global variable or extern global variabls/functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Static function prototypes
- *****************************************************************************/
-
-/*****************************************************************************
- * functions body
- *****************************************************************************/
-
-
-/*****************************************************************************
- * Name: fts_point_report_check_func
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_point_report_check_func(struct work_struct *work)
+* Name: fts_prc_func
+* Brief: fts point report check work func, report whole up of points
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+static void fts_prc_func(struct work_struct *work)
{
-
+ struct fts_ts_data *ts_data = container_of(work,
+ struct fts_ts_data, prc_work.work);
+ struct input_dev *input_dev = ts_data->input_dev;
#if FTS_MT_PROTOCOL_B_EN
- unsigned int finger_count = 0;
+ u32 finger_count = 0;
+ u32 max_touches = fts_data->pdata->max_touch_number;
#endif
- FTS_FUNC_ENTER();
- mutex_lock(&fts_wq_data->report_mutex);
+ FTS_FUNC_ENTER();
+ mutex_lock(&ts_data->report_mutex);
#if FTS_MT_PROTOCOL_B_EN
- for (finger_count = 0;
- finger_count < fts_wq_data->pdata->max_touch_number;
- finger_count++) {
- input_mt_slot(fts_input_dev, finger_count);
- input_mt_report_slot_state(fts_input_dev,
- MT_TOOL_FINGER, false);
- }
+ for (finger_count = 0; finger_count < max_touches; finger_count++) {
+ input_mt_slot(input_dev, finger_count);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+ }
#else
- input_mt_sync(fts_input_dev);
+ input_mt_sync(input_dev);
#endif
- input_report_key(fts_input_dev, BTN_TOUCH, 0);
- input_sync(fts_input_dev);
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_sync(input_dev);
- mutex_unlock(&fts_wq_data->report_mutex);
+ mutex_unlock(&ts_data->report_mutex);
- FTS_FUNC_EXIT();
-}
-
-void fts_point_report_check_queue_work(void)
-{
- cancel_delayed_work(&fts_point_report_check_work);
- queue_delayed_work(fts_point_report_check_workqueue,
- &fts_point_report_check_work,
- msecs_to_jiffies(POINT_REPORT_CHECK_WAIT_TIME));
+ FTS_FUNC_EXIT();
}
/*****************************************************************************
- * Name: fts_point_report_check_init
- * Brief:
- * Input:
- * Output:
- * Return: < 0: Fail to create esd check queue
- *****************************************************************************/
-int fts_point_report_check_init(void)
+* Name: fts_prc_queue_work
+* Brief: fts point report check queue work, call it when interrupt comes
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+void fts_prc_queue_work(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
-
- INIT_DELAYED_WORK(&fts_point_report_check_work,
- fts_point_report_check_func);
- fts_point_report_check_workqueue =
- create_workqueue("fts_point_report_check_func_wq");
- if (fts_point_report_check_workqueue == NULL)
- FTS_ERROR("[POINT_REPORT]: Failed to create workqueue!!");
- else
- FTS_DEBUG("[POINT_REPORT]: Success to create workqueue!!");
-
- FTS_FUNC_EXIT();
-
- return 0;
+ cancel_delayed_work_sync(&ts_data->prc_work);
+ queue_delayed_work(ts_data->ts_workqueue, &ts_data->prc_work,
+ msecs_to_jiffies(POINT_REPORT_CHECK_WAIT_TIME));
}
/*****************************************************************************
- * Name: fts_point_report_check_exit
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-int fts_point_report_check_exit(void)
+* Name: fts_point_report_check_init
+* Brief:
+* Input:
+* Output:
+* Return: < 0: Fail to create esd check queue
+*****************************************************************************/
+int fts_point_report_check_init(struct fts_ts_data *ts_data)
{
- FTS_FUNC_ENTER();
+ FTS_FUNC_ENTER();
- destroy_workqueue(fts_point_report_check_workqueue);
+ if (ts_data->ts_workqueue) {
+ INIT_DELAYED_WORK(&ts_data->prc_work, fts_prc_func);
+ } else {
+ FTS_ERROR("fts workqueue is NULL, can't run point report check function");
+ return -EINVAL;
+ }
- FTS_FUNC_EXIT();
- return 0;
+ FTS_FUNC_EXIT();
+ return 0;
+}
+
+/*****************************************************************************
+* Name: fts_point_report_check_exit
+* Brief:
+* Input:
+* Output:
+* Return:
+*****************************************************************************/
+int fts_point_report_check_exit(struct fts_ts_data *ts_data)
+{
+ FTS_FUNC_ENTER();
+
+ FTS_FUNC_EXIT();
+ return 0;
}
#endif /* FTS_POINT_REPORT_CHECK_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c b/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c
deleted file mode 100644
index e8e86b5..0000000
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- *
- * FocalTech TouchScreen driver.
- *
- * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
- *
- * 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.
- *
- */
-
-/*****************************************************************************
- *
- * File Name: focaltech_esdcheck.c
- *
- * Author: Focaltech Driver Team
- *
- * Created: 2016-08-03
- *
- * Abstract: Sensor
- *
- * Version: v1.0
- *
- * Revision History:
- * v1.0:
- * First release. By luougojin 2016-08-03
- *****************************************************************************/
-
-/*****************************************************************************
- * Included header files
- *****************************************************************************/
-#include "focaltech_core.h"
-
-#if FTS_PSENSOR_EN
-/*****************************************************************************
- * Private constant and macro definitions using #define
- *****************************************************************************/
-/* psensor register address*/
-#define FTS_REG_PSENSOR_ENABLE 0xB0
-#define FTS_REG_PSENSOR_STATUS 0x01
-
-/* psensor register bits*/
-#define FTS_PSENSOR_ENABLE_MASK 0x01
-#define FTS_PSENSOR_STATUS_NEAR 0xC0
-#define FTS_PSENSOR_STATUS_FAR 0xE0
-#define FTS_PSENSOR_FAR_TO_NEAR 0
-#define FTS_PSENSOR_NEAR_TO_FAR 1
-#define FTS_PSENSOR_ORIGINAL_STATE_FAR 1
-#define FTS_PSENSOR_WAKEUP_TIMEOUT 500
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-static struct sensors_classdev __maybe_unused sensors_proximity_cdev = {
-
- .name = "fts-proximity",
- .vendor = "FocalTech",
- .version = 1,
- .handle = SENSORS_PROXIMITY_HANDLE,
- .type = SENSOR_TYPE_PROXIMITY,
- .max_range = "5.0",
- .resolution = "5.0",
- .sensor_power = "0.1",
- .min_delay = 0,
- .fifo_reserved_event_count = 0,
- .fifo_max_event_count = 0,
- .enabled = 0,
- .delay_msec = 200,
- .sensors_enable = NULL,
- .sensors_poll_delay = NULL,
-};
-
-/*****************************************************************************
- * functions body
- *****************************************************************************/
-/*****************************************************************************
- * Name: fts_psensor_support_enabled
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static inline bool fts_psensor_support_enabled(void)
-{
- /*return config_enabled(CONFIG_TOUCHSCREEN_FTS_PSENSOR);*/
- return FTS_PSENSOR_EN;
-}
-
-/*****************************************************************************
- * Name: fts_psensor_enable
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static void fts_psensor_enable(struct fts_ts_data *data, int enable)
-{
- u8 state;
- int ret = -1;
-
- if (data->client == NULL)
- return;
-
- fts_i2c_read_reg(data->client, FTS_REG_PSENSOR_ENABLE, &state);
- if (enable)
- state |= FTS_PSENSOR_ENABLE_MASK;
- else
- state &= ~FTS_PSENSOR_ENABLE_MASK;
-
- ret = fts_i2c_write_reg(data->client, FTS_REG_PSENSOR_ENABLE, state);
- if (ret < 0)
- FTS_ERROR("write psensor switch command failed");
-
-}
-
-/*****************************************************************************
- * Name: fts_psensor_enable_set
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_psensor_enable_set(struct sensors_classdev *sensors_cdev,
- unsigned int enable)
-{
- struct fts_psensor_platform_data *psensor_pdata =
- container_of(sensors_cdev,
- struct fts_psensor_platform_data, ps_cdev);
- struct fts_ts_data *data = psensor_pdata->data;
- struct input_dev *input_dev = data->psensor_pdata->input_psensor_dev;
-
- mutex_lock(&input_dev->mutex);
- fts_psensor_enable(data, enable);
- psensor_pdata->tp_psensor_data = FTS_PSENSOR_ORIGINAL_STATE_FAR;
- if (enable)
- psensor_pdata->tp_psensor_opened = 1;
- else
- psensor_pdata->tp_psensor_opened = 0;
-
- mutex_unlock(&input_dev->mutex);
-
- return enable;
-}
-
-/*****************************************************************************
- * Name: fts_read_tp_psensor_data
- * Brief:
- * Input:
- * Output:
- * Return:
- *****************************************************************************/
-static int fts_read_tp_psensor_data(struct fts_ts_data *data)
-{
- u8 psensor_status;
- char tmp;
- int ret = 1;
-
- fts_i2c_read_reg(data->client,
- FTS_REG_PSENSOR_STATUS, &psensor_status);
-
- tmp = data->psensor_pdata->tp_psensor_data;
- if (psensor_status == FTS_PSENSOR_STATUS_NEAR)
- data->psensor_pdata->tp_psensor_data =
- FTS_PSENSOR_FAR_TO_NEAR;
- else if (psensor_status == FTS_PSENSOR_STATUS_FAR)
- data->psensor_pdata->tp_psensor_data =
- FTS_PSENSOR_NEAR_TO_FAR;
-
- if (tmp != data->psensor_pdata->tp_psensor_data) {
- FTS_ERROR("%s sensor data changed", __func__);
- ret = 0;
- }
-
- return ret;
-}
-
-
-int fts_sensor_read_data(struct fts_ts_data *data)
-{
- int ret = 0;
-
- if (fts_psensor_support_enabled()
- && data->psensor_pdata->tp_psensor_opened) {
- ret = fts_read_tp_psensor_data(data);
- if (!ret) {
- if (data->suspended)
- pm_wakeup_event(&data->client->dev,
- FTS_PSENSOR_WAKEUP_TIMEOUT);
-
- input_report_abs(data->psensor_pdata->input_psensor_dev,
- ABS_DISTANCE,
- data->psensor_pdata->tp_psensor_data);
- input_sync(data->psensor_pdata->input_psensor_dev);
- }
-
- return 1;
- }
-
- return 0;
-}
-
-int fts_sensor_suspend(struct fts_ts_data *data)
-{
- int ret = 0;
-
- if (fts_psensor_support_enabled() &&
- device_may_wakeup(&data->client->dev) &&
- data->psensor_pdata->tp_psensor_opened) {
- ret = enable_irq_wake(data->client->irq);
- if (ret != 0)
- FTS_ERROR("%s: set_irq_wake failed", __func__);
-
- data->suspended = true;
- return 1;
- }
-
- return 0;
-}
-
-
-int fts_sensor_resume(struct fts_ts_data *data)
-{
- int ret = 0;
-
- if (fts_psensor_support_enabled()
- && device_may_wakeup(&data->client->dev)
- && data->psensor_pdata->tp_psensor_opened) {
- ret = disable_irq_wake(data->client->irq);
- if (ret)
- FTS_ERROR("%s: disable_irq_wake failed", __func__);
-
- data->suspended = false;
- return 1;
- }
-
- return 0;
-}
-
-
-int fts_sensor_init(struct fts_ts_data *data)
-{
- struct fts_psensor_platform_data *psensor_pdata;
- struct input_dev *psensor_input_dev;
- int err;
-
- if (fts_psensor_support_enabled()) {
- device_init_wakeup(&data->client->dev, 1);
- psensor_pdata = devm_kzalloc(&data->client->dev,
- sizeof(struct fts_psensor_platform_data),
- GFP_KERNEL);
- if (!psensor_pdata) {
- FTS_ERROR("Failed to allocate memory");
- goto irq_free;
- }
-
- data->psensor_pdata = psensor_pdata;
-
- psensor_input_dev = input_allocate_device();
- if (!psensor_input_dev) {
- FTS_ERROR("Failed to allocate device");
- goto free_psensor_pdata;
- }
-
- __set_bit(EV_ABS, psensor_input_dev->evbit);
- input_set_abs_params(psensor_input_dev, ABS_DISTANCE,
- 0, 1, 0, 0);
- psensor_input_dev->name = "proximity";
- psensor_input_dev->id.bustype = BUS_I2C;
- psensor_input_dev->dev.parent = &data->client->dev;
- data->psensor_pdata->input_psensor_dev = psensor_input_dev;
-
- err = input_register_device(psensor_input_dev);
- if (err) {
- FTS_ERROR("Unable to register device, err=%d", err);
- goto free_psensor_input_dev;
- }
-
- psensor_pdata->ps_cdev = sensors_proximity_cdev;
- psensor_pdata->ps_cdev.sensors_enable = fts_psensor_enable_set;
- psensor_pdata->data = data;
-
- err = sensors_classdev_register(&data->client->dev,
- &psensor_pdata->ps_cdev);
- if (err)
- goto unregister_psensor_input_device;
- }
-
- return 0;
-
-unregister_psensor_input_device:
- if (fts_psensor_support_enabled())
- input_unregister_device(data->psensor_pdata->input_psensor_dev);
-free_psensor_input_dev:
- if (fts_psensor_support_enabled())
- input_free_device(data->psensor_pdata->input_psensor_dev);
-free_psensor_pdata:
- if (fts_psensor_support_enabled()) {
- devm_kfree(&data->client->dev, psensor_pdata);
- data->psensor_pdata = NULL;
- }
-irq_free:
- if (fts_psensor_support_enabled())
- device_init_wakeup(&data->client->dev, 0);
- free_irq(data->client->irq, data);
-
- return 1;
-}
-
-int fts_sensor_remove(struct fts_ts_data *data)
-{
- if (fts_psensor_support_enabled()) {
- device_init_wakeup(&data->client->dev, 0);
- sensors_classdev_unregister(&data->psensor_pdata->ps_cdev);
- input_unregister_device(data->psensor_pdata->input_psensor_dev);
- devm_kfree(&data->client->dev, data->psensor_pdata);
- data->psensor_pdata = NULL;
- }
- return 0;
-}
-#endif /* FTS_PSENSOR_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/include/firmware/FT3518_Ref_firmware.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/FT3518_Ref_firmware.i
new file mode 100644
index 0000000..4725ad1
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/firmware/FT3518_Ref_firmware.i
@@ -0,0 +1,3350 @@
+0x2, 0x28,0x73,0x2, 0xc0,0xf4,0xe4,0x2, 0x19,0xdd,0x22,0x2, 0x0, 0x4a,0xb4,0x2,
+0x4, 0xa9,0xb7,0xea,0x22,0x24,0xff,0xa9,0x97,0xea,0x22,0x2, 0xc0,0xc8,0x12,0x18,
+0x6b,0x2, 0x1c,0x7b,0x22,0xeb,0xaa,0x8, 0xb2,0x86,0x22,0x2, 0x7b,0x95,0x7f,0x60,
+0xa9,0xc2,0xea,0x74,0x1, 0x12,0x1d,0x58,0x7f,0x6, 0x12,0xd, 0x0, 0x7f,0x6, 0x2,
+0x13,0xbe,0x22,0x2, 0x7c,0x46,0xb2,0x82,0x22,0x22,0x32,0x2, 0xf, 0xfe,0x1, 0x2,
+0x4, 0x8, 0x10,0x20,0x40,0x80,0xf5,0xfd,0xe5,0xfe,0x22,0x2, 0x19,0x28,0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x74,0x1, 0x7a,0xb3,0x3f,0x25,0x22,0x2, 0xf, 0xff,0xd2,0x4,
+0x2, 0x3f,0x15,0x2, 0x1a,0xe1,0xca,0xf8,0x7c,0xfb,0x7e,0x34,0x0, 0x1, 0x7e,0xf,
+0x40,0x14,0x79,0x30,0x0, 0x10,0xc2,0x19,0xe4,0x7a,0xb3,0x40,0xb, 0x5e,0xf0,0x3,
+0x74,0x3, 0x12,0x1c,0xfb,0x74,0x1, 0x12,0x19,0xdd,0xa, 0x2f,0x5e,0x24,0x0, 0x3,
+0x3e,0x24,0x7e,0xf, 0x3f,0xbe,0xb, 0xa, 0x30,0x5e,0x70,0xf9,0x4d,0x32,0x1b,0xa,
+0x30,0x7e,0xf, 0x3f,0xbe,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, 0x30,0x7e,0xf,
+0x3f,0xbe,0xb, 0xa, 0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0x2e,0x14,0x0, 0x9e,0xb,
+0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x74,0x1, 0x12,0x1c,0xfb,0x7e,0xf, 0x40,
+0x14,0xb, 0xa, 0x30,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xa9,0xd3,0xcd,0x7e,0xf, 0x40,
+0x14,0xb, 0x15,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, 0x30,0xda,0xf8,0x22,0x22,
+0xd1,0x60,0x2e,0x9f,0xde,0x68,0x21,0x97,0xb0,0xd9,0x4f,0x26,0x60,0x9f,0x9, 0xf6,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xdf,0x48,0xee,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xbe,0x8, 0x0, 0x0, 0x78,0x2, 0x61,0x94,0xbe,0xb0,0x3, 0x40,0x2, 0x61,0x94,0x60,
+0x2, 0x41,0x2, 0xb, 0xa, 0x30,0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x46,0x69,0x30,
+0x0, 0x2, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x40,0x29,0x70,0x0, 0x4, 0xa, 0x27,
+0x5e,0x24,0x0, 0x3, 0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x4c,0xb, 0x2a,0x30,0x5e,
+0x70,0xfc,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0x5, 0xa, 0x27,0x5e,0x24,0x0,
+0x7f,0x7c,0x45,0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x12,0xb, 0x2a,0x30,
+0x5e,0x60,0x80,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0xe, 0xa, 0x27,0x7c,0x45,
+0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x16,0xb, 0x2a,0x30,0x6c,0x66,0x4d,
+0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0xf, 0xa, 0x27,0x7c,0x45,0x6c,0x55,0x7e,0x2f,
+0x3f,0xc6,0x2e,0x54,0x0, 0x22,0xb, 0x2a,0x30,0x6c,0x66,0x4d,0x32,0x1b,0x2a,0x30,
+0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x50,0x69,0x30,0x0, 0x8,
+0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x56,0x69,0x30,0x0, 0xa, 0x7e,0x2f,0x3f,0xc6,
+0x79,0x32,0x0, 0x5c,0x69,0x30,0x0, 0xc, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x62,
+0x61,0x5c,0xb4,0x1, 0x2, 0x80,0x2, 0x41,0xc8,0xb, 0xa, 0x30,0x7e,0x2f,0x3f,0xc6,
+0x79,0x32,0x0, 0x48,0x69,0x30,0x0, 0x2, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x42,
+0x29,0x70,0x0, 0x4, 0xa, 0x27,0x5e,0x24,0x0, 0x3, 0x3e,0x24,0x3e,0x24,0x7e,0x2f,
+0x3f,0xc6,0x2e,0x54,0x0, 0x4c,0xb, 0x2a,0x30,0x5e,0x70,0xf3,0x4d,0x32,0x1b,0x2a,
+0x30,0x29,0x70,0x0, 0x5, 0xa, 0x27,0x5e,0x24,0x0, 0x7f,0x7e,0x2f,0x3f,0xc6,0x2e,
+0x54,0x0, 0x4e,0xb, 0x2a,0x30,0x5e,0x70,0x80,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,
+0x0, 0xe, 0xa, 0x27,0x7c,0x45,0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x16,
+0xb, 0x2a,0x30,0x6c,0x66,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0xf, 0xa, 0x27,
+0x7c,0x45,0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x22,0xb, 0x2a,0x30,0x6c,
+0x66,0x4d,0x32,0x1b,0x2a,0x30,0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,
+0x0, 0x52,0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x58,0x69,0x30,
+0x0, 0xa, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x5e,0x69,0x30,0x0, 0xc, 0x7e,0x2f,
+0x3f,0xc6,0x79,0x32,0x0, 0x64,0x61,0x5c,0xb4,0x2, 0x2, 0x80,0x2, 0x61,0x5c,0xb,
+0xa, 0x30,0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x4a,0x69,0x30,0x0, 0x2, 0x7e,0x2f,
+0x3f,0xc6,0x79,0x32,0x0, 0x44,0x29,0x70,0x0, 0x4, 0xa, 0x27,0x5e,0x24,0x0, 0x3,
+0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x4c,
+0xb, 0x2a,0x30,0x5e,0x70,0xcf,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0x5, 0xa,
+0x27,0x5e,0x24,0x0, 0x7f,0x7c,0x45,0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0,
+0x4e,0xb, 0x2a,0x30,0x5e,0x60,0x80,0x4d,0x32,0x1b,0x2a,0x30,0x69,0x30,0x0, 0x6,
+0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x54,0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x3f,0xc6,
+0x79,0x32,0x0, 0x5a,0x69,0x30,0x0, 0xa, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x60,
+0x69,0x30,0x0, 0xc, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x66,0x29,0x70,0x0, 0xe,
+0xa, 0x27,0x7c,0x45,0x6c,0x55,0x7e,0x2f,0x3f,0xc6,0x2e,0x54,0x0, 0x16,0xb, 0x2a,
+0x30,0x6c,0x66,0x4d,0x32,0x1b,0x2a,0x30,0x29,0x70,0x0, 0xf, 0xa, 0x27,0x7c,0x45,
+0x6c,0x55,0x7e,0xf, 0x3f,0xc6,0x2e,0x14,0x0, 0x22,0xb, 0xa, 0x30,0x6c,0x66,0x4d,
+0x32,0x1b,0xa, 0x30,0x22,0xca,0x79,0x7f,0x70,0x74,0x1, 0x12,0x1d,0x89,0x29,0xe7,
+0x1, 0xf, 0x29,0x77,0x0, 0xb5,0x29,0x27,0x0, 0xb6,0x29,0x67,0x1, 0x10,0x7a,0x63,
+0x3f,0xcf,0x29,0x67,0x1, 0x12,0x7a,0x63,0x3f,0xdd,0x29,0x67,0x1, 0x11,0x7a,0x63,
+0x3f,0xd0,0xbe,0x70,0x3, 0x38,0x2, 0x61,0xcb,0x6c,0x77,0xbe,0x20,0x40,0x38,0x2,
+0x61,0xd5,0x7e,0x20,0x40,0xa, 0xe, 0x7e,0x6f,0x3f,0xc6,0x79,0x6, 0x0, 0xa, 0xa,
+0x7, 0x9, 0xf0,0x3f,0xca,0xa, 0x42,0x5e,0x44,0x0, 0x7f,0x7e,0x1f,0x3f,0xc6,0x2e,
+0x34,0x0, 0x12,0xb, 0x1a,0x0, 0x5e,0x10,0x80,0x4d,0x4, 0x1b,0x1a,0x0, 0x7c,0x7e,
+0xac,0x7f,0xa, 0x22,0x12,0x26,0xc7,0x7c,0xb7,0xa, 0xb, 0x7e,0x1f,0x3f,0xc6,0x79,
+0x1, 0x0, 0x14,0xa, 0x2f,0xa, 0x32,0x12,0x26,0xc7,0x7d,0x43,0x29,0xb7,0x0, 0xb7,
+0x70,0x2, 0x81,0x7c,0x7c,0x7e,0xac,0x7f,0x29,0x37,0x1, 0x10,0xa, 0x23,0xad,0x32,
+0xa, 0x22,0x8d,0x32,0x7d,0x3, 0x7c,0x7e,0xac,0x7f,0xa, 0x22,0x12,0x26,0xc7,0x7c,
+0xa7,0x7c,0x21,0x2c,0xa2,0xbe,0xa0,0xd, 0x40,0x2, 0x81,0x4f,0x7e,0xa0,0xd, 0x7e,
+0x30,0xc, 0xa, 0x2a,0x9e,0x24,0x0, 0xd, 0x2e,0x24,0x0, 0xc, 0x6c,0x44,0x7e,0x6f,
+0x3f,0xc6,0x2e,0xd4,0x0, 0x22,0xb, 0x6a,0x30,0x6c,0x77,0x4d,0x32,0x1b,0x6a,0x30,
+0xa, 0x2a,0x9e,0x24,0x0, 0xd, 0x2e,0x24,0x0, 0x18,0x81,0xb2,0x29,0x77,0x1, 0x12,
+0xa, 0x57,0x2e,0x54,0x0, 0xd, 0x7c,0xab,0x6c,0x33,0xa, 0x2a,0x9e,0x24,0x0, 0xd,
+0x2e,0x24,0x0, 0xc, 0x6c,0x44,0x7e,0x6f,0x3f,0xc6,0x2e,0xd4,0x0, 0x22,0xb, 0x6a,
+0x30,0x6c,0x77,0x4d,0x32,0x1b,0x6a,0x30,0xa, 0x2a,0x9e,0x24,0x0, 0xd, 0x2e,0x24,
+0x0, 0xc, 0x6c,0x44,0x7e,0x6f,0x3f,0xc6,0x2e,0xd4,0x0, 0x16,0xb, 0x6a,0x30,0x6c,
+0x77,0x4d,0x32,0x1b,0x6a,0x30,0xa, 0x3a,0xad,0x34,0x7d,0x23,0xb, 0x24,0xbe,0x24,
+0x2, 0x0, 0x50,0x2, 0x81,0xda,0x7e,0x24,0x1, 0xff,0x1e,0x24,0x6c,0x44,0x7e,0x6f,
+0x3f,0xc6,0x2e,0xd4,0x0, 0xc, 0xb, 0x6a,0x30,0x6c,0x77,0x4d,0x32,0x1b,0x6a,0x30,
+0x29,0x27,0x1, 0x11,0x7e,0x10,0x2, 0xac,0x12,0xa, 0x33,0xad,0x34,0x2d,0x30,0x29,
+0x27,0x1, 0x14,0xa, 0x22,0xb, 0x24,0x3e,0x24,0x2d,0x23,0x69,0x37,0x1, 0x15,0xbe,
+0x34,0x0, 0x0, 0x38,0x2, 0xa1,0x19,0xb, 0x25,0xb, 0x24,0xbe,0x24,0x2, 0x0, 0x50,
+0x2, 0xa1,0x27,0x7e,0x24,0x1, 0xff,0x1e,0x24,0x7c,0x45,0x6c,0x55,0x7e,0x7f,0x3f,
+0xc6,0x2e,0xf4,0x0, 0xc, 0xb, 0x7a,0x30,0x6c,0x66,0x4d,0x32,0x1b,0x7a,0x30,0xda,
+0x79,0x22,0xca,0x3b,0x7c,0x57,0x7c,0x4b,0xbe,0x40,0x3, 0x40,0x2, 0x6c,0x44,0x69,
+0x30,0x0, 0x4, 0x5e,0x60,0xf, 0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xd0,0x0,
+0xe, 0x69,0xc0,0x0, 0xc, 0x2d,0xd4,0x29,0xb6,0x0, 0x1, 0xa, 0xfb,0x7d,0x4f,0x7c,
+0x89,0x6c,0x99,0x7d,0xf4,0x7e,0x6b,0xb0,0xa, 0x4b,0x4d,0x4f,0x7e,0xd0,0x34,0xac,
+0xd5,0x7e,0xf0,0x2, 0xac,0xfa,0x7d,0xf7,0x2d,0xf6,0xa, 0xc4,0x7e,0xd4,0x1, 0x38,
+0xad,0xdc,0x2d,0xdf,0x7e,0x7f,0x40,0x10,0x2d,0xfd,0x79,0x47,0x0, 0x10,0xb, 0xa0,
+0xbe,0xa0,0x6, 0x78,0xb3,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xd0,0x0, 0xa,
+0x69,0xc0,0x0, 0x8, 0x2d,0xd4,0x29,0xb6,0x0, 0x1, 0xa, 0xfb,0x7d,0x4f,0x7c,0x89,
+0x6c,0x99,0x7d,0xf4,0x7e,0x6b,0xb0,0xa, 0x4b,0x4d,0x4f,0x7e,0xd0,0x34,0xac,0xd5,
+0x7e,0xf0,0x2, 0xac,0xfa,0x7d,0xf7,0x2d,0xf6,0xa, 0xc4,0x7e,0xd4,0x1, 0x38,0xad,
+0xdc,0x2d,0xdf,0x7e,0x7f,0x40,0x10,0x2d,0xfd,0x79,0x47,0x0, 0x1c,0xb, 0xa0,0xbe,
+0xa0,0xc, 0x78,0xb3,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xf0,0x0, 0x2, 0xb,
+0xa, 0xe0,0x2d,0xf4,0xb, 0x7a,0x40,0x7e,0xd0,0x34,0xac,0xd5,0x7e,0xf0,0x2, 0xac,
+0xfa,0x7d,0xf7,0x2d,0xf6,0xa, 0xc4,0x7e,0xd4,0x1, 0x38,0xad,0xdc,0x2d,0xdf,0x7e,
+0x7f,0x40,0x10,0x2d,0xfd,0x1b,0x7a,0x40,0xb, 0xa0,0xbe,0xa0,0x5, 0x40,0xc7,0x6d,
+0x44,0xa, 0xe4,0x7e,0xf4,0x1, 0x38,0xad,0xfe,0x74,0x34,0xac,0xb5,0x2d,0x5f,0x7e,
+0x7f,0x40,0x10,0x2d,0xf5,0x79,0x47,0x0, 0xa, 0xa, 0xe4,0x7e,0xf4,0x1, 0x38,0xad,
+0xfe,0x74,0x34,0xac,0xb5,0x2d,0xf5,0x7e,0x2f,0x40,0x10,0x2d,0x5f,0x79,0x32,0x0,
+0xc, 0x69,0x30,0x0, 0x6, 0xa, 0x4, 0x7e,0x14,0x1, 0x38,0xad,0x10,0x74,0x34,0xac,
+0x5b,0x2d,0x21,0x7e,0xf, 0x40,0x10,0x2d,0x12,0x79,0x30,0x0, 0xe, 0xda,0x3b,0x22,
+0xca,0x79,0x7e,0x6f,0x3f,0xc6,0x69,0x26,0x0, 0xa, 0x69,0x6, 0x0, 0x2, 0x1e,0x4,
+0x1e,0x4, 0x1e,0x4, 0x1e,0x4, 0x1e,0x4, 0x1e,0x4, 0x1e,0x4, 0x5e,0x4, 0x0, 0x3,
+0x9, 0x0, 0x3f,0xca,0x69,0x76,0x0, 0x12,0x5e,0x74,0x0, 0x7f,0x69,0x36,0x0, 0x14,
+0x69,0xa6,0x0, 0xc, 0x7d,0xba,0x5e,0xb4,0x0, 0xff,0x3e,0xb4,0x7d,0x4a,0xa, 0x48,
+0x3e,0x44,0x69,0x56,0x0, 0x16,0x7c,0x1b,0x69,0x56,0x0, 0x22,0x7c,0xab,0xac,0x50,
+0xac,0x7f,0xbd,0x32,0x78,0x2, 0xc1,0xde,0x7e,0x34,0x0, 0x81,0xe1,0xa5,0xa, 0x20,
+0xa, 0x3f,0x12,0x26,0xc7,0x4d,0x22,0x78,0x2, 0xc1,0xf1,0x7e,0x34,0x0, 0x82,0xe1,
+0xa5,0xa, 0xf0,0xad,0xfb,0xa, 0x2f,0x7d,0x3f,0x8d,0x32,0xbe,0x70,0xd, 0x40,0x2,
+0xe1,0x8, 0x7e,0x34,0x0, 0x83,0xe1,0xa5,0x7c,0x57,0xac,0x5f,0xbd,0x2f,0x78,0x2,
+0xe1,0x18,0x7e,0x34,0x0, 0x84,0xe1,0xa5,0x7e,0x50,0xc, 0xac,0x5f,0xa, 0xe0,0x7d,
+0xf2,0x8d,0xfe,0x7d,0x2f,0x69,0xf6,0x0, 0x2a,0x7d,0xef,0x1e,0xe4,0x1e,0xe4,0x1e,
+0xe4,0x1e,0xe4,0x1e,0xe4,0x1e,0xe4,0x5e,0xe4,0x3, 0xff,0xbe,0xe4,0x0, 0x0, 0x38,
+0x2, 0xe1,0x49,0x7e,0x14,0x0, 0x2, 0xe1,0x4b,0x6d,0x11,0x5e,0xf4,0x0, 0x3f,0xb,
+0xf4,0x3e,0xf4,0x2d,0x21,0x2d,0x2f,0xbd,0x24,0x78,0x2, 0xe1,0x63,0x7e,0x34,0x0,
+0x85,0xe1,0xa5,0x7e,0xb3,0x3f,0xbc,0x70,0x2, 0xe1,0x7f,0xa, 0x47,0x2e,0x44,0x0,
+0xb, 0xa, 0x21,0xbd,0x24,0x78,0x2, 0xe1,0x91,0x7e,0x34,0x0, 0x86,0xe1,0xa5,0xa,
+0x27,0x1b,0x24,0xa, 0x1, 0xbd,0x2, 0x78,0x2, 0xe1,0x91,0x7e,0x34,0x0, 0x87,0xe1,
+0xa5,0xa, 0x37,0x1b,0x34,0xa, 0xa, 0xbd,0x3, 0x78,0x2, 0xe1,0xa3,0x7e,0x34,0x0,
+0x88,0xe1,0xa5,0x6d,0x33,0xda,0x79,0x22,0x7f,0x10,0xa9,0xd6,0xcb,0x69,0x11,0x0,
+0x2, 0x7e,0x2f,0x40,0x3b,0x79,0x12,0x0, 0x4, 0x69,0x11,0x0, 0x4, 0x7e,0x2f,0x40,
+0x3b,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x6, 0x7e,0x2f,0x40,0x3b,0x79,0x12,0x0,
+0x8, 0x7e,0x1b,0x30,0xa, 0x3, 0x7e,0x14,0x1, 0x0, 0xad,0x10,0x29,0x71,0x0, 0x1,
+0xa, 0x37,0x2d,0x31,0x7e,0xf, 0x40,0x3b,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,
+0x40,0x3b,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0x60,0x12,0x19,0x84,0xa9,0xc6,0xcb,0x22,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x29,0x70,0x0, 0xa6,0x29,0x90,0x0, 0xa8,0x29,0x60,0x0, 0xa7,0x29,0x80,0x0, 0x9d,
+0xbe,0x80,0x4, 0x28,0x2, 0xa1,0x1b,0x6c,0xaa,0xa1,0x42,0xbe,0x80,0x8, 0x28,0x2,
+0xa1,0x27,0x7e,0xa0,0x1, 0xa1,0x42,0xbe,0x80,0x10,0x28,0x2, 0xa1,0x33,0x7e,0xa0,
+0x2, 0xa1,0x42,0xbe,0x80,0x20,0x28,0x2, 0xa1,0x3f,0x7e,0xa0,0x3, 0xa1,0x42,0x7e,
+0xa0,0x4, 0xbe,0x90,0x3, 0x38,0x2, 0xa1,0x4c,0x7e,0x90,0x3, 0xbe,0x80,0x3f,0x38,
+0x2, 0xa1,0x56,0x7e,0x80,0x3f,0xbe,0x60,0x1, 0x38,0x2, 0xa1,0x60,0x7e,0x60,0x1,
+0xbe,0x70,0x2, 0x38,0x2, 0xa1,0x69,0x6c,0x77,0xa, 0x28,0x3e,0x24,0x3e,0x24,0x3e,
+0x24,0x3e,0x24,0x3e,0x24,0x7c,0x89,0x6c,0x99,0x3e,0x44,0x3e,0x44,0x3e,0x44,0x2d,
+0x42,0xa, 0x26,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d,0x24,0xa, 0x37,0x3e,
+0x34,0x3e,0x34,0x2d,0x32,0x7e,0x7f,0x40,0x14,0x79,0x37,0x0, 0x2, 0x29,0xb0,0x0,
+0x9c,0x7c,0x4b,0x6c,0x55,0x29,0xb0,0x0, 0x9b,0xa, 0x3b,0x2d,0x32,0x7e,0x7f,0x3f,
+0xbe,0x79,0x37,0x0, 0x9a,0x69,0x30,0x0, 0xb2,0x7e,0x7f,0x40,0x14,0x79,0x37,0x0,
+0xc, 0x69,0x20,0x0, 0xb0,0x7d,0x32,0x7e,0x7f,0x40,0x14,0x79,0x37,0x0, 0xe, 0x69,
+0x30,0x0, 0xae,0x5e,0x34,0xe0,0xf, 0x29,0xb0,0x0, 0x9c,0xa, 0x2b,0x1b,0x24,0x3e,
+0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d,0x32,0x7e,0x7f,0x3f,0xbe,0x79,0x37,0x0,
+0x9c,0xa, 0x2a,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x29,0xb0,0x0, 0xa9,0xa,
+0x3b,0x2d,0x32,0x7e,0x7f,0x40,0x14,0x79,0x37,0x0, 0x6, 0x69,0x30,0x0, 0xac,0x7e,
+0x7f,0x40,0x14,0x79,0x37,0x0, 0x8, 0x69,0x30,0x0, 0xaa,0x7e,0xf, 0x40,0x14,0x79,
+0x30,0x0, 0xa, 0x22,0xca,0x79,0x7c,0x57,0x7c,0x7b,0x6c,0x66,0x80,0x17,0x7e,0xf0,
+0x2, 0xac,0xf6,0x7e,0x7f,0x40,0xc, 0x2d,0xf7,0xb, 0x7a,0x40,0x7f,0x70,0x2d,0xf7,
+0x1b,0x7a,0x40,0xb, 0x60,0xbc,0x56,0x38,0xe5,0x6c,0x66,0x80,0x20,0x7e,0x90,0x2,
+0xac,0x96,0x7e,0x7f,0x40,0xc, 0x2d,0xf4,0x69,0x47,0x0, 0x48,0xa, 0xe5,0xa, 0xf6,
+0x2d,0xfe,0x3e,0xf4,0x2d,0xf1,0x7d,0xe0,0x1b,0x7a,0x40,0xb, 0x60,0xbc,0x76,0x38,
+0xdc,0x7e,0x7f,0x40,0x14,0x69,0x47,0x0, 0x4, 0x5e,0x44,0x0, 0x1, 0x78,0x2, 0xe1,
+0x3f,0xa, 0x45,0xa, 0x57,0x2d,0x54,0x7c,0xab,0x6c,0x66,0x80,0x20,0x7e,0x90,0x2,
+0xac,0x96,0x7e,0x7f,0x40,0xc, 0x2d,0xf4,0x69,0x47,0x0, 0x8e,0xa, 0xe6,0xa, 0xfa,
+0x2d,0xfe,0x3e,0xf4,0x2d,0xf1,0x7d,0xe0,0x1b,0x7a,0x40,0xb, 0x60,0xbc,0x56,0x38,
+0xdc,0x2c,0xa5,0x6c,0x66,0x80,0x20,0x7e,0x90,0x2, 0xac,0x96,0x7e,0x7f,0x40,0xc,
+0x2d,0xf4,0x69,0x47,0x0, 0xd6,0xa, 0xe6,0xa, 0xfa,0x2d,0xfe,0x3e,0xf4,0x2d,0xf1,
+0x7d,0xe0,0x1b,0x7a,0x40,0xb, 0x60,0xbc,0x76,0x38,0xdc,0x7e,0x7f,0x40,0x14,0x69,
+0x47,0x0, 0x4, 0x1e,0x44,0x5e,0x44,0x0, 0x1, 0x78,0x54,0x2c,0xa7,0x6c,0x66,0x80,
+0x20,0x7e,0x90,0x2, 0xac,0x96,0x7e,0x7f,0x40,0xc, 0x2d,0xf4,0x69,0x47,0x1, 0x1c,
+0xa, 0xe6,0xa, 0xfa,0x2d,0xfe,0x3e,0xf4,0x2d,0xf1,0x7d,0xe0,0x1b,0x7a,0x40,0xb,
+0x60,0xbc,0x56,0x38,0xdc,0x2c,0xa5,0x6c,0x66,0x80,0x20,0x7e,0x50,0x2, 0xac,0x56,
+0x7e,0x7f,0x40,0xc, 0x2d,0xf2,0x69,0x27,0x1, 0x64,0xa, 0xf6,0xa, 0x4a,0x2d,0x4f,
+0x3e,0x44,0x7f,0x70,0x2d,0xf4,0x1b,0x7a,0x20,0xb, 0x60,0xbc,0x76,0x38,0xdc,0xda,
+0x79,0x22,0xbe,0x8, 0x0, 0x0, 0x78,0x2, 0xe1,0xf4,0xbe,0x18,0x0, 0x0, 0x78,0x2,
+0xe1,0xf4,0x29,0xb1,0x0, 0x2, 0xbe,0xb0,0x3, 0x28,0x5, 0xe4,0x39,0xb1,0x0, 0x2,
+0x29,0xb1,0x0, 0x3, 0xbe,0xb0,0x40,0x28,0x6, 0x74,0x40,0x39,0xb1,0x0, 0x3, 0x29,
+0xb1,0x0, 0x2, 0xa, 0x4b,0x9, 0xa4,0x3f,0xca,0x39,0xb0,0x0, 0x4, 0x29,0x91,0x0,
+0x3, 0x39,0x90,0x0, 0x5, 0xb4,0x3, 0xf, 0xb, 0x1a,0xf0,0x7e,0xe4,0x0, 0x6, 0x8d,
+0xfe,0x79,0xf0,0x0, 0x2, 0x80,0x7, 0xb, 0x1a,0x40,0x79,0x40,0x0, 0x2, 0xb, 0x1a,
+0x40,0x1e,0x44,0x29,0xb1,0x0, 0x4, 0xa, 0xeb,0x7d,0xf4,0x9d,0xfe,0x79,0xf0,0x0,
+0x6, 0x1b,0x45,0x79,0x40,0x0, 0x8, 0xb, 0x1a,0xf0,0x1e,0xf4,0x69,0x41,0x0, 0x5,
+0x9d,0xf4,0x9e,0xf4,0x0, 0xa, 0x79,0xf0,0x0, 0xa, 0x79,0x40,0x0, 0xc, 0x29,0xb1,
+0x0, 0x7, 0x39,0xb0,0x0, 0xe, 0x39,0xb0,0x0, 0xf, 0xa, 0x3b,0x29,0xb0,0x0, 0xe,
+0xa, 0x2b,0x2d,0x23,0x29,0xb0,0x0, 0x5, 0xa, 0x3b,0xad,0x32,0xa, 0x2a,0x12,0x26,
+0xc7,0x1b,0xa, 0x30,0x22,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x22,0x32,0x32,
+0xca,0x3b,0x7f,0x30,0x7e,0x3b,0xb0,0xf5,0x27,0x29,0xb3,0x0, 0x1, 0xbe,0xb1,0x27,
+0x28,0x2, 0xf5,0x27,0x69,0x13,0x0, 0x6, 0x6d,0x0, 0x7e,0x34,0x0, 0xf2,0x74,0xff,
+0x12,0x29,0x72,0x7f,0x3, 0x12,0x7, 0xa8,0xa9,0xd6,0xcb,0x75,0x25,0x0, 0x80,0x33,
+0x75,0x26,0x0, 0x80,0x23,0x7e,0x11,0x25,0x74,0xb, 0xac,0x1b,0xe5,0x26,0xa, 0x1b,
+0x2d,0x1, 0x3e,0x4, 0x69,0x13,0x0, 0x6, 0x2d,0x10,0x6d,0x0, 0xb, 0xa, 0x30,0x6e,
+0x34,0xff,0xff,0x1b,0xa, 0x30,0x5, 0x26,0x29,0x73,0x0, 0x1, 0xbe,0x71,0x26,0x38,
+0xd4,0x5, 0x25,0x7e,0x3b,0x70,0xbe,0x71,0x25,0x38,0xc5,0x69,0x33,0x0, 0x6, 0x7e,
+0xf, 0x40,0x3b,0x79,0x30,0x0, 0x4, 0xe5,0x27,0xa, 0x2b,0x7d,0x32,0x7c,0x67,0x6c,
+0x77,0x2d,0x32,0x7e,0xf, 0x40,0x3b,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,0x40,
+0x3b,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xd0,0x12,0x19,0x84,0x75,0x25,0x0, 0xe5,0x25,
+0xbe,0xb0,0x4, 0x50,0x17,0x7e,0xa1,0x25,0x74,0x4, 0xa4,0x7e,0x1f,0x40,0x3b,0x69,
+0x11,0x0, 0x26,0x60,0x44,0x1e,0x14,0x14,0x78,0xfb,0x80,0x3d,0xe5,0x25,0xbe,0xb0,
+0x8, 0x50,0x1b,0xe5,0x25,0xa, 0x5b,0x1b,0x56,0x3e,0x54,0x3e,0x54,0x7e,0x1f,0x40,
+0x3b,0x69,0x11,0x0, 0x28,0x60,0x22,0x1e,0x14,0x14,0x78,0xfb,0x80,0x1b,0xe5,0x25,
+0xa, 0x5b,0x9e,0x54,0x0, 0x8, 0x3e,0x54,0x3e,0x54,0x7e,0x1f,0x40,0x3b,0x69,0x11,
+0x0, 0x2a,0x60,0x5, 0x1e,0x14,0x14,0x78,0xfb,0x5e,0x14,0x0, 0xf, 0x7e,0xa1,0x25,
+0x74,0x2, 0xa4,0x69,0x33,0x0, 0x6, 0x2d,0x35,0x6d,0x22,0x1b,0x1a,0x10,0x5, 0x25,
+0xe5,0x25,0xbe,0xb0,0xb, 0x40,0x87,0xa9,0xc6,0xcb,0xda,0x3b,0x22,0xca,0x3b,0x7f,
+0x30,0x74,0x1, 0x12,0x1d,0x89,0x29,0x73,0x1, 0xd, 0x2e,0x70,0xff,0x92,0x4, 0x29,
+0xb3,0x1, 0xe, 0x12,0x1d,0x71,0x7f,0x3, 0x12,0x16,0x52,0x7f,0x3, 0x12,0x3, 0x95,
+0x29,0x73,0x0, 0xa, 0xa, 0x37,0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x24,0x29,0x73,
+0x0, 0xb5,0xa, 0x27,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,
+0x3e,0x24,0x69,0x33,0x1, 0x19,0x4d,0x32,0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x2,
+0x29,0x73,0x0, 0xa, 0xa, 0x47,0x29,0x73,0x0, 0x1, 0xa, 0x57,0x9d,0x54,0xf5,0x33,
+0x7f,0x3, 0x12,0x14,0x6a,0x29,0x73,0x0, 0xb7,0x2e,0x70,0xff,0x92,0x4, 0x7f,0x3,
+0xe5,0x33,0x12,0x15,0xb8,0x69,0x23,0x1, 0x15,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,
+0x24,0x3e,0x24,0x3e,0x24,0x29,0x73,0x1, 0x14,0xa, 0x37,0x2d,0x32,0x7e,0xf, 0x3f,
+0xc6,0x79,0x30,0x0, 0x2a,0x29,0x73,0x1, 0x13,0xa, 0x37,0x7e,0xf, 0x3f,0xc6,0x79,
+0x30,0x0, 0x2c,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x34,0x7e,
+0x34,0x1, 0xb, 0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x2e,0x29,0x73,0x0, 0x1, 0xa,
+0x37,0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x10,0x29,0x73,0x0, 0xb9,0x7e,0x60,0x1,
+0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x1a,0x69,0x33,0x0, 0xba,0x7e,0xf, 0x3f,0xc6,
+0x79,0x30,0x0, 0x1c,0x69,0x33,0x0, 0xbc,0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x1e,
+0x7f,0x3, 0x12,0x12,0xf5,0xda,0x3b,0x22,0x7f,0x21,0xa9,0xd6,0xcb,0x69,0x30,0x0,
+0x4, 0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x7f,0x40,
+0x3b,0x79,0x37,0x0, 0x6, 0x69,0x30,0x0, 0x6, 0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0,
+0x8, 0x29,0x70,0x0, 0x1, 0x7c,0x47,0x6c,0x55,0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,
+0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x1b,0x34,
+0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0xa, 0x69,0x30,0x0, 0xa, 0x7e,0x7f,0x40,0x3b,
+0x79,0x37,0x0, 0xe, 0x69,0x30,0x0, 0xc, 0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0x10,
+0x69,0x30,0x0, 0xe, 0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0x12,0x69,0x30,0x0, 0x10,
+0x7e,0x7f,0x40,0x3b,0x79,0x37,0x0, 0x30,0x29,0x70,0x0, 0x3, 0x7c,0x27,0x6c,0x33,
+0x7e,0x1f,0x40,0x3b,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xa0,0x12,0x19,0x84,0x7e,0x1f,
+0x40,0x3b,0x69,0x11,0x0, 0x1a,0x7a,0x2b,0x30,0x69,0x11,0x0, 0x1c,0x39,0x32,0x0,
+0x1, 0x69,0x11,0x0, 0x16,0x79,0x12,0x0, 0x2, 0x69,0x11,0x0, 0x18,0x79,0x12,0x0,
+0x4, 0x69,0x11,0x0, 0x22,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x24,0x79,0x12,0x0,
+0x8, 0x69,0x11,0x0, 0x1e,0x79,0x12,0x0, 0xa, 0x69,0x31,0x0, 0x20,0x79,0x32,0x0,
+0xc, 0xa9,0xc6,0xcb,0x22,0xca,0x79,0x7f,0x60,0x29,0x76,0x1, 0x1e,0xa, 0x27,0x5e,
+0x24,0x0, 0x1, 0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7e,
+0xf, 0x3f,0xc6,0xb, 0x15,0xb, 0xa, 0x30,0x5e,0x70,0xbf,0x4d,0x32,0x1b,0xa, 0x30,
+0x29,0x76,0x1, 0x1f,0x7c,0xf7,0xbe,0xf0,0x3, 0x38,0x4, 0x7c,0xf7,0x80,0x3, 0x7e,
+0xf0,0x3, 0xa, 0x3f,0x5e,0x34,0x0, 0x3, 0x7d,0x23,0x7c,0x45,0x6c,0x55,0x3e,0x24,
+0x3e,0x24,0x3e,0x24,0x7e,0xf, 0x3f,0xc6,0xb, 0x15,0xb, 0xa, 0x30,0x5e,0x60,0xe7,
+0x4d,0x32,0x1b,0xa, 0x30,0x29,0x76,0x0, 0xb8,0x7a,0x73,0x31,0xcf,0x69,0x36,0x1,
+0x17,0x7a,0x37,0x31,0xd0,0x29,0x76,0x1, 0x31,0x7a,0x73,0x31,0xd2,0x6c,0xee,0x80,
+0x46,0x74,0x5, 0xac,0xbe,0x7f,0x16,0x2d,0x35,0x69,0x31,0x1, 0x21,0x7a,0x37,0x31,
+0xcb,0x74,0x5, 0xac,0xbe,0x7f,0x16,0x2d,0x35,0x29,0x71,0x1, 0x23,0x7a,0x73,0x31,
+0xcd,0x74,0x5, 0xac,0xbe,0x7f,0x16,0x2d,0x35,0x29,0x71,0x1, 0x24,0x7a,0x73,0x31,
+0xce,0x7e,0x8, 0x31,0xbb,0x7e,0x18,0x31,0xcb,0x12,0xf, 0x42,0x7e,0x8, 0x31,0xbb,
+0x7c,0xbe,0x12,0x1, 0x30,0xb, 0xe0,0xbc,0xfe,0x38,0xb6,0xda,0x79,0x22,0xca,0x79,
+0x29,0x70,0x0, 0xb, 0xa, 0x27,0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x6d,0x44,0x6c,
+0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x3f,0xbe,0x2d,0xf2,0x79,0x47,0x0, 0x2,
+0xb, 0xa0,0xbe,0xa0,0x23,0x78,0xea,0x6c,0xaa,0x80,0x4f,0xa, 0x2a,0x7f,0x70,0x2d,
+0xf2,0x29,0x67,0x0, 0x54,0xbe,0x60,0x23,0x50,0x1d,0x29,0xb7,0x0, 0xc6,0x7c,0x8b,
+0x6c,0x99,0x7e,0x50,0x2, 0xac,0x56,0x7e,0x7f,0x3f,0xbe,0x2d,0xf2,0xb, 0xf5,0xb,
+0x7a,0x20,0x4d,0x24,0x1b,0x7a,0x20,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0xb7,0x0,
+0x54,0xa, 0x4b,0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x3f,0xbe,0x2d,0xf2,0xb, 0xf5,
+0xb, 0x7a,0x20,0x4d,0x24,0x1b,0x7a,0x20,0xb, 0xa0,0xbc,0x7a,0x38,0xad,0x6c,0xaa,
+0x80,0x1d,0xa, 0x3a,0x2d,0x31,0x7d,0x20,0x29,0xb1,0x0, 0x77,0xa, 0x4b,0x7e,0xf0,
+0x2, 0xac,0xfa,0x7e,0x1f,0x3f,0xbe,0x2d,0x37,0x79,0x41,0x0, 0x52,0xb, 0xa0,0x29,
+0xb0,0x0, 0x1, 0xbc,0xba,0x38,0xdb,0xda,0x79,0x22,0xca,0x3b,0x7f,0x30,0xe4,0x12,
+0x19,0xdd,0x6c,0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x69,0x13,0x1, 0x1b,0x2d,0x12,0x7e,
+0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x7e,0xf, 0x40,0x10,0x2d,0x12,0x79,0x30,0x3, 0xd4,
+0xb, 0xa0,0xbe,0xa0,0xc, 0x78,0xdd,0x29,0x73,0x1, 0x1d,0xa, 0x37,0x7e,0xf, 0x40,
+0x10,0x79,0x30,0x3, 0xf2,0x6c,0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x69,0x13,0x1, 0x2f,
+0x2d,0x12,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x7e,0xf, 0x40,0x10,0x2d,0x12,0x79,
+0x30,0x3, 0xf4,0xb, 0xa0,0xbe,0xa0,0xc, 0x78,0xdd,0x29,0x73,0x1, 0x31,0xa, 0x37,
+0x7e,0xf, 0x40,0x10,0x79,0x30,0x4, 0x12,0x29,0xb3,0x1, 0x32,0x70,0x2, 0x81,0xf6,
+0x7e,0x34,0xff,0xff,0x7e,0xf, 0x40,0x10,0x79,0x30,0x4, 0xc, 0x7e,0xf, 0x40,0x10,
+0x79,0x30,0x4, 0xe, 0xa1,0x8, 0x6d,0x33,0x7e,0xf, 0x40,0x10,0x79,0x30,0x4, 0xc,
+0x7e,0xf, 0x40,0x10,0x79,0x30,0x4, 0xe, 0x7e,0xf, 0x40,0x10,0x79,0x30,0x4, 0x10,
+0xda,0x3b,0x22,0x7c,0xab,0x6c,0x77,0x7e,0x50,0x3, 0xac,0x57,0x7d,0x42,0x2e,0x44,
+0x28,0x6a,0x7a,0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0xbc,0xba,0x78,0x23,0x7d,0x42,
+0x2e,0x44,0x28,0x6b,0x7a,0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0x7a,0xb, 0xb0,0x2e,
+0x24,0x28,0x6c,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0x39,0xb0,0x0, 0x1, 0x80,
+0x7, 0xb, 0x70,0xbe,0x70,0x2, 0x28,0xbf,0xbe,0x70,0x2, 0x28,0x25,0x7e,0x34,0x28,
+0x28,0x79,0x30,0x0, 0x2, 0x7e,0x34,0x27,0xe0,0x79,0x30,0x0, 0x4, 0xbe,0xa0,0x81,
+0x78,0x9, 0x74,0x23,0x7a,0xb, 0xb0,0x74,0x24,0x80,0x38,0x74,0x1, 0x7a,0xb, 0xb0,
+0x80,0x31,0x2e,0xa0,0xf4,0x68,0x4, 0xb, 0xa0,0x78,0x11,0x7e,0x34,0x28,0x4b,0x79,
+0x30,0x0, 0x2, 0x7e,0x34,0x28,0x4, 0x79,0x30,0x0, 0x4, 0x22,0x7e,0x34,0x28,0x28,
+0x79,0x30,0x0, 0x2, 0x7e,0x34,0x27,0xe0,0x79,0x30,0x0, 0x4, 0x74,0x23,0x7a,0xb,
+0xb0,0x74,0x24,0x39,0xb0,0x0, 0x1, 0x22,0xca,0x79,0x7c,0xeb,0x7a,0xd, 0x34,0x7e,
+0x1f,0x40,0x10,0x2e,0x34,0x3, 0xec,0x7a,0x1d,0x39,0x7e,0x8, 0x31,0xbb,0x7e,0x34,
+0x0, 0x6, 0xe4,0x12,0x29,0x72,0xa2,0x4, 0xe4,0x33,0x7e,0x1d,0x34,0x39,0xb1,0x0,
+0xb7,0x7e,0x1d,0x34,0x29,0x71,0x0, 0xb7,0x7a,0x73,0x3f,0xbc,0x30,0x4, 0x3d,0x6c,
+0xff,0x80,0x35,0xa, 0x5f,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x7c,0xab,0xa,
+0x3f,0x7e,0x24,0x0, 0x10,0x12,0x26,0xc7,0x7c,0xb5,0x7e,0x44,0x0, 0x1, 0x60,0x5,
+0x3e,0x44,0x14,0x78,0xfb,0x7e,0x50,0x2, 0xac,0x5a,0x2e,0x24,0x31,0xbb,0xb, 0x28,
+0x30,0x4d,0x34,0x1b,0x28,0x30,0xb, 0xf0,0xbc,0xef,0x38,0xc7,0x7e,0xd, 0x34,0x12,
+0x3, 0x95,0xe4,0x12,0x19,0xdd,0x6c,0xff,0x74,0x2, 0xac,0xbf,0x49,0x15,0x31,0xbb,
+0x7e,0x1d,0x39,0x2d,0x35,0x1b,0x1a,0x10,0xb, 0xf0,0xbe,0xf0,0x3, 0x40,0xe9,0xda,
+0x79,0x22,0x69,0x30,0x0, 0xc0,0x29,0xb0,0x0, 0xb5,0xb4,0x3, 0x12,0x7e,0x44,0x0,
+0x6, 0x7d,0x53,0x8d,0x54,0x7e,0x7f,0x3f,0xc6,0x79,0x57,0x0, 0x6, 0x80,0x8, 0x7e,
+0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x6, 0x29,0x50,0x0, 0xb8,0xa, 0x55,0x7d,0x23,0x1e,
+0x24,0x9d,0x25,0x7e,0x2f,0x3f,0xc6,0x79,0x22,0x0, 0x18,0x7d,0x23,0x1e,0x24,0x1b,
+0x25,0x7e,0x2f,0x3f,0xc6,0x79,0x22,0x0, 0x38,0x69,0x20,0x1, 0x17,0x1e,0x34,0x9d,
+0x32,0x9e,0x34,0x0, 0xa, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x26,0x69,0x30,0x1,
+0x17,0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x28,0x29,0x70,0x0, 0xb9,0xa, 0x37,0x7e,
+0x60,0x1, 0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x1a,0x29,0x70,0x0, 0xb, 0xa, 0x27,
+0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x3f,0xc6,0x79,0x32,0x0, 0x8, 0x2,
+0x13,0xbe,0xa9,0xd6,0xcb,0x69,0x20,0x0, 0x4, 0x7e,0x7f,0x40,0x3b,0x79,0x27,0x0,
+0x4, 0x69,0x20,0x0, 0x6, 0x7e,0x7f,0x40,0x3b,0x79,0x27,0x0, 0x6, 0x69,0x20,0x0,
+0x8, 0x7e,0x7f,0x40,0x3b,0x79,0x27,0x0, 0x8, 0x6d,0x22,0x7e,0x7f,0x40,0x3b,0x79,
+0x27,0x0, 0xe, 0x7c,0x4b,0x7c,0x64,0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0x10,0x7e,
+0x2f,0x40,0x3b,0x2e,0x54,0x0, 0xe, 0xb, 0x2a,0x30,0x6d,0x33,0x7e,0x2f,0x40,0x3b,
+0x79,0x32,0x0, 0xa, 0x7e,0xb, 0x70,0x7c,0x47,0x29,0x70,0x0, 0x1, 0x2d,0x32,0x7e,
+0xf, 0x40,0x3b,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,0x40,0x3b,0x1b,0x1a,0x10,
+0x7e,0x34,0x0, 0x30,0x12,0x19,0x84,0xa9,0xc6,0xcb,0x22,0xa9,0xd6,0xcb,0x69,0x30,
+0x0, 0x6, 0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,
+0x40,0x3b,0x79,0x32,0x0, 0x8, 0x29,0x70,0x0, 0x2, 0x7c,0x47,0x6c,0x55,0x29,0x70,
+0x0, 0x3, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0xc, 0x7e,0xb,
+0x70,0x7c,0x47,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x40,0x3b,0x79,
+0x32,0x0, 0xa, 0x29,0x70,0x0, 0x4, 0xa, 0x37,0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0,
+0xe, 0x29,0xb0,0x0, 0x5, 0x54,0x1, 0x7c,0x2b,0x6c,0x33,0x7e,0x1f,0x40,0x3b,0x1b,
+0x1a,0x10,0x7e,0x34,0x0, 0xc0,0x12,0x19,0x84,0xa9,0xc6,0xcb,0x22,0x2e,0x34,0x4,
+0x0, 0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x80,0x7e,0x34,0x4, 0x0, 0x9d,0x32,0x7e,
+0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x82,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x3f,0xc6,0x79,
+0x30,0x0, 0x84,0xa, 0x3b,0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x86,0x22,0xff,0xff,
+0xa9,0xd6,0xcb,0xc2,0x18,0x69,0x30,0x0, 0x4, 0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0,
+0x4, 0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0x6, 0x69,0x30,0x0,
+0x8, 0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0x8, 0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,
+0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0xc,
+0x29,0x70,0x0, 0x2, 0xa, 0x37,0x7e,0x2f,0x40,0x3b,0x79,0x32,0x0, 0xe, 0x29,0xb0,
+0x0, 0x3, 0x54,0x1, 0xa, 0x5b,0x7c,0xab,0xe4,0x7e,0x1f,0x40,0x3b,0x1b,0x1a,0x50,
+0x69,0x30,0x0, 0xa, 0x12,0x19,0x84,0xa9,0xc6,0xcb,0x22,0x74,0x3, 0x12,0x1c,0xfb,
+0x74,0x1, 0x12,0x19,0xdd,0xa9,0xd1,0xc4,0x7e,0xf, 0x3f,0xbe,0x2e,0x14,0x0, 0x9e,
+0xb, 0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x7e,0xf, 0x3f,0xbe,0xb, 0xa, 0x30,
+0x5e,0x70,0xf9,0x1b,0xa, 0x30,0x7e,0xf, 0x3f,0xbe,0xb, 0xa, 0x30,0x4e,0x70,0x1,
+0x1b,0xa, 0x30,0x7e,0xf, 0x3f,0xc6,0xb, 0x16,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,
+0xa, 0x30,0xc2,0xb, 0xe4,0x7a,0xb3,0x3f,0xde,0x7e,0x1f,0x3f,0xbe,0xb, 0x1a,0x30,
+0x5e,0x34,0x0, 0x1, 0x78,0xf3,0x74,0x2, 0x2, 0x1c,0xfb,0xa9,0xd6,0xcb,0x69,0x20,
+0x0, 0x4, 0x7e,0x2f,0x40,0x3b,0x79,0x22,0x0, 0x4, 0x69,0x20,0x0, 0x8, 0x7e,0x2f,
+0x40,0x3b,0x79,0x22,0x0, 0x8, 0x7e,0xb, 0x50,0xa, 0x55,0x7c,0xab,0xe4,0x29,0x50,
+0x0, 0x1, 0xa, 0x25,0x2d,0x25,0x7e,0x2f,0x40,0x3b,0x79,0x22,0x0, 0xc, 0x29,0x50,
+0x0, 0x2, 0xa, 0x25,0x7e,0xf, 0x40,0x3b,0x79,0x20,0x0, 0xe, 0x7e,0xf, 0x40,0x3b,
+0x79,0x30,0x0, 0xa, 0x6d,0x11,0x7e,0x1f,0x40,0x3b,0x1b,0x1a,0x10,0x7e,0x34,0x0,
+0x40,0x12,0x19,0x84,0xa9,0xc6,0xcb,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,
+0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0xb, 0x7e,0xf,
+0x3f,0xc6,0x69,0x30,0x0, 0x4, 0x7a,0x73,0x3f,0xde,0x7e,0x73,0x3f,0xde,0xa, 0x37,
+0x5e,0x34,0x0, 0x4, 0x68,0x4, 0xd2,0xa, 0x80,0x2, 0xc2,0xa, 0x7e,0x34,0x0, 0x1f,
+0x79,0x30,0x0, 0x4, 0xc2,0xc3,0x12,0x1d,0x3e,0x12,0x5f,0x74,0xa9,0xc1,0xc4,0xd0,
+0x82,0xd0,0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,
+0x6b,0xda,0x7b,0x32,0xa9,0xd7,0xcb,0x7d,0x23,0x4e,0x50,0x1, 0x7e,0xf, 0x40,0x3b,
+0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x80,0x1e,0x7e,0xf, 0x40,0x3b,0xb, 0xa,
+0x30,0x7d,0x23,0x5e,0x24,0x0, 0x8, 0xbe,0x24,0x0, 0x8, 0x78,0xb, 0xa9,0xd7,0xcb,
+0x4e,0x70,0x4, 0x1b,0xa, 0x30,0xd2,0x18,0x7e,0xf, 0x40,0x3b,0x69,0x30,0x0, 0x38,
+0x5e,0x34,0x80,0x0, 0xbe,0x34,0x80,0x0, 0x78,0xd0,0xb, 0xa, 0x30,0x4e,0x60,0x40,
+0x1b,0xa, 0x30,0x6d,0x11,0x7e,0x1f,0x40,0x3b,0x1b,0x1a,0x10,0x22,0x7c,0xab,0xbe,
+0xa0,0x2, 0x78,0x1b,0x7e,0x1f,0x3f,0xbe,0xb, 0x1a,0x30,0x1e,0x34,0x1e,0x34,0x1e,
+0x34,0x5e,0x34,0x0, 0x1, 0x78,0x6, 0x74,0x1, 0x7c,0xab,0x80,0x2, 0x6c,0xaa,0xa,
+0x2a,0x5e,0x24,0x0, 0x1, 0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7e,0xf, 0x3f,0xbe,0xb,
+0xa, 0x30,0x5e,0x70,0xf7,0x4d,0x32,0x1b,0xa, 0x30,0x7e,0x1f,0x3f,0xbe,0xb, 0x1a,
+0x20,0x1e,0x24,0x1e,0x24,0x1e,0x24,0x1e,0x24,0x5e,0x24,0x0, 0x1, 0xa, 0x3a,0xbd,
+0x23,0x78,0xe7,0x22,0xca,0xf8,0x7c,0xfb,0x7f,0x71,0x7f,0x60,0xe5,0x24,0x7e,0x8,
+0x0, 0x25,0x12,0x15,0x13,0xbe,0xf0,0x23,0x28,0x3, 0x7e,0xf0,0x23,0x6c,0xaa,0x80,
+0x33,0xa, 0x3a,0x2d,0x3f,0x7d,0x2e,0x7e,0x1b,0x70,0xbe,0x71,0x25,0x40,0xd, 0x74,
+0x23,0xa, 0x4a,0x7f,0x6, 0x2d,0x14,0x7a,0xb, 0xb0,0x80,0x16,0xa, 0x37,0x2e,0x35,
+0x27,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x16,0x2d,0x34,0x7a,
+0x1b,0xb0,0xb, 0xa0,0xbc,0xfa,0x38,0xc9,0xda,0xf8,0x22,0x6c,0xaa,0x7e,0x50,0x2,
+0xac,0x5a,0x69,0xf0,0x0, 0xe, 0x69,0xe0,0x0, 0xc, 0x2d,0xf2,0x29,0xb7,0x0, 0x1,
+0x7c,0x8b,0x6c,0x99,0x7e,0x7b,0xb0,0xa, 0x3b,0x4d,0x34,0x7e,0x7f,0x40,0x10,0x2d,
+0xf2,0x79,0x37,0x3, 0xb0,0xb, 0xa0,0xbe,0xa0,0x12,0x40,0xd1,0x7e,0x34,0xff,0xff,
+0x7e,0xf, 0x40,0x10,0x79,0x30,0x3, 0xa8,0x7e,0xf, 0x40,0x10,0x79,0x30,0x3, 0xaa,
+0x7e,0xf, 0x40,0x10,0x79,0x30,0x3, 0xac,0x7e,0xf, 0x40,0x10,0x79,0x30,0x3, 0xae,
+0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,
+0xd0,0xc0,0x83,0xc0,0x82,0xd2,0x19,0x7e,0xf, 0x40,0x14,0xb, 0xa, 0x30,0x7c,0x57,
+0x7a,0x53,0x40,0xb, 0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xc2,0xc6,0x6d,0x33,0x7e,0xf,
+0x40,0x14,0x79,0x30,0x0, 0x10,0x12,0x1d,0x3e,0x12,0x5f,0x74,0xd0,0x82,0xd0,0x83,
+0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,
+0x32,0xca,0xf8,0x7c,0xfb,0x7f,0x71,0x7f,0x60,0xe5,0x24,0x7e,0x8, 0x0, 0x25,0x12,
+0x15,0x13,0x6c,0xaa,0x80,0x33,0xa, 0x3a,0x2d,0x3f,0x7d,0x2e,0x7e,0x1b,0x70,0xbe,
+0x71,0x26,0x40,0xd, 0x74,0x24,0xa, 0x4a,0x7f,0x6, 0x2d,0x14,0x7a,0xb, 0xb0,0x80,
+0x16,0xa, 0x37,0x2e,0x35,0x29,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x4a,
+0x7f,0x16,0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xbc,0xfa,0x38,0xc9,0xda,0xf8,0x22,
+0xca,0x79,0x7c,0x6b,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x60,0x2d,0xd4,0x29,
+0xb6,0x0, 0x1, 0xa, 0xfb,0x7d,0x2f,0x7c,0x45,0x6c,0x55,0x7d,0xf2,0x7e,0x6b,0xb0,
+0xa, 0x2b,0x4d,0x2f,0x7e,0xf0,0x34,0xac,0xf7,0x2d,0x47,0xa, 0xe6,0x7e,0xf4,0x1,
+0x38,0xad,0xfe,0x2d,0x4f,0x7e,0x7f,0x40,0x10,0x2d,0xf4,0x79,0x27,0x0, 0x1c,0xb,
+0xa0,0xbe,0xa0,0xc, 0x40,0xc0,0xda,0x79,0x22,0xca,0x79,0x7c,0x6b,0x6c,0xaa,0x7e,
+0x90,0x2, 0xac,0x9a,0x7f,0x60,0x2d,0xd4,0x29,0xb6,0x0, 0x1, 0xa, 0xfb,0x7d,0x2f,
+0x7c,0x45,0x6c,0x55,0x7d,0xf2,0x7e,0x6b,0xb0,0xa, 0x2b,0x4d,0x2f,0x7e,0xf0,0x34,
+0xac,0xf7,0x2d,0x47,0xa, 0xe6,0x7e,0xf4,0x1, 0x38,0xad,0xfe,0x2d,0x4f,0x7e,0x7f,
+0x40,0x10,0x2d,0xf4,0x79,0x27,0x0, 0x10,0xb, 0xa0,0xbe,0xa0,0x6, 0x40,0xc0,0xda,
+0x79,0x22,0x7c,0x6b,0xa9,0xd6,0xcb,0xbe,0x60,0x23,0x28,0x3, 0x7e,0x60,0x23,0xbe,
+0x70,0x24,0x28,0x3, 0x7e,0x70,0x24,0x7e,0x14,0x0, 0x5, 0x7e,0x2f,0x40,0x3b,0x79,
+0x12,0x0, 0x2, 0x7c,0x26,0x6c,0x33,0xa, 0x37,0x2d,0x31,0x7e,0xf, 0x40,0x3b,0x79,
+0x30,0x0, 0x32,0x7e,0xf, 0x40,0x3b,0x79,0x20,0x0, 0x14,0xa9,0xc6,0xcb,0x22,0x6c,
+0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x7f,0x70,0x2d,0xf2,0x29,0xb7,0x0, 0x1, 0x7c,0x8b,
+0x6c,0x99,0x7e,0x7b,0xb0,0xa, 0x3b,0x4d,0x34,0x7e,0x7f,0x40,0x10,0x2d,0xf2,0x79,
+0x37,0x3, 0xb0,0xb, 0xa0,0xbe,0xa0,0x12,0x40,0xd7,0x22,0x7e,0x34,0x0, 0x1f,0x7e,
+0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x4, 0xa9,0xd2,0xcd,0x7e,0xb3,0x3f,0xce,0xb4,0x1,
+0x7, 0x12,0x6, 0x80,0x7a,0x73,0x3f,0xbd,0x7e,0xf, 0x3f,0xc6,0xb, 0xa, 0x30,0x4e,
+0x70,0x1, 0x1b,0xa, 0x30,0x22,0x7c,0xa5,0xbe,0x34,0x0, 0x0, 0x28,0x10,0xa, 0x1b,
+0x3e,0x14,0x7d,0x23,0x7c,0x45,0x6c,0x55,0x2d,0x21,0xa, 0x3a,0x80,0x8, 0xa, 0x2b,
+0x3e,0x24,0x7c,0x67,0x6c,0x77,0x2d,0x32,0x7e,0xf, 0x40,0x14,0x79,0x30,0x0, 0x4,
+0x22,0x7c,0xa7,0x7e,0x1f,0x3f,0xbe,0x69,0x41,0x0, 0xa4,0x5e,0x44,0x10,0xf, 0xa,
+0x1a,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x3e,0x14,0xa, 0x5b,0xc4,0x23,0x54,0xe0,0x7c,
+0xab,0xe4,0x2d,0x51,0x4d,0x45,0x79,0x41,0x0, 0xa4,0x22,0x7e,0xf, 0x3f,0xbe,0x69,
+0x30,0x0, 0x9e,0x5e,0x70,0xe7,0x1b,0xb1,0x68,0xc, 0x14,0x68,0xc, 0xb, 0xb1,0x78,
+0x5, 0x4e,0x70,0x10,0x80,0x3, 0x4e,0x70,0x8, 0x79,0x30,0x0, 0x9e,0x22,0xa, 0x5b,
+0x5e,0x54,0x0, 0x1, 0xc4,0x54,0xf0,0x7c,0xab,0xe4,0x7e,0xf, 0x3f,0xbe,0x2e,0x14,
+0x0, 0xa4,0xb, 0xa, 0x30,0x5e,0x60,0xef,0x4d,0x35,0x1b,0xa, 0x30,0x22,0x7e,0xf,
+0x3f,0xbe,0x2e,0x14,0x0, 0x9e,0xb, 0xa, 0x30,0x5e,0x70,0xdf,0x1b,0xa, 0x30,0x74,
+0x3, 0x12,0x1c,0xfb,0xe4,0x2, 0x1c,0xfb,0xbe,0xb0,0x0, 0x28,0xa, 0xa9,0xd7,0xca,
+0xa9,0xd3,0xcb,0xa9,0xd2,0xcb,0x22,0xa9,0xc7,0xca,0xa9,0xc3,0xcb,0xa9,0xc2,0xcb,
+0x22,0x30,0x4, 0xa, 0x54,0x3, 0xa, 0x3b,0x2e,0x34,0x2, 0x0, 0x80,0x2, 0x6d,0x33,
+0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x3a,0x22,0xbe,0xb0,0x0, 0x28,0x9, 0xa9,0xd6,
+0xca,0xd2,0xcd,0xa9,0xd1,0xcb,0x22,0xa9,0xc6,0xca,0xc2,0xcd,0xa9,0xc1,0xcb,0x22,
+0x7e,0x34,0x0, 0xf, 0x7e,0xf, 0x3f,0xc6,0x79,0x30,0x0, 0x4, 0xc2,0xc3,0xd2,0xeb,
+0x22,0x7d,0x13,0x7e,0x1f,0x40,0x14,0x1b,0x1a,0x10,0xc2,0xc6,0xd2,0xee,0x22,0x6,
+0xe, 0x15,0x1a,0x1f,0x26,0x2b,0x2d,0x2e,0x2f,0x2c,0x2a,0x24,0x1f,0x1a,0x14,0xf,
+0x8, 0x3, 0x3, 0x6, 0xb, 0x10,0x15,0x1c,0x22,0x28,0x2d,0x34,0x39,0x3d,0x40,0xe,
+0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xc, 0x11,0x16,0x1c,0x23,0x2b,0x32,0x37,0x3c,0x40,
+0x45,0x4a,0x4d,0x4c,0x4b,0x4a,0x48,0x46,0x46,0x45,0x45,0x44,0x44,0x43,0x44,0x45,
+0x78,0x65,0x55,0x2, 0xd, 0x14,0x1b,0x21,0x25,0x2b,0x31,0x37,0x36,0x33,0x2d,0x28,
+0x20,0x19,0x14,0xd, 0x8, 0x1, 0x2, 0x5, 0xb, 0x10,0x18,0x1e,0x23,0x2a,0x30,0x35,
+0x3a,0x3e,0x3f,0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x9, 0xf, 0x15,
+0x1d,0x24,0x2a,0x30,0x35,0x3b,0x3e,0x3f,0x40,0x3f,0x3e,0x3d,0x3d,0x3c,0x3c,0x3b,
+0x3b,0x39,0x37,0x1a,0x2d,0x65,0x55,0x35,0x2e,0x27,0x22,0x1f,0x1b,0x16,0x10,0xc,
+0x8, 0x6, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x6, 0xb, 0xe, 0x12,0x17,0x1d,0x22,
+0x26,0x2a,0x30,0x35,0x39,0x3d,0x3f,0x0, 0x0, 0x1, 0x4, 0x6, 0x8, 0xb, 0x10,0x16,
+0x1b,0x1f,0x23,0x28,0x2d,0x32,0x36,0x3b,0x40,0x44,0x48,0x4a,0x4b,0x4c,0x4b,0x4a,
+0x48,0x46,0x43,0x40,0x3e,0x3c,0x3a,0x3c,0x9c,0x34,0x55,0x9, 0x17,0x1d,0x26,0x2e,
+0x37,0x3c,0x3f,0x3b,0x33,0x2b,0x22,0x1a,0x11,0xb, 0x5, 0x3, 0x1, 0x1, 0x0, 0x0,
+0x0, 0x1, 0x6, 0xa, 0x11,0x19,0x22,0x2a,0x32,0x39,0x3d,0x30,0x30,0x2f,0x2c,0x26,
+0x1e,0x17,0xd, 0x5, 0x0, 0x0, 0x1, 0x6, 0xe, 0x15,0x1e,0x26,0x2c,0x32,0x3a,0x41,
+0x48,0x50,0x5b,0x61,0x64,0x64,0x60,0x5b,0x56,0x51,0x4f,0xd8,0x2c,0x33,0x55,0x0,
+0x7, 0x10,0x19,0x24,0x2c,0x2c,0x26,0x1e,0x15,0xb, 0x7, 0x3, 0x0, 0x0, 0x0, 0x2,
+0x9, 0x12,0x1a,0x23,0x27,0x2f,0x37,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x1c,
+0x1e,0x1e,0x1c,0x17,0xf, 0xb, 0x3, 0x0, 0x2, 0xa, 0xf, 0x18,0x20,0x29,0x32,0x36,
+0x3e,0x3f,0x3e,0x3b,0x3a,0x37,0x32,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0xd8,
+0x2c,0x33,0x55,0x1, 0xa, 0x13,0x1c,0x24,0x2c,0x2f,0x2f,0x2c,0x23,0x1a,0x10,0xb,
+0x3, 0x0, 0x0, 0x1, 0x6, 0xb, 0x14,0x1f,0x29,0x34,0x3c,0x3f,0x3f,0x3f,0x3f,0x3f,
+0x3f,0x3f,0x3f,0x28,0x29,0x29,0x28,0x24,0x1b,0x17,0xd, 0x5, 0x0, 0x2, 0x9, 0xf,
+0x19,0x23,0x2d,0x36,0x40,0x43,0x45,0x44,0x42,0x3e,0x3a,0x38,0x38,0x38,0x38,0x38,
+0x38,0x38,0x38,0xd8,0x2c,0x33,0x55,0xd, 0x13,0x1d,0x27,0x2e,0x30,0x2e,0x27,0x1e,
+0x19,0xf, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x8, 0xd, 0x17,0x21,0x2a,0x2f,0x38,0x3f,
+0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1b,0x1c,0x1d,0x1a,0x15,0x11,0x9, 0x2, 0x0,
+0x0, 0x4, 0xd, 0x16,0x1e,0x22,0x2b,0x33,0x3c,0x3e,0x3f,0x3d,0x3a,0x38,0x34,0x30,
+0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xd8,0x2c,0x33,0x55,0x5, 0xb, 0x14,0x1d,0x21,
+0x26,0x26,0x25,0x1e,0x16,0x11,0x9, 0x4, 0x2, 0x0, 0x0, 0x0, 0x4, 0xd, 0x13,0x1d,
+0x25,0x2a,0x34,0x3e,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x1e,0x1f,0x1f,0x1e,0x1b,
+0x13,0xa, 0x6, 0x0, 0x0, 0x3, 0xb, 0x15,0x1a,0x22,0x2b,0x2f,0x38,0x3e,0x3f,0x3e,
+0x3c,0x3b,0x37,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0xd8,0x2c,0x33,0x55,0x0,
+0x8, 0x11,0x1a,0x1e,0x26,0x2c,0x2d,0x29,0x1f,0x1a,0x11,0x9, 0x6, 0x3, 0x1, 0x1,
+0x4, 0xc, 0x11,0x1c,0x26,0x2b,0x34,0x3e,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x20,
+0x22,0x22,0x20,0x1e,0x19,0x11,0xd, 0x3, 0x0, 0x0, 0x6, 0x10,0x15,0x1e,0x2a,0x2f,
+0x37,0x3d,0x3e,0x3f,0x3e,0x3c,0x3a,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xd8,
+0x2c,0x33,0x55,0x2, 0x8, 0x11,0x1a,0x1f,0x26,0x27,0x24,0x20,0x17,0xe, 0x6, 0x3,
+0x0, 0x0, 0x0, 0x1, 0x5, 0xd, 0x17,0x1c,0x25,0x2f,0x38,0x3d,0x3f,0x3f,0x3f,0x3f,
+0x3f,0x3f,0x3f,0x20,0x21,0x20,0x1e,0x1b,0x14,0xc, 0x3, 0x0, 0x0, 0x4, 0xb, 0x10,
+0x18,0x21,0x2a,0x2e,0x36,0x3e,0x3f,0x3f,0x3c,0x39,0x34,0x30,0x2f,0x2f,0x2f,0x2f,
+0x2f,0x2f,0x2f,0xd8,0x2c,0x33,0x55,0x9, 0x7, 0x6, 0x6, 0x5, 0x5, 0x4, 0x4, 0x4,
+0x4, 0x3, 0x2, 0x2, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa, 0x10,0x14,0x1b,
+0x22,0x28,0x2e,0x34,0x39,0x3d,0x40,0x0, 0xb, 0x11,0x16,0x1b,0x22,0x28,0x2c,0x33,
+0x39,0x40,0x46,0x4d,0x52,0x56,0x5c,0x61,0x68,0x6d,0x73,0x73,0x71,0x71,0x71,0x70,
+0x70,0x6f,0x6f,0x6f,0x6f,0x6d,0x6e,0x79,0x80,0x44,0x55,0x17,0x13,0x12,0x12,0x11,
+0x10,0xf, 0xd, 0xc, 0xb, 0x9, 0x8, 0x7, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x1,
+0x4, 0xb, 0x10,0x16,0x1d,0x24,0x29,0x31,0x39,0x3d,0x40,0x0, 0xe, 0x16,0x1a,0x1f,
+0x24,0x29,0x2e,0x33,0x38,0x3e,0x43,0x47,0x50,0x55,0x59,0x62,0x69,0x6e,0x75,0x7c,
+0xff,0x7d,0x7c,0x79,0x73,0x6d,0x68,0x60,0x5a,0x57,0x56,0x5d,0x8, 0x44,0x55,0x0,
+0x7, 0xb, 0xd, 0x10,0x12,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x19,0x1c,0x1e,0x20,
+0x22,0x23,0x25,0x27,0x29,0x2b,0x30,0x32,0x33,0x35,0x38,0x39,0x3b,0x3d,0x3f,0x3e,
+0x29,0x1f,0x18,0xf, 0x7, 0x6, 0xc, 0x12,0x1d,0x25,0x2d,0x36,0x3e,0x3b,0x35,0x2c,
+0x26,0x20,0x19,0x11,0xa, 0x3, 0x3, 0x9, 0x10,0x18,0x24,0x2c,0x33,0x3a,0x3e,0x60,
+0x9b,0x32,0x55,0x0, 0x5, 0x5, 0x5, 0x4, 0x3, 0x2, 0x3, 0x5, 0x7, 0xa, 0xe, 0x11,
+0x19,0x1b,0x1c,0x1d,0x1c,0x1c,0x1d,0x1f,0x22,0x25,0x2a,0x31,0x33,0x35,0x37,0x38,
+0x39,0x3c,0x40,0x0, 0x12,0x1c,0x24,0x2b,0x34,0x3c,0x39,0x2f,0x29,0x21,0x16,0xf,
+0xd, 0x14,0x1e,0x2a,0x33,0x31,0x27,0x20,0x18,0x10,0x7, 0xa, 0x10,0x1a,0x26,0x2f,
+0x37,0x3d,0x3f,0xfb,0x8f,0x32,0x55,0x2c,0x23,0x1f,0x19,0x13,0xc, 0x7, 0x3, 0x0,
+0x0, 0x0, 0x1, 0x5, 0xa, 0xf, 0x16,0x1d,0x23,0x2a,0x30,0x36,0x3b,0x3e,0x40,0x3f,
+0x3e,0x3b,0x38,0x33,0x2f,0x2b,0x28,0x9, 0x1, 0x0, 0x1, 0x3, 0x9, 0xe, 0x14,0x1b,
+0x21,0x27,0x2e,0x36,0x3b,0x3e,0x41,0x41,0x40,0x3d,0x3a,0x36,0x2f,0x2b,0x26,0x20,
+0x1c,0x16,0x10,0xc, 0xa, 0x9, 0xb, 0x36,0xdc,0x30,0x55,0x1a,0x9, 0x5, 0x1, 0x0,
+0x0, 0x0, 0x2, 0x5, 0x9, 0xf, 0x16,0x1c,0x22,0x2a,0x31,0x36,0x39,0x3c,0x3e,0x3f,
+0x3f,0x3d,0x38,0x30,0x27,0x1f,0x18,0x12,0xb, 0x6, 0x5, 0x7, 0x12,0x19,0x22,0x2c,
+0x36,0x3f,0x49,0x53,0x5c,0x63,0x66,0x64,0x5f,0x58,0x4c,0x43,0x3d,0x34,0x2b,0x22,
+0x1b,0x15,0xb, 0x4, 0x0, 0x0, 0x1, 0x4, 0xb, 0x13,0x18,0xf1,0xc, 0x30,0x55,0x18,
+0x2c,0x34,0x39,0x3c,0x3d,0x3f,0x3f,0x3f,0x3d,0x3b,0x36,0x30,0x2a,0x24,0x1c,0x16,
+0xd, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x5, 0x9, 0xf, 0x17,0x1e,0x24,0x1,
+0x2, 0x8, 0xe, 0x14,0x1a,0x21,0x28,0x30,0x37,0x40,0x49,0x50,0x55,0x59,0x5c,0x5c,
+0x58,0x51,0x48,0x3f,0x38,0x31,0x2b,0x25,0x1d,0x17,0x11,0xa, 0x4, 0x1, 0x1, 0x9d,
+0xbf,0x30,0x55,0x16,0x7, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x8, 0xe, 0x16,0x1f,
+0x28,0x30,0x38,0x3c,0x3e,0x3f,0x40,0x3f,0x3f,0x3d,0x3b,0x37,0x32,0x2c,0x25,0x1d,
+0x16,0xf, 0xc, 0x53,0x46,0x3e,0x35,0x2e,0x27,0x20,0x1a,0x14,0xd, 0x6, 0x1, 0x0,
+0x0, 0x3, 0xa, 0x13,0x1a,0x20,0x27,0x2d,0x33,0x3a,0x40,0x48,0x4f,0x54,0x58,0x5a,
+0x5a,0x58,0x57,0xc6,0x55,0x30,0x55,0x7, 0x1, 0x4, 0xa, 0x10,0x18,0x20,0x2a,0x32,
+0x38,0x3c,0x3e,0x3f,0x3e,0x3d,0x3b,0x39,0x35,0x30,0x27,0x21,0x19,0x12,0xb, 0x6,
+0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x1d,0x12,0x9, 0x5, 0x1, 0x0, 0x0, 0x1,
+0x5, 0xd, 0x17,0x20,0x2a,0x32,0x3b,0x45,0x4e,0x58,0x63,0x69,0x6b,0x6a,0x64,0x5d,
+0x57,0x4f,0x47,0x40,0x38,0x32,0x2f,0x1a,0xb5,0x30,0x55,0x21,0x13,0xc, 0x8, 0x5,
+0x2, 0x1, 0x0, 0x0, 0x1, 0x3, 0x8, 0xf, 0x17,0x1e,0x24,0x2b,0x32,0x39,0x3d,0x3e,
+0x3f,0x3f,0x3d,0x3a,0x36,0x30,0x29,0x21,0x1a,0x16,0x13,0x5, 0x9, 0xe, 0x14,0x1a,
+0x22,0x29,0x30,0x38,0x3f,0x47,0x4d,0x51,0x51,0x4f,0x4d,0x49,0x42,0x39,0x31,0x2b,
+0x25,0x1e,0x17,0x10,0x8, 0x3, 0x0, 0x0, 0x1, 0x3, 0x5, 0xaf,0x13,0x30,0x55,0x38,
+0x3f,0x3d,0x3a,0x36,0x2e,0x26,0x1f,0x14,0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2,
+0x5, 0x9, 0xe, 0x14,0x1c,0x23,0x2a,0x34,0x38,0x3a,0x3b,0x3d,0x3d,0x3d,0x3d,0x29,
+0x1a,0x10,0x9, 0x4, 0x0, 0x0, 0x1, 0x4, 0xc, 0x14,0x1c,0x22,0x28,0x2f,0x37,0x3f,
+0x47,0x4f,0x56,0x5a,0x5b,0x59,0x56,0x4e,0x47,0x40,0x37,0x30,0x28,0x22,0x1f,0x2a,
+0xa9,0x30,0x55,0x3e,0x3b,0x38,0x33,0x2b,0x24,0x1d,0x16,0x10,0x7, 0x3, 0x1, 0x0,
+0x0, 0x0, 0x1, 0x1, 0x3, 0x6, 0xc, 0x15,0x1c,0x23,0x29,0x2f,0x35,0x38,0x3b,0x3c,
+0x3e,0x3f,0x3f,0x1f,0x10,0xa, 0x6, 0x0, 0x0, 0x0, 0x2, 0x4, 0xc, 0x12,0x18,0x1e,
+0x25,0x2c,0x35,0x3c,0x42,0x4a,0x51,0x56,0x56,0x53,0x4e,0x49,0x40,0x3a,0x33,0x2c,
+0x25,0x1f,0x1c,0xf9,0xa2,0x30,0x55,0x1f,0x2b,0x31,0x35,0x38,0x3b,0x3e,0x3f,0x3f,
+0x3d,0x3a,0x34,0x2d,0x27,0x23,0x1d,0x17,0x10,0x9, 0x4, 0x1, 0x0, 0x0, 0x1, 0x3,
+0x6, 0xa, 0xf, 0x15,0x1b,0x20,0x23,0x45,0x42,0x3e,0x38,0x34,0x2d,0x24,0x1c,0x15,
+0x11,0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0xd, 0x12,0x18,0x20,0x28,0x30,
+0x36,0x3c,0x42,0x47,0x48,0x49,0x4a,0x65,0x9d,0x30,0x55,0x1c,0x2a,0x33,0x39,0x3c,
+0x3e,0x3f,0x3f,0x3e,0x3d,0x3a,0x35,0x2e,0x28,0x23,0x1c,0x15,0xf, 0x9, 0x4, 0x1,
+0x0, 0x0, 0x1, 0x1, 0x4, 0x8, 0xd, 0x13,0x19,0x1e,0x22,0x40,0x3e,0x3a,0x33,0x2f,
+0x29,0x22,0x1b,0x15,0x10,0xa, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x5, 0xa, 0x11,0x17,
+0x1c,0x24,0x2a,0x30,0x35,0x3b,0x40,0x43,0x44,0x45,0x45,0xcb,0xc6,0x30,0x55,0x5,
+0x3, 0x4, 0x7, 0xa, 0x10,0x17,0x21,0x28,0x2e,0x33,0x38,0x3c,0x3e,0x3f,0x3f,0x3e,
+0x3b,0x38,0x31,0x29,0x21,0x18,0xf, 0x9, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26,
+0x35,0x3d,0x45,0x4b,0x51,0x53,0x52,0x4f,0x4c,0x46,0x41,0x3b,0x34,0x2e,0x25,0x1e,
+0x17,0x11,0x9, 0x3, 0x0, 0x0, 0x2, 0x6, 0xc, 0x12,0x18,0x1e,0x24,0x2c,0x31,0xf4,
+0xb6,0x30,0x55,0xa, 0x5, 0x5, 0x5, 0x8, 0xf, 0x16,0x20,0x29,0x31,0x36,0x3a,0x3c,
+0x3e,0x3f,0x3f,0x3e,0x3c,0x3a,0x33,0x2d,0x24,0x1c,0x14,0xf, 0x8, 0x4, 0x0, 0x0,
+0x0, 0x1, 0x2, 0x35,0x46,0x4e,0x56,0x5d,0x65,0x68,0x66,0x60,0x57,0x4f,0x47,0x3f,
+0x37,0x2e,0x25,0x1e,0x16,0x10,0x6, 0x2, 0x0, 0x1, 0x5, 0xb, 0x15,0x1d,0x28,0x2f,
+0x39,0x41,0x45,0xf0,0xbc,0x30,0x55,0x7, 0x3, 0x3, 0x3, 0x4, 0x7, 0xf, 0x17,0x20,
+0x28,0x30,0x36,0x3b,0x3d,0x3f,0x3f,0x3d,0x39,0x36,0x2d,0x25,0x1d,0x16,0xd, 0x8,
+0x2, 0x0, 0x0, 0x1, 0x2, 0x3, 0x5, 0x2e,0x3f,0x48,0x50,0x59,0x5f,0x67,0x68,0x63,
+0x5d,0x52,0x4a,0x3e,0x35,0x2b,0x20,0x18,0x10,0xa, 0x3, 0x0, 0x0, 0x1, 0x7, 0xe,
+0x19,0x22,0x2b,0x31,0x3a,0x42,0x47,0xef,0xc9,0x30,0x55,0x3b,0x3c,0x3c,0x3b,0x39,
+0x36,0x2f,0x27,0x21,0x19,0x11,0xb, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x4, 0x6, 0xa,
+0x10,0x16,0x1f,0x26,0x2d,0x33,0x39,0x3c,0x3e,0x3f,0x3f,0x22,0x31,0x3b,0x41,0x47,
+0x4d,0x56,0x59,0x5a,0x58,0x55,0x51,0x4b,0x43,0x3d,0x35,0x29,0x20,0x18,0x11,0x9,
+0x3, 0x0, 0x0, 0x1, 0x3, 0x7, 0xf, 0x15,0x1b,0x21,0x26,0x2b,0xa0,0x30,0x55,0x37,
+0x38,0x37,0x34,0x2d,0x26,0x1c,0x16,0xe, 0x9, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2,
+0x5, 0xa, 0x10,0x17,0x20,0x26,0x2e,0x35,0x3a,0x3c,0x3e,0x3f,0x3f,0x3e,0x3e,0x30,
+0x40,0x49,0x50,0x59,0x5e,0x60,0x5d,0x56,0x50,0x47,0x41,0x39,0x33,0x2a,0x20,0x1a,
+0x10,0xa, 0x5, 0x1, 0x0, 0x0, 0x3, 0x8, 0x10,0x17,0x1f,0x25,0x2f,0x38,0x3c,0x37,
+0xc3,0x30,0x55,0x3b,0x3d,0x3d,0x3b,0x38,0x32,0x27,0x1c,0x13,0xe, 0x8, 0x3, 0x0,
+0x0, 0x0, 0x1, 0x3, 0x7, 0xb, 0x12,0x18,0x20,0x28,0x31,0x39,0x3d,0x3f,0x40,0x3f,
+0x3f,0x3e,0x3e,0x33,0x45,0x4e,0x57,0x5d,0x65,0x6c,0x6a,0x66,0x63,0x5c,0x53,0x4a,
+0x40,0x38,0x2e,0x25,0x1a,0x11,0x8, 0x4, 0x0, 0x0, 0x2, 0x9, 0x10,0x19,0x21,0x2a,
+0x32,0x39,0x3e,0x7, 0x90,0x30,0x55,0x39,0x2b,0x24,0x1c,0x15,0xe, 0x9, 0x6, 0x5,
+0x6, 0x9, 0x10,0x19,0x22,0x27,0x2e,0x35,0x3b,0x3e,0x3f,0x3d,0x38,0x32,0x2c,0x26,
+0x1f,0x19,0x13,0xb, 0x5, 0x1, 0x0, 0x6, 0x0, 0x1, 0x2, 0x6, 0xb, 0x11,0x17,0x1d,
+0x24,0x2a,0x2f,0x32,0x34,0x35,0x36,0x37,0x3b,0x41,0x47,0x4e,0x56,0x5d,0x61,0x64,
+0x65,0x65,0x63,0x60,0x5c,0x57,0x54,0xd1,0x4a,0x46,0x55,0x0, 0x1, 0x3, 0x5, 0x7,
+0x8, 0xa, 0xb, 0xc, 0xe, 0xf, 0x11,0x12,0x14,0x16,0x1a,0x1e,0x22,0x24,0x27,0x2a,
+0x2c,0x2e,0x31,0x33,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x3f,0x1, 0xe, 0x14,0x1b,0x23,
+0x28,0x2e,0x35,0x3a,0x40,0x48,0x4f,0x56,0x5d,0x62,0x61,0x5a,0x53,0x4e,0x47,0x40,
+0x3b,0x35,0x2d,0x29,0x22,0x1b,0x17,0x10,0x9, 0x5, 0x1, 0x6d,0x7d,0x54,0x55,0x0,
+0x2, 0x3, 0x5, 0x6, 0x8, 0xb, 0x10,0x13,0x16,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x22,
+0x22,0x22,0x22,0x23,0x25,0x28,0x2e,0x31,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x6,
+0x17,0x20,0x27,0x30,0x38,0x3e,0x39,0x32,0x2b,0x25,0x1e,0x18,0x10,0x9, 0x9, 0x10,
+0x18,0x1f,0x26,0x2f,0x36,0x3c,0x38,0x2f,0x27,0x1f,0x18,0xf, 0x8, 0x1, 0x2, 0xc7,
+0x75,0x31,0x55,0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x8, 0xd, 0x12,0x15,0x17,0x18,
+0x1a,0x1b,0x1c,0x1d,0x1d,0x1e,0x1f,0x22,0x27,0x2e,0x35,0x38,0x3b,0x3d,0x3e,0x3f,
+0x40,0x3f,0x3e,0x6, 0x15,0x1b,0x23,0x29,0x2f,0x37,0x3c,0x37,0x2e,0x27,0x20,0x1a,
+0x13,0xe, 0x14,0x1a,0x21,0x27,0x2f,0x38,0x3f,0x3d,0x35,0x2e,0x26,0x20,0x18,0x11,
+0xb, 0x3, 0x0, 0x67,0x3f,0x31,0x55,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,0xc2,0xd5,0x7c,0xb0,0x30,0xe7,0x8, 0xb2,0xd5,0x9f,
+0x22,0x9f,0x20,0x7f,0x2, 0x7c,0xb4,0x30,0xe7,0x13,0xb2,0xd5,0x9f,0x22,0x9f,0x21,
+0x7f,0x12,0x12,0x27,0x15,0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x80,0x3, 0x12,0x27,0x15,
+0x30,0xd5,0x6, 0x9f,0x22,0x9f,0x21,0x7f,0x12,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,0x6c,0xaa,0x4d,0x11,0x68,
+0x1e,0x1e,0x54,0x50,0xc, 0x7e,0x1b,0x0, 0x7a,0x19,0x0, 0x68,0x12,0xb, 0x1c,0xb,
+0x14,0xb, 0x1a,0x0, 0x1b,0x18,0x0, 0xb, 0x1d,0xb, 0x15,0x1b,0x54,0x78,0xf2,0x22,
+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,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,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,0x0, 0x1, 0x1, 0xb, 0x1f,0x24,
+0xc, 0x1f,0x24,0x75,0x84,0x1, 0x7e,0x44,0x47,0xef,0xe4,0x7a,0x49,0xb0,0x1b,0x44,
+0x78,0xf9,0x7e,0xf8,0x40,0x45,0x75,0xc, 0x0, 0x75,0xd, 0x0, 0x75,0xe, 0x2, 0x75,
+0xf, 0x0, 0xc2,0x6, 0xc2,0x7, 0x75,0x1c,0x0, 0xc2,0xc, 0x75,0x18,0x47,0x75,0x19,
+0xf0,0xc2,0xd, 0xc2,0xf, 0xc2,0x11,0xc2,0x12,0x75,0x1d,0x0, 0xc2,0x13,0x75,0x1e,
+0x0, 0xc2,0x14,0xc2,0x15,0xc2,0x8, 0x75,0x1f,0x64,0xc2,0x16,0xc2,0x17,0x75,0x64,
+0x0, 0xd2,0x0, 0xd2,0x1, 0xd2,0x2, 0xc2,0xa, 0xd2,0xb, 0xd2,0x19,0x7e,0x4, 0x0,
+0xff,0x7e,0x14,0x29,0xc4,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, 0x2c,0x6d,0x0, 0x0, 0x0, 0x47,0x0, 0xcb,0x1,
+0x0, 0x0, 0x10,0xfd,0xc7,0xfb,0x7e,0xfb,0xfb,0x1, 0xbb,0xc, 0x9e,0x19,0x0, 0x21,
+0x45,0x7, 0x46,0x15,0x97,0x22,0x68,0x22,0x68,0x15,0x97,0x7, 0x46,0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 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,0xca,0xf8,0x7f,
+0x20,0x80,0xa, 0x7e,0x1b,0xf0,0x7a,0x2b,0xf0,0xb, 0x34,0xb, 0x54,0x69,0xff,0xff,
+0xfc,0x7d,0xef,0x1b,0xe4,0x79,0xef,0xff,0xfc,0x4d,0xff,0x78,0xe6,0x7f,0x10,0xda,
+0xf8,0x22,0x7d,0x43,0x7f,0x10,0x80,0x7, 0x1b,0x44,0x7a,0xb, 0xb0,0xb, 0x14,0x4d,
+0x44,0x78,0xf5,0x22,0x5, 0x63,0x31,0x20,0x18,0x13,0xf, 0xd, 0xc, 0xa, 0x9, 0x8,
+0x7, 0x6, 0x5, 0x4, 0x32,0x1, 0x19,0x1, 0x0, 0x2, 0xf8,0x4, 0xe7,0x5, 0xce,0x6,
+0xc2,0x7, 0xb5,0x8, 0xff,0x0, 0x1, 0x2, 0x0, 0xff,0x1, 0x2, 0x0, 0x1, 0xff,0x2,
+0x0, 0x1, 0x2, 0xff,0x7d,0x23,0xbe,0x24,0x0, 0x0, 0x48,0x3, 0x7d,0x32,0x22,0x6d,
+0x33,0x9d,0x32,0x22,0x0, 0x2, 0x2b,0xfe,0x0, 0x1, 0x0, 0x48,0x2c,0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2c,0x48,0x0, 0x0, 0x4, 0x30,0x4d,0x0,
+0x0, 0x0, 0x0, 0x0, 0x48,0x31,0x73,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x1, 0x40,0x41,0x1, 0x0, 0x1, 0x1f,0x67,0x1, 0x0, 0x2, 0x3f,0x72,0x0, 0x0, 0x0,
+0x2, 0x3f,0x74,0x0, 0x0, 0x0, 0x1, 0x3, 0x9d,0xff,0x0, 0x1, 0x40,0x42,0x0, 0x0,
+0x1, 0x40,0x43,0x0, 0x0, 0x1, 0x3, 0xff,0x0, 0x0, 0x2, 0x3b,0x77,0x0, 0x0, 0x0,
+0x1, 0x3b,0xa5,0x0, 0x0, 0x1, 0x3c,0x1e,0x0, 0x0, 0x1, 0x3c,0x1f,0x0, 0x0, 0x3c,
+0x3d,0x3d,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
+0x3e,0x2e,0x1, 0x0, 0x2, 0x3e,0x31,0x0, 0x0, 0x0, 0x1, 0x0, 0x65,0x0, 0x0, 0x1,
+0x0, 0x66,0x0, 0x0, 0x1, 0x0, 0x67,0x0, 0x0, 0x1, 0x3e,0x35,0x1, 0x0, 0x1, 0x40,
+0x44,0x0, 0x0, 0x6, 0x40,0x23,0x3f,0x1f,0x52,0x10,0x20,0x0, 0x0, 0x1, 0x40,0x29,
+0x22,0x0, 0x1, 0x40,0x2a,0x0, 0x0, 0x1, 0x40,0x2b,0x0, 0x0, 0x1, 0x40,0x2c,0x0,
+0x0, 0x1, 0x40,0x2d,0x0, 0x0, 0x1, 0x40,0x2e,0x0, 0x0, 0x1, 0x40,0x2f,0x0, 0x0,
+0x1, 0x2, 0x89,0x0, 0x0, 0x1, 0x2, 0x8c,0x0, 0x0, 0x2, 0x2, 0xab,0x0, 0x0, 0x0,
+0x4, 0x3e,0xae,0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x40,0x30,0x0, 0x0, 0x1, 0x40,0x31,
+0x0, 0x0, 0x2, 0x40,0x32,0x0, 0x0, 0x0, 0x1, 0x40,0x34,0x64,0x0, 0x1, 0x40,0x35,
+0x0, 0x0, 0x1, 0x40,0x45,0x0, 0x0, 0x1, 0x40,0x3f,0x0, 0x0, 0x1, 0x40,0x40,0x0,
+0x0, 0x2, 0x37,0x5d,0x37,0x63,0x0, 0x1, 0x3b,0x23,0x2, 0x0, 0x1, 0x3b,0x4c,0x0,
+0x0, 0x1, 0x40,0x18,0x0, 0x0, 0x1, 0x3f,0x77,0xff,0x0, 0x1, 0x3f,0x78,0x0, 0x0,
+0x1, 0x3f,0x79,0x0, 0x0, 0x1, 0x3f,0x7a,0x40,0x0, 0x1, 0x3f,0x7b,0x40,0x0, 0x4,
+0x40,0x3b,0x0, 0x0, 0xb0,0x0, 0x0, 0x1, 0x3f,0xbc,0x1, 0x0, 0x1, 0x3f,0xbd,0x0,
+0x0, 0x4, 0x3f,0xbe,0x0, 0x0, 0xbc,0x0, 0x0, 0x4, 0x3f,0xc2,0x0, 0x0, 0xb8,0xc0,
+0x0, 0x4, 0x3f,0xc6,0x0, 0x0, 0xb8,0x0, 0x0, 0x4, 0x3f,0xca,0x4, 0x8, 0x10,0x6,
+0x0, 0x1, 0x3f,0xce,0x0, 0x0, 0x4, 0x3f,0xdf,0x0, 0x0, 0x80,0x0, 0x0, 0x4, 0x40,
+0xc, 0x0, 0x0, 0x80,0x0, 0x0, 0x4, 0x40,0x10,0x0, 0x0, 0x90,0x0, 0x0, 0x4, 0x40,
+0x14,0x0, 0x0, 0xb4,0x0, 0x0, 0x0, 0x3, 0xe8,0x0, 0xc, 0x1, 0xf4,0x3, 0x20,0x0,
+0xa, 0x1, 0x4a,0x2, 0xbc,0x0, 0x9, 0x0, 0xc8,0x1, 0xf4,0x0, 0x9, 0x0, 0xa0,0x1,
+0x2c,0x0, 0x8, 0x0, 0x64,0x0, 0x64,0x0, 0x6, 0x0, 0x3c,0x0, 0x50,0x0, 0x6, 0x0,
+0x0, 0x0, 0xd, 0x19,0x23,0x5, 0xdc,0x0, 0x32,0x3, 0xe8,0x0, 0x28,0x0, 0x0, 0x0,
+0x1e,0x7e,0x34,0xc, 0xff,0x7e,0x24,0x0, 0xff,0x7e,0x1b,0xb0,0xbe,0xb0,0xff,0x68,
+0x1b,0x7e,0x34,0x8, 0x0, 0x7e,0x24,0x0, 0xff,0x6d,0x11,0x7e,0x4, 0xff,0xff,0x1b,
+0x1a,0x0, 0xb, 0x14,0xb, 0x35,0xbe,0x14,0x2, 0x80,0x78,0xef,0x22,0x75,0x91,0xc0,
+0x12,0x2c,0x41,0x75,0x91,0xc1,0x75,0x91,0xc2,0x12,0x3f,0x94,0x75,0x91,0xc3,0x12,
+0x2c,0xa4,0x75,0x91,0xc4,0x12,0x71,0x5f,0x75,0x91,0xc5,0x12,0x2e,0x67,0x7e,0xb3,
+0x3, 0xc5,0x24,0xfd,0x68,0x9, 0xb, 0xb1,0x78,0xf4,0x12,0x4c,0x77,0x80,0xef,0x12,
+0x4c,0xf5,0x80,0xea,0x7e,0x54,0x0, 0x5e,0x7e,0x44,0x0, 0xff,0x69,0x32,0x0, 0x4,
+0x69,0x22,0x0, 0x2, 0xb, 0x2a,0x10,0x7a,0x1d,0x26,0x7a,0x15,0x24,0x7e,0x34,0x0,
+0x20,0x7e,0x8, 0x0, 0x24,0x7e,0x24,0x0, 0x6, 0x12,0xc3,0xf5,0x7e,0x34,0x61,0x5f,
+0x12,0x2d,0x68,0x1e,0x34,0x1e,0x34,0x7a,0x73,0x3, 0x9e,0x7e,0x34,0x61,0x61,0x12,
+0x2d,0x68,0xe, 0x34,0xe, 0x34,0x7a,0x73,0x3, 0x9f,0x7e,0x34,0x61,0x65,0x12,0x2d,
+0x68,0x12,0xf, 0xf5,0x7a,0x73,0x3, 0xa0,0x7e,0x34,0x61,0x69,0x12,0x2d,0x68,0x12,
+0xf, 0xf5,0x7a,0x73,0x3, 0xa1,0x7e,0x34,0x61,0x6b,0x12,0x2d,0x68,0x12,0xf, 0xf5,
+0x7a,0x73,0x3, 0xa2,0x7e,0x34,0x61,0x6d,0x12,0x2d,0x68,0x12,0xf, 0xf5,0x7a,0x73,
+0x3, 0xa3,0x7e,0x34,0x0, 0x59,0xca,0x39,0x7e,0x34,0x61,0x75,0x7e,0x24,0x0, 0xff,
+0x7e,0x8, 0x3, 0xa4,0x12,0x29,0x4d,0x1b,0xfd,0xe5,0x25,0x7a,0xb3,0x3, 0xcf,0xe5,
+0x28,0x7a,0xb3,0x3, 0xbe,0x22,0x7e,0x34,0x61,0x5f,0x7e,0x24,0x0, 0xff,0xb, 0x1a,
+0x30,0x7a,0x37,0x24,0x26,0x7e,0x34,0x61,0x61,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,
+0x7a,0x37,0x24,0x28,0x7e,0x34,0x61,0x63,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,0x22,
+0x7e,0x34,0x61,0x65,0x12,0x2d,0x68,0x7a,0x37,0x22,0x6, 0x7e,0x34,0x61,0xd0,0x12,
+0x2d,0x68,0x7a,0x37,0x22,0xa, 0x7e,0x34,0x61,0xce,0x12,0x2d,0x68,0x7a,0x37,0x22,
+0x8, 0x7e,0x34,0x62,0x28,0x12,0x2d,0x68,0x7a,0x37,0x22,0xc, 0x7e,0x34,0x61,0xd2,
+0x12,0x2d,0x68,0x7a,0x37,0x22,0xe, 0x7e,0x34,0x61,0xd4,0x12,0x2d,0x68,0x7a,0x37,
+0x22,0x10,0x7e,0x34,0x61,0xd6,0x12,0x2d,0x68,0x7a,0x37,0x22,0x12,0x7e,0x34,0x61,
+0xd8,0x12,0x2d,0x68,0x7a,0x37,0x22,0x14,0x90,0x61,0xda,0xe4,0x93,0x7a,0xb3,0x22,
+0x16,0xe4,0x7a,0xb3,0x22,0x19,0x12,0xb7,0x4f,0x7e,0x8, 0x1f,0x68,0xe4,0x2, 0x29,
+0x72,0x12,0x2e,0xfd,0x7e,0xb3,0x3e,0x40,0xb4,0x1, 0x16,0x7e,0x34,0x62,0x4a,0x12,
+0x2d,0x68,0x7a,0x37,0x24,0x26,0x7e,0x34,0x62,0x4c,0x12,0x2d,0x68,0x7a,0x37,0x24,
+0x28,0x7e,0xb3,0x22,0x19,0xb4,0x1, 0x37,0x7e,0x34,0x62,0x54,0x12,0x2d,0x68,0x7a,
+0x37,0x24,0x26,0x7e,0x34,0x62,0x56,0x12,0x2d,0x68,0x7a,0x37,0x24,0x28,0x7e,0x34,
+0x62,0x58,0x12,0x2d,0x68,0x7a,0x37,0x24,0x1b,0x7e,0x34,0x62,0x5a,0x12,0x2d,0x68,
+0x7a,0x37,0x24,0x1d,0x7e,0x34,0x62,0x5c,0x12,0x2d,0x68,0x7a,0x37,0x24,0x1f,0x7e,
+0xb3,0x23,0x87,0x70,0x21,0x7e,0x27,0x24,0x26,0x7d,0x32,0x7e,0x14,0x0, 0x4, 0xad,
+0x13,0x7d,0x31,0x12,0xf, 0xf5,0xbe,0x34,0x0, 0x50,0x28,0x4, 0x7e,0x34,0x0, 0x50,
+0x2d,0x32,0x7a,0x37,0x24,0x26,0x22,0x74,0x1, 0x7a,0xb3,0x3, 0xc5,0x12,0x35,0xec,
+0x12,0x4b,0x21,0x12,0x71,0xb6,0x12,0x3d,0x99,0x12,0xab,0x40,0x7e,0xb3,0x24,0xed,
+0x2, 0x44,0x2b,0x90,0x60,0xa1,0xe4,0x93,0x7a,0xb3,0x24,0x19,0x90,0x60,0xa6,0xe4,
+0x93,0x7a,0xb3,0x24,0x1a,0x7e,0x34,0x61,0x65,0x12,0x2d,0x68,0x12,0xd0,0xe7,0x12,
+0x2d,0x68,0x7a,0x37,0x24,0x1d,0x7e,0x14,0x61,0x6b,0x12,0x6f,0xe6,0x7a,0x27,0x24,
+0x1f,0x7a,0x37,0x24,0x21,0x90,0x60,0xa5,0xe4,0x93,0x7a,0xb3,0x24,0x25,0x12,0x2d,
+0x46,0x12,0xd0,0xdc,0x7e,0x34,0x62,0x28,0x12,0x2d,0x68,0x7a,0x37,0x24,0x2c,0x90,
+0x60,0xa7,0xe4,0x93,0x7a,0xb3,0x24,0x30,0x90,0x60,0xa8,0xe4,0x93,0x7a,0xb3,0x24,
+0x31,0x7e,0x34,0x60,0xa9,0x12,0x2d,0x68,0x7a,0x37,0x24,0x32,0x7e,0x34,0x61,0x6d,
+0x12,0x2d,0x68,0x7a,0x37,0x24,0x2e,0xe4,0x7a,0xb3,0x1f,0x5e,0x22,0x12,0x2d,0x46,
+0x12,0xd0,0xdc,0x7e,0x34,0x61,0x65,0x12,0x2d,0x68,0x12,0xd0,0xe7,0x12,0x2d,0x68,
+0x7a,0x37,0x24,0x1d,0x7e,0x34,0x61,0x6b,0x12,0x2d,0x68,0x7a,0x37,0x24,0x1f,0x22,
+0xca,0xf8,0x7e,0xf3,0x3f,0x25,0xbe,0xf0,0x5, 0x78,0x8, 0x12,0x0, 0x64,0x12,0x0,
+0x42,0x80,0x5e,0xbe,0xf0,0x4, 0x78,0x17,0x12,0x0, 0x64,0x7e,0x34,0x60,0xab,0x12,
+0x2d,0x68,0x12,0x48,0x8f,0xe4,0x7a,0xb3,0x24,0xde,0x12,0x5e,0x3c,0x80,0x42,0xbe,
+0xf0,0x6, 0x78,0x1d,0x12,0x0, 0x64,0x7e,0x34,0x60,0xab,0x12,0x2d,0x68,0x12,0x48,
+0x8f,0x12,0x58,0xbf,0xe4,0x7a,0xb3,0x24,0xfc,0x12,0x4b,0x4b,0x12,0xd1,0x3e,0x80,
+0x20,0xbe,0xf0,0x7, 0x78,0x21,0x12,0x0, 0x64,0x7e,0x34,0x60,0xab,0x12,0x2d,0x68,
+0x12,0x48,0x8f,0x12,0x4b,0x71,0x50,0xfb,0x12,0x88,0x19,0x12,0x4b,0x2a,0x12,0x3d,
+0x99,0x74,0x2, 0x7a,0xb3,0x3f,0x25,0xda,0xf8,0x22,0x7c,0x7b,0xbe,0x70,0x34,0x38,
+0x3, 0x2, 0x30,0x90,0xa5,0xbf,0x35,0x5, 0x7e,0xb3,0x24,0xee,0x22,0xbe,0x70,0x36,
+0x68,0x4, 0xa5,0xbf,0x37,0x19,0x7e,0x25,0x8, 0x7d,0x12,0xb, 0x14,0x7a,0x15,0x8,
+0x2e,0x27,0x30,0x4b,0x7e,0x29,0xb0,0xa5,0xbf,0x37,0x3, 0x75,0x1b,0x36,0x22,0xbe,
+0x70,0x38,0x68,0x4, 0xa5,0xbf,0x39,0x19,0x7e,0xa3,0x3f,0x45,0x7c,0xba,0x4, 0x7a,
+0xb3,0x3f,0x45,0xa5,0xbf,0x39,0x3, 0x75,0x1b,0x38,0xa, 0x3a,0x9, 0xb3,0x24,0xff,
+0x22,0xbe,0x70,0x3a,0x68,0x4, 0xa5,0xbf,0x3b,0x19,0x7e,0xa3,0x3f,0x47,0x7c,0xba,
+0x4, 0x7a,0xb3,0x3f,0x47,0xa5,0xbf,0x3b,0x3, 0x75,0x1b,0x3a,0xa, 0x3a,0x9, 0xb3,
+0x25,0x22,0x22,0xa5,0xbf,0xfb,0x5, 0x7e,0xb3,0x24,0xf0,0x22,0xa5,0xbf,0x5e,0x22,
+0x7e,0xf, 0x3f,0xbe,0x69,0x40,0x0, 0xa8,0xa, 0x38,0x12,0xf, 0xf7,0x5e,0x34,0x0,
+0x1, 0x7c,0xb7,0x3, 0x3, 0x54,0xc0,0xa, 0x38,0x5e,0x34,0x0, 0x3, 0x4c,0xb7,0x44,
+0x80,0x22,0xbe,0x70,0x3c,0x68,0x4, 0xa5,0xbf,0x3d,0x19,0x7e,0xa3,0x3f,0x49,0x7c,
+0xba,0x4, 0x7a,0xb3,0x3f,0x49,0xa5,0xbf,0x3d,0x3, 0x75,0x1b,0x3c,0xa, 0x3a,0x9,
+0xb3,0x24,0x46,0x22,0xbe,0x70,0x3e,0x68,0x4, 0xa5,0xbf,0x3f,0x19,0x7e,0xa3,0x3f,
+0x4b,0x7c,0xba,0x4, 0x7a,0xb3,0x3f,0x4b,0xa5,0xbf,0x3f,0x3, 0x75,0x1b,0x3e,0xa,
+0x3a,0x9, 0xb3,0x24,0x69,0x22,0xbe,0x70,0x40,0x40,0xc, 0xbe,0x70,0x4d,0x38,0x7,
+0xa, 0x37,0x9, 0xb3,0x3f,0x21,0x22,0xbe,0x70,0x4e,0x68,0x4, 0xa5,0xbf,0x4f,0x1c,
+0x7e,0xa3,0x3f,0x66,0x7c,0xba,0x4, 0x7a,0xb3,0x3f,0x66,0xa5,0xbf,0x4f,0x3, 0x75,
+0x1b,0x4e,0xa, 0x3a,0x2e,0x37,0x30,0x49,0x7e,0x39,0xb0,0x22,0xbe,0x70,0x51,0x68,
+0x4, 0xa5,0xbf,0x52,0x26,0x7e,0xf4,0x60,0x0, 0x6d,0xee,0x2e,0xe4,0x0, 0xff,0x7e,
+0xb3,0x3f,0x71,0xa, 0x1b,0x6d,0x0, 0x2f,0x7, 0x7e,0xb, 0x60,0x4, 0x7a,0xb3,0x3f,
+0x71,0xa5,0xbf,0x52,0x3, 0x75,0x1b,0x51,0x7c,0xb6,0x22,0xbe,0x70,0x60,0x40,0xc,
+0xbe,0x70,0x6c,0x38,0x7, 0xa, 0x37,0x9, 0xb3,0x3f,0x9e,0x22,0xa5,0xbf,0x5b,0x3,
+0xe5,0xe, 0x22,0xa5,0xbf,0x5a,0x7, 0x7e,0x37,0x2b,0xfe,0x7c,0xb7,0x22,0xbe,0x70,
+0x58,0x68,0x4, 0xa5,0xbf,0x59,0x20,0xa5,0xbf,0x59,0x5, 0x75,0x1b,0x58,0x80,0x5,
+0xe4,0x7a,0xb3,0x2c,0x48,0x7e,0x73,0x2c,0x48,0x7c,0xb7,0x4, 0x7a,0xb3,0x2c,0x48,
+0xa, 0x37,0x9, 0xb3,0x2c,0x0, 0x22,0xbe,0x70,0xf4,0x68,0x4, 0xa5,0xbf,0xf5,0x16,
+0x7e,0x25,0xa, 0x7d,0x12,0xb, 0x14,0x7a,0x15,0xa, 0x9, 0xb2,0x30,0x51,0xa5,0xbf,
+0xf5,0x3, 0x75,0x1b,0xf4,0x22,0xbe,0x70,0xf0,0x68,0x4, 0xa5,0xbf,0xf1,0x8, 0x7c,
+0x17,0x2e,0x10,0x20,0xa5,0xe7,0x22,0xbe,0x70,0xf2,0x68,0x4, 0xa5,0xbf,0xf3,0x1c,
+0x7e,0x25,0x10,0x3e,0x24,0x7e,0xf, 0x30,0x4d,0x2d,0x12,0xb, 0xa, 0x20,0xa5,0xbf,
+0xf2,0x5, 0xa, 0x34,0x7c,0xb7,0x22,0x7d,0x32,0x7c,0xb7,0x22,0xa5,0xbf,0xf6,0x3,
+0xe5,0xf, 0x22,0xa5,0xbf,0xf7,0xa, 0x7e,0x34,0x62,0x5e,0x12,0x2d,0x68,0x7c,0xb7,
+0x22,0xa5,0xbf,0xfd,0x2, 0xe4,0x22,0xe4,0x22,0x12,0x37,0xcd,0xb4,0x1, 0x14,0xca,
+0x39,0x7e,0x18,0x3f,0x61,0x7e,0x8, 0x1f,0x5f,0x12,0x29,0x4d,0x1b,0xfd,0x12,0x36,
+0x55,0x80,0x12,0xca,0x39,0x7e,0x18,0x3f,0x61,0x7e,0x8, 0x25,0x6c,0x12,0x29,0x4d,
+0x1b,0xfd,0x12,0x36,0x5e,0x2, 0x31,0xd8,0x7a,0x1f,0x24,0xd8,0x7a,0xf, 0x24,0xd4,
+0x22,0xca,0xf8,0x7c,0x6b,0xa5,0xbe,0x0, 0x9, 0x7c,0xb7,0x12,0x7b,0xb1,0xd2,0x6,
+0x81,0x73,0xa5,0xbe,0x1, 0x3d,0x7a,0x73,0x3f,0x22,0xa5,0xbf,0xad,0x2, 0x80,0x2f,
+0xa5,0xbf,0xae,0x4, 0xd2,0x7, 0x81,0x73,0xa5,0xbf,0xaa,0x5, 0x12,0xd1,0x35,0x80,
+0x1e,0xa5,0xbf,0xab,0xa, 0x7e,0x34,0x5, 0x92,0x7a,0x37,0x30,0x4b,0x80,0x10,0xa5,
+0xbf,0xac,0x2, 0x80,0x2, 0x81,0x73,0x7e,0x34,0x5, 0xc, 0x7a,0x37,0x30,0x4b,0x6d,
+0x33,0x41,0xb9,0xbe,0x60,0x4, 0x40,0x22,0xbe,0x60,0x8, 0x38,0x1d,0xd2,0x6, 0x12,
+0x34,0x76,0xa5,0xbe,0x7, 0x7, 0x6d,0x33,0x7a,0x35,0xa, 0x81,0x73,0xa5,0xbe,0x8,
+0x2, 0x80,0x2, 0x81,0x73,0x12,0x0, 0x28,0x81,0x73,0xa5,0xbe,0xa, 0x9, 0x43,0xc,
+0x20,0x7a,0x73,0x3f,0x2b,0x81,0x73,0xa5,0xbe,0xb, 0xa, 0xd2,0x6, 0x12,0x34,0x76,
+0x12,0x0, 0x46,0x81,0x73,0xbe,0x60,0x1b,0x40,0x7, 0xbe,0x60,0x1c,0x38,0x2, 0x61,
+0xd5,0xbe,0x60,0x1e,0x40,0xd, 0xbe,0x60,0x23,0x38,0x8, 0x12,0x34,0x76,0x43,0xc,
+0x40,0x81,0x73,0xbe,0x60,0x24,0x40,0x7, 0xbe,0x60,0x2c,0x38,0x2, 0x61,0xd5,0xa5,
+0xbe,0x2d,0x1b,0x12,0x34,0x76,0x20,0x7, 0x2, 0x81,0x73,0x7e,0x63,0x3f,0x4d,0x7c,
+0x46,0x6c,0x55,0xa, 0x37,0x2d,0x32,0x3e,0x34,0x7a,0x35,0x8, 0x81,0x73,0xbe,0x60,
+0x2f,0x40,0xa, 0xbe,0x60,0x33,0x38,0x5, 0x43,0xc, 0x8, 0x61,0xd5,0xa5,0xbe,0x34,
+0xf, 0x43,0xc, 0x10,0xbe,0x70,0x64,0x38,0x2, 0x61,0xd5,0x7e,0x70,0x64,0x61,0xd5,
+0xbe,0x60,0x38,0x68,0x4, 0xa5,0xbe,0x39,0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x3f,0x46,
+0x7c,0xbf,0x4, 0x7a,0xb3,0x3f,0x46,0xa, 0x2f,0x19,0x72,0x24,0xff,0xa5,0xbe,0x39,
+0x2, 0x80,0x2, 0x81,0x73,0x75,0x1b,0x38,0x81,0x73,0xbe,0x60,0x3a,0x68,0x4, 0xa5,
+0xbe,0x3b,0x21,0x43,0xc, 0x2, 0x7e,0xf3,0x3f,0x48,0x7c,0xbf,0x4, 0x7a,0xb3,0x3f,
+0x48,0xa, 0x2f,0x19,0x72,0x25,0x22,0xa5,0xbe,0x3b,0x2, 0x80,0x2, 0x81,0x73,0x75,
+0x1b,0x3a,0x81,0x73,0xa5,0xbe,0xfb,0x9, 0x43,0xc, 0x4, 0x7a,0x73,0x24,0xf0,0x81,
+0x73,0xa5,0xbe,0x50,0x6, 0x7a,0x73,0x3f,0x71,0x81,0x73,0xbe,0x60,0x3c,0x68,0x4,
+0xa5,0xbe,0x3d,0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x3f,0x4a,0x7c,0xbf,0x4, 0x7a,0xb3,
+0x3f,0x4a,0xa, 0x2f,0x19,0x72,0x24,0x46,0xa5,0xbe,0x3d,0x2, 0x80,0x2, 0x81,0x73,
+0x75,0x1b,0x3c,0x81,0x73,0xbe,0x60,0x3e,0x68,0x4, 0xa5,0xbe,0x3f,0x21,0x43,0xc,
+0x1, 0x7e,0xf3,0x3f,0x4c,0x7c,0xbf,0x4, 0x7a,0xb3,0x3f,0x4c,0xa, 0x2f,0x19,0x72,
+0x24,0x69,0xa5,0xbe,0x3f,0x2, 0x80,0x2, 0x81,0x73,0x75,0x1b,0x3e,0x81,0x73,0xbe,
+0x60,0x40,0x40,0xd, 0xbe,0x60,0x42,0x38,0x8, 0x12,0x34,0x76,0x75,0xd, 0x1, 0x80,
+0xa, 0xa5,0xbe,0x43,0xb, 0x12,0x34,0x76,0x75,0xd, 0x2, 0x12,0x31,0xa9,0x81,0x73,
+0xa5,0xbe,0x44,0x8, 0x12,0x34,0x76,0x12,0x36,0x1b,0x81,0x73,0xbe,0x60,0x45,0x68,
+0x4, 0xa5,0xbe,0x46,0x5, 0x12,0x34,0x76,0x81,0x73,0xbe,0x60,0x4e,0x68,0x4, 0xa5,
+0xbe,0x4f,0x20,0x43,0xd, 0x4, 0x7e,0xf3,0x3f,0x67,0x7c,0xbf,0x4, 0x7a,0xb3,0x3f,
+0x67,0xa, 0x2f,0x2e,0x27,0x30,0x49,0x7a,0x29,0x70,0xa5,0xbe,0x4f,0x75,0x75,0x1b,
+0x4e,0x80,0x70,0xa5,0xbe,0x5b,0x5, 0x7a,0x71,0xe, 0x80,0x67,0xbe,0x60,0x58,0x68,
+0x4, 0xa5,0xbe,0x59,0x21,0xa5,0xbe,0x59,0x5, 0x75,0x1b,0x58,0x80,0x5, 0xe4,0x7a,
+0xb3,0x2c,0x48,0x7e,0x63,0x2c,0x48,0x7c,0xb6,0x4, 0x7a,0xb3,0x2c,0x48,0xa, 0x26,
+0x19,0x72,0x2c,0x0, 0x80,0x3d,0xa5,0xbe,0x5a,0x8, 0xa, 0x37,0x7a,0x37,0x2b,0xfe,
+0x80,0x31,0xbe,0x60,0xf0,0x40,0x25,0xbe,0x60,0xf3,0x38,0x20,0x7c,0x16,0x2e,0x10,
+0x20,0x7c,0xb7,0xa5,0xf7,0xa5,0xbe,0xf3,0x1a,0x7e,0x15,0x12,0x7e,0x5, 0x10,0x3e,
+0x4, 0x7e,0x1f,0x30,0x4d,0x2d,0x30,0x1b,0x1a,0x10,0x80,0x7, 0xa5,0xbe,0xf6,0x3,
+0x7a,0x71,0xf, 0xda,0xf8,0x22,0xa, 0x26,0x19,0x72,0x3f,0x21,0x22,0x7a,0xb3,0x24,
+0xdc,0x70,0x14,0x12,0x36,0x5e,0x12,0x31,0xd8,0x7e,0x18,0x6, 0x9e,0x7a,0x1f,0x7,
+0x24,0x7e,0x18,0x4, 0x86,0x80,0x10,0xb4,0x1, 0x11,0x12,0x36,0x55,0x12,0x31,0xd8,
+0x12,0xd0,0xac,0x7e,0x18,0x4, 0x0, 0x7a,0x1f,0x7, 0x28,0x22,0x74,0x1, 0x12,0x0,
+0x6, 0xe4,0x12,0x34,0x7d,0x12,0x34,0xc4,0xe4,0x12,0x0, 0x6, 0x74,0x1, 0x12,0x34,
+0x7d,0x2, 0x34,0xc4,0xca,0x3b,0x7e,0xb3,0x24,0x3f,0xf5,0x26,0x7e,0xd3,0x24,0x40,
+0x7e,0x8, 0x31,0xcb,0x7e,0x34,0x0, 0x90,0x74,0x3f,0x12,0x29,0x72,0x7e,0x8, 0x32,
+0x5b,0x7e,0x34,0x0, 0x48,0x12,0x29,0x72,0x7e,0x8, 0x32,0xa3,0x12,0xd0,0xf8,0x7e,
+0x8, 0x32,0xaf,0x7e,0x34,0x0, 0xc, 0x12,0x29,0x72,0x7e,0xb3,0x24,0xd8,0xf5,0x25,
+0x12,0x35,0xcd,0x7e,0x18,0x32,0xa3,0x12,0x35,0xe0,0x12,0xb7,0x7b,0x6c,0xee,0x80,
+0x20,0x7a,0xe1,0x24,0xa, 0x3e,0x9, 0xc3,0x24,0xb0,0xa, 0x3c,0x12,0x57,0xb7,0x7c,
+0xcb,0xbe,0xc0,0x24,0x50,0x9, 0x12,0x37,0xd6,0x12,0x36,0xd3,0x12,0x35,0xd5,0xb,
+0xe0,0xbc,0xde,0x38,0xdc,0x6c,0xee,0x80,0x1a,0xa, 0x4e,0xa, 0x5d,0x2d,0x54,0xf5,
+0x24,0xa, 0x3e,0x12,0x37,0xc5,0x50,0x9, 0x12,0x7b,0x7c,0x12,0x36,0xd3,0x12,0x35,
+0xd5,0xb, 0xe0,0xe5,0x26,0xbc,0xbe,0x38,0xe0,0x7e,0xb3,0x24,0xd9,0x60,0xf, 0x12,
+0x35,0xcd,0x7e,0x18,0x32,0xbb,0x12,0x35,0xe0,0x12,0xc5,0x13,0x80,0x7, 0x7e,0x8,
+0x32,0xbb,0x12,0xd0,0xf0,0x6c,0xee,0x7e,0x70,0xc, 0xac,0x7e,0x2e,0x34,0x32,0xbb,
+0x6d,0x22,0x7a,0x1f,0x31,0xbb,0x74,0x2, 0xac,0xbe,0x49,0x35,0x32,0xa3,0x7a,0x37,
+0x31,0xbf,0x74,0x2, 0xac,0xbe,0x49,0x35,0x32,0xaf,0x7a,0x37,0x31,0xc1,0x7e,0x70,
+0x18,0xac,0x7e,0x2e,0x34,0x31,0xcb,0x7a,0x1f,0x31,0xc3,0x7e,0x70,0xc, 0xac,0x7e,
+0x2e,0x34,0x32,0x5b,0x7a,0x1f,0x31,0xc7,0x7e,0x8, 0x31,0xbb,0xe5,0x25,0x7c,0x7e,
+0x12,0x5, 0x42,0xb, 0xe0,0xbe,0xe0,0x6, 0x40,0xad,0xda,0x3b,0x22,0x7e,0x18,0x24,
+0xb0,0x7a,0x1d,0x27,0x22,0x7e,0x73,0x24,0xd7,0xa, 0x2f,0x19,0x72,0x32,0x5b,0x22,
+0x7a,0x1d,0x2b,0xe5,0x26,0x7c,0x7d,0x7e,0x8, 0x24,0x8d,0x22,0x12,0xab,0x64,0x12,
+0x0, 0xa, 0x12,0x1d,0xa0,0x12,0xc4,0x3e,0x7e,0x24,0x3, 0xd4,0x12,0x3f,0xf1,0x74,
+0x1, 0x12,0x34,0x7d,0x12,0x5f,0xee,0x7e,0x34,0xd0,0xc, 0x12,0x1d,0xb1,0x12,0x34,
+0xac,0x7e,0x34,0x0, 0x1, 0xe4,0x6c,0x55,0x2, 0x1c,0xa6,0x12,0x37,0xcd,0xb4,0x1,
+0x17,0xca,0x39,0x7e,0x18,0x1f,0x5f,0x7e,0x8, 0x3f,0x61,0x12,0x29,0x4d,0x1b,0xfd,
+0x12,0xd1,0x2c,0x12,0x36,0x55,0x80,0x1a,0xca,0x39,0x7e,0x18,0x25,0x6c,0x7e,0x8,
+0x3f,0x61,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x37,0x25,0x72,0x7a,0x37,0x30,0x49,0x12,
+0x36,0x5e,0x2, 0x31,0xd8,0x7e,0x1f,0x1f,0x63,0x7e,0xf, 0x1f,0x5f,0x22,0x7e,0x1f,
+0x25,0x70,0x7e,0xf, 0x25,0x6c,0x22,0xe5,0xd, 0x60,0x52,0xe5,0xd, 0x30,0xe0,0x6,
+0x53,0xd, 0xfe,0x12,0x5c,0xc2,0xe5,0xd, 0x30,0xe1,0x14,0x53,0xd, 0xfd,0x7e,0xb3,
+0x3f,0x65,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x12,0x5d,0xb8,0x12,0x7a,0xc1,0xe5,
+0xd, 0x30,0xe2,0x29,0x53,0xd, 0xfb,0xe4,0x7a,0xb3,0x3f,0x66,0x7e,0xb3,0x3f,0x65,
+0x70,0xa, 0x74,0x1, 0x12,0x0, 0x6, 0x12,0x36,0x5e,0x80,0x7, 0xe4,0x12,0x0, 0x6,
+0x12,0x36,0x55,0x12,0x31,0xd8,0x7e,0xb3,0x24,0xd8,0x2, 0x37,0x3e,0x22,0x7a,0xb3,
+0x24,0xdc,0x70,0x5, 0x12,0x36,0x5e,0x80,0x6, 0xb4,0x1, 0x6, 0x12,0x36,0x55,0x12,
+0x31,0xd8,0x22,0x2d,0x31,0x7c,0xf7,0x7e,0x30,0x2, 0xac,0x3f,0x2e,0x14,0x31,0xcb,
+0x6d,0x0, 0x7e,0x71,0x24,0x74,0x2, 0xac,0x7b,0x2e,0x37,0x24,0xda,0x6d,0x22,0x74,
+0x1, 0xca,0x79,0x7c,0xab,0x7f,0x71,0x6c,0x99,0x80,0x3c,0x12,0x57,0xdd,0x2d,0xd7,
+0xb, 0x6a,0xd0,0x5e,0xd4,0x1, 0xff,0xbe,0xd4,0x0, 0xff,0x28,0xc, 0x7d,0x2d,0x9e,
+0x24,0x0, 0xff,0x7e,0x34,0x0, 0xff,0x80,0x4, 0x6d,0x22,0x7d,0x3d,0x7c,0xb5,0x7f,
+0x50,0x2d,0xb7,0x7a,0x5b,0xb0,0x7c,0x87,0x7e,0xf0,0x2, 0xac,0xf9,0x7f,0x50,0x2d,
+0xb7,0x39,0x85,0x0, 0x1, 0xb, 0x90,0xbc,0xa9,0x38,0xc0,0xda,0x79,0x22,0xca,0x3b,
+0x7c,0xeb,0x7e,0x8, 0x32,0x41,0x7e,0x34,0x0, 0x90,0x74,0x3e,0x12,0x7b,0x74,0xf5,
+0x2a,0x7e,0xb3,0x24,0x40,0xf5,0x2b,0x6c,0xdd,0x80,0x20,0x7a,0xd1,0x29,0xa, 0x3d,
+0x9, 0xc3,0x24,0xb0,0xa, 0x3c,0x12,0x57,0xb7,0x7c,0xcb,0xbe,0xc0,0x24,0x50,0x9,
+0x12,0x37,0xd6,0x12,0x37,0xe9,0x12,0x36,0xe5,0xb, 0xd0,0xe5,0x2b,0xbc,0xbd,0x38,
+0xda,0x6c,0xdd,0x80,0x1c,0xa, 0x4d,0xe5,0x2b,0xa, 0x5b,0x2d,0x54,0xf5,0x29,0xa,
+0x3d,0x12,0x37,0xc5,0x50,0x9, 0x12,0x7b,0x7c,0x12,0x37,0xe9,0x12,0x36,0xe5,0xb,
+0xd0,0xe5,0x2a,0xbc,0xbd,0x38,0xde,0x6c,0xdd,0x7e,0x30,0x18,0xac,0x3d,0x2e,0x14,
+0x32,0x41,0x6d,0x0, 0x7c,0xbe,0x7c,0x7d,0x12,0x1b,0x80,0xb, 0xd0,0xbe,0xd0,0x6,
+0x40,0xe7,0xda,0x3b,0x22,0x9, 0xc3,0x24,0x8d,0xbe,0xc0,0x23,0x22,0x7e,0xb3,0x3f,
+0x65,0x7e,0x34,0x0, 0x4, 0x22,0xa, 0x1c,0x7e,0x24,0x0, 0x3, 0x8d,0x12,0x7e,0x14,
+0x0, 0xc, 0xad,0x10,0xa, 0x3c,0x8d,0x32,0x22,0x2d,0x31,0x7c,0xf7,0x7e,0x30,0x2,
+0xac,0x3f,0x2e,0x14,0x32,0x41,0x6d,0x0, 0x7e,0x71,0x29,0x22,0x30,0x6, 0x31,0xc2,
+0x6, 0x12,0x2f,0x20,0x7e,0x73,0x3f,0x26,0x7a,0x73,0x24,0x19,0x7e,0x73,0x3f,0x27,
+0x7a,0x73,0x24,0xfb,0x7e,0x73,0x3f,0x27,0x7a,0x73,0x24,0xdd,0x7e,0x73,0x3f,0x28,
+0x4c,0x77,0x68,0xc, 0xa, 0x37,0x1b,0x34,0x12,0x39,0x3d,0xe4,0x7a,0xb3,0x3f,0x28,
+0x12,0x36,0x67,0x2, 0x38,0x36,0xe5,0xc, 0x70,0x2, 0x21,0x3c,0xe5,0xc, 0x30,0xe0,
+0x10,0x53,0xc, 0xfe,0x12,0x42,0x66,0x12,0x78,0x5b,0x7e,0x8, 0x24,0x39,0x12,0x13,
+0xbe,0xe5,0xc, 0x30,0xe1,0x6, 0x53,0xc, 0xfd,0x12,0xc4,0xd5,0xe5,0xc, 0x30,0xe2,
+0x36,0x53,0xc, 0xfb,0x7e,0xb3,0x24,0xf0,0x60,0x9, 0x7e,0x8, 0x24,0x39,0x12,0x3,
+0x95,0x80,0xb, 0x7e,0xb3,0x25,0x4b,0x7e,0x73,0x25,0x4a,0x12,0x0, 0x24,0x7e,0x73,
+0x24,0xf0,0x2e,0x70,0xff,0x92,0x4, 0x7e,0x8, 0x24,0x39,0x90,0x60,0x51,0xe4,0x93,
+0x9e,0xb3,0x24,0x43,0x12,0x15,0xb8,0xe5,0xc, 0x30,0xe3,0x30,0x53,0xc, 0xf7,0x7e,
+0x73,0x3f,0x53,0x7a,0x73,0x24,0xed,0x12,0x42,0xce,0x12,0x5a,0x30,0x7e,0x73,0x3f,
+0x54,0xbe,0x73,0x25,0x48,0x68,0x6, 0x7a,0x73,0x25,0x48,0xd2,0xc, 0x30,0xc, 0x6,
+0x12,0xab,0x62,0x12,0x0, 0xa, 0x12,0xab,0x40,0x12,0x44,0x27,0xe5,0xc, 0x30,0xe4,
+0xf, 0x53,0xc, 0xef,0x7e,0x43,0x3f,0x55,0x7e,0x50,0xa, 0xac,0x45,0x12,0x3f,0xf1,
+0xe5,0xc, 0x30,0xe6,0x48,0x53,0xc, 0xbf,0x7e,0x73,0x3f,0x41,0xbe,0x70,0x7, 0x28,
+0x6, 0x74,0x7, 0x7a,0xb3,0x3f,0x41,0xa9,0xd5,0xcb,0x7e,0x71,0xcf,0x5e,0x70,0xf,
+0x7e,0x63,0x3f,0x41,0xa, 0x26,0x2e,0x24,0x0, 0x3, 0x12,0x3d,0xb5,0x7c,0x65,0x4c,
+0x76,0x7a,0x71,0xcf,0x7e,0x71,0xcf,0x12,0x3c,0x77,0x7e,0x73,0x3f,0x44,0x7a,0x73,
+0x24,0xf2,0x7e,0x73,0x3f,0x43,0x7a,0x73,0x24,0xfd,0x12,0xd1,0x3e,0xe5,0xc, 0x30,
+0xe5,0xa, 0x53,0xc, 0xdf,0x7e,0xb3,0x3f,0x2b,0x2, 0x58,0x3e,0x22,0xca,0x3b,0x7d,
+0xc3,0x6c,0xee,0x12,0x40,0x79,0xa, 0x2b,0xa, 0x3a,0x2d,0x32,0x7c,0xc7,0x12,0x40,
+0x8, 0x7e,0x34,0x60,0xab,0x12,0x2d,0x68,0x12,0x48,0x8f,0x7e,0x8, 0x30,0x51,0x7e,
+0x34,0x1, 0x22,0xe4,0x12,0x29,0x72,0x12,0x4b,0x71,0x50,0xfb,0x7e,0x1f,0x3f,0xbe,
+0x69,0xd1,0x0, 0x9e,0x69,0xe1,0x0, 0xaa,0x7e,0x1f,0x3f,0xc6,0x69,0xf1,0x0, 0x2e,
+0xa9,0xd0,0xc4,0xa9,0xd5,0xcb,0x74,0x7, 0x12,0x0, 0x56,0xf5,0x24,0x74,0x7, 0x7e,
+0x70,0xf, 0x12,0x3c,0x74,0x74,0x1, 0x12,0x1d,0x89,0x7e,0x34,0x4, 0xb0,0x7e,0xf,
+0x3f,0xc2,0x79,0x30,0x0, 0x6, 0x7e,0x34,0x0, 0x80,0x7e,0xf, 0x3f,0xc2,0x79,0x30,
+0x0, 0x8, 0x7e,0x34,0x0, 0x10,0x7e,0xf, 0x3f,0xc2,0x79,0x30,0x0, 0x12,0x6d,0x33,
+0x12,0x3e,0x98,0x7e,0xf, 0x3f,0xc6,0x2e,0x14,0x0, 0x2e,0xb, 0xa, 0x30,0x5e,0x60,
+0xfe,0x1b,0xa, 0x30,0x6d,0x33,0x12,0xc1,0xff,0x12,0x3d,0x4d,0x4e,0x70,0x20,0x1b,
+0xa, 0x30,0x12,0x3d,0x4d,0x5e,0x34,0xfe,0x7f,0x1b,0xa, 0x30,0x7e,0x27,0x2b,0xfe,
+0x5e,0x24,0x0, 0x3, 0x12,0x3d,0xb5,0x12,0x3d,0xb7,0x12,0x3d,0x4d,0x4d,0x32,0x1b,
+0xa, 0x30,0x7e,0x34,0xff,0xff,0x7e,0xf, 0x3f,0xbe,0x79,0x30,0x0, 0xac,0x7e,0xf,
+0x3f,0xbe,0x79,0x30,0x0, 0xae,0x7e,0x34,0x0, 0xf, 0x7e,0xf, 0x3f,0xbe,0x79,0x30,
+0x0, 0xb0,0x12,0x3d,0x4d,0x4e,0x60,0x88,0x1b,0xa, 0x30,0xbe,0xc4,0x0, 0x3, 0x78,
+0x13,0x12,0x3d,0xc9,0x4e,0xc4,0x0, 0x1, 0x1b,0x1a,0xc0,0x12,0x3d,0xc9,0x5e,0xc4,
+0x0, 0xf, 0x80,0x14,0xbe,0xc4,0x0, 0x4, 0x78,0x1d,0x7e,0xc4,0x0, 0x2, 0x12,0x3e,
+0x86,0x12,0x3d,0xc9,0x4e,0xc4,0x0, 0x8, 0x1b,0x1a,0xc0,0x12,0x3d,0xbe,0x12,0x3b,
+0xbe,0x7a,0x37,0x30,0x51,0x61,0x52,0x7e,0x34,0x0, 0x10,0x12,0x3e,0x98,0x7d,0x2c,
+0x3e,0x24,0x3e,0x24,0x7e,0xf, 0x3f,0xc2,0x2e,0x14,0x0, 0xe, 0xb, 0xa, 0x30,0x4d,
+0x32,0x1b,0xa, 0x30,0xe5,0xe, 0x60,0x7, 0xe5,0xe, 0xbe,0xb0,0x64,0x28,0x6, 0x7e,
+0x34,0x0, 0x2, 0x80,0x4, 0xe5,0xe, 0xa, 0x3b,0x12,0x3b,0x9f,0x4d,0xcc,0x78,0x18,
+0x6c,0xee,0x80,0xe, 0xa, 0x3e,0x9, 0x73,0x31,0x74,0x12,0x3e,0x8f,0x12,0x3d,0x59,
+0xb, 0xe0,0xbc,0xce,0x38,0xee,0x61,0x4c,0xbe,0xc4,0x0, 0x2, 0x78,0x22,0x7e,0xc3,
+0x2c,0x0, 0x6c,0xee,0x80,0x14,0xa, 0x3e,0x9, 0xf3,0x2c,0x1, 0xa, 0x3f,0x9, 0x73,
+0x31,0x73,0x12,0x3e,0x8f,0x12,0x3d,0x59,0xb, 0xe0,0xbc,0xce,0x38,0xe8,0x80,0x6c,
+0xbe,0xc4,0x0, 0x1, 0x78,0x66,0x6c,0x99,0x7e,0xc3,0x2c,0x0, 0x7e,0xd0,0x1, 0x80,
+0x55,0xa, 0xcd,0x9, 0xfc,0x2c,0x0, 0xb, 0xc4,0x7d,0x3c,0x7c,0xe7,0x80,0x41,0xa,
+0xce,0x9, 0x8c,0x2c,0x0, 0xbc,0x8f,0x68,0x35,0xbe,0x90,0x8f,0x38,0x36,0xa, 0x5f,
+0x9, 0x75,0x31,0x73,0xa, 0xc7,0x7d,0x3c,0x7c,0x67,0x6c,0x77,0x7d,0xc3,0xa, 0x58,
+0x9, 0x75,0x31,0x73,0xa, 0x57,0x4d,0x5c,0x7e,0x1f,0x3f,0xc2,0x79,0x51,0x0, 0x10,
+0x12,0x3b,0xbe,0x7c,0xa9,0xb, 0x90,0x74,0x2, 0xa4,0x59,0x35,0x30,0x51,0xb, 0xe0,
+0xbc,0xce,0x50,0xbb,0xb, 0xd0,0xbc,0xcd,0x38,0xa7,0x7c,0xe9,0x12,0x3d,0xbe,0x12,
+0x3d,0x59,0xa9,0xd5,0xcb,0x74,0x7, 0x7e,0x71,0x24,0x12,0x3c,0x74,0xa9,0xc0,0xc4,
+0x7e,0x1f,0x3f,0xbe,0x79,0xd1,0x0, 0x9e,0x7e,0x1f,0x3f,0xbe,0x79,0xe1,0x0, 0xaa,
+0x7e,0x1f,0x3f,0xc6,0x79,0xf1,0x0, 0x2e,0x6d,0xcc,0x7e,0x1f,0x3f,0xc2,0x79,0xc1,
+0x0, 0x6, 0x7e,0x1f,0x3f,0xc2,0x79,0xc1,0x0, 0x8, 0x7e,0x1f,0x3f,0xc2,0x79,0xc1,
+0x0, 0x12,0x12,0x3e,0x86,0x12,0x3d,0xc0,0xda,0x3b,0x22,0x7e,0x34,0x0, 0x1, 0x7d,
+0x23,0x80,0x12,0x7e,0x30,0x4, 0x80,0x5, 0x74,0xfa,0x12,0x3e,0xa1,0x7c,0x23,0x1b,
+0x30,0xa5,0xba,0x0, 0xf3,0x7d,0x32,0x1b,0x24,0x4d,0x33,0x78,0xe6,0x22,0x7e,0x34,
+0x0, 0x2, 0x12,0x3b,0x9f,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x3f,0xc2,0x79,0x30,0x0,
+0x4, 0x7e,0xf, 0x3f,0xc2,0x69,0x30,0x0, 0x14,0x5e,0x34,0x0, 0x1, 0x68,0xf2,0x7e,
+0x34,0x0, 0x1, 0x79,0x30,0x0, 0x14,0x7e,0xf, 0x3f,0xc2,0x69,0x30,0x0, 0xa, 0x7d,
+0x23,0x6d,0x33,0x69,0x10,0x0, 0xc, 0x6d,0x0, 0x2f,0x10,0x74,0x7, 0x1e,0x34,0x1e,
+0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x22,0xf5,0xfd,0x7a,0x71,0xfe,0x22,
+0x6d,0x33,0x7e,0x8, 0x0, 0x24,0x7e,0x24,0x0, 0x12,0x12,0xc3,0xf5,0xa9,0xd5,0xcb,
+0x74,0x8, 0x7e,0x71,0x2c,0x12,0x3c,0xa, 0x74,0x9, 0x7e,0x71,0x2d,0x12,0x3c,0xa,
+0xe5,0x33,0xb4,0x1, 0x17,0x7e,0x71,0x31,0x5e,0x70,0x1f,0x3e,0x70,0x3e,0x70,0x74,
+0xa, 0x12,0x3c,0xa, 0x74,0xb, 0x7e,0x71,0x32,0x12,0x3c,0xa, 0x74,0xc, 0x7e,0x71,
+0x30,0x12,0x3c,0xa, 0x74,0x2, 0x7e,0x71,0x26,0x12,0x3c,0xa, 0x74,0x3, 0x7e,0x71,
+0x27,0x12,0x3c,0xa, 0x74,0x4, 0x7e,0x71,0x28,0x12,0x3c,0xa, 0x74,0x5, 0x7e,0x71,
+0x29,0x2, 0x3c,0x74,0x12,0x3c,0xa, 0x75,0xfd,0xff,0xa9,0xc5,0xcb,0x22,0xca,0x79,
+0xa9,0xd5,0xcb,0x74,0x2, 0x7e,0x70,0x3f,0x12,0x3c,0xa, 0x74,0x3, 0x7e,0x70,0x1f,
+0x12,0x3c,0xa, 0xa9,0xd0,0xce,0xa9,0xd6,0xc9,0x74,0x5, 0x12,0x0, 0x56,0x7c,0xfb,
+0x5e,0xf0,0xe0,0x4e,0xf0,0x1d,0x74,0x5, 0x7c,0x7f,0x12,0x3c,0xa, 0x74,0xa, 0x7e,
+0x70,0x24,0x12,0x3c,0xa, 0x74,0xb, 0x7e,0x70,0xc, 0x12,0x3c,0xa, 0x74,0xc, 0x7e,
+0x70,0x2, 0x12,0x3c,0xa, 0x7e,0xf1,0xc1,0x5e,0xf0,0xe0,0x4e,0xf0,0x2, 0x7a,0xf1,
+0xc1,0x7e,0xf1,0xc2,0x5e,0xf0,0xe0,0x4e,0xf0,0x4, 0x7a,0xf1,0xc2,0x74,0xc, 0x12,
+0x0, 0x56,0x7c,0xfb,0x54,0x7f,0x68,0x8, 0x74,0xc, 0x7e,0x70,0xf8,0x12,0x3c,0xa,
+0x90,0x61,0x28,0xe4,0x93,0x7c,0xab,0xbe,0xa0,0x7, 0x38,0x11,0xa, 0x3a,0x2e,0x34,
+0x0, 0x3, 0x12,0x3e,0x7d,0x7c,0xb7,0xa, 0x7b,0xb, 0x75,0x80,0x1c,0x90,0x61,0x27,
+0xe4,0x93,0xb4,0x1, 0x14,0xbe,0xa0,0x7, 0x28,0xf, 0xa, 0x3a,0x2e,0x34,0x0, 0x3,
+0x12,0x3e,0x7d,0xa, 0x77,0x2e,0x74,0x0, 0x7, 0x7a,0xf1,0xcf,0x74,0x7, 0x12,0x0,
+0x56,0x7c,0xfb,0x5e,0xf0,0xfb,0x90,0x60,0x2, 0xe4,0x93,0xa, 0x3b,0x3e,0x34,0x3e,
+0x34,0x4c,0xf7,0x74,0x7, 0x7c,0x7f,0x12,0x3c,0x74,0xda,0x79,0x22,0x7e,0xf, 0x3f,
+0xbe,0x2e,0x14,0x0, 0x9e,0xb, 0xa, 0x30,0x22,0x7e,0x34,0x0, 0x2, 0x12,0x3b,0x9f,
+0x12,0x3b,0xc5,0x74,0x2, 0xac,0xbe,0x59,0x35,0x30,0x51,0x22,0x12,0x4b,0x71,0x50,
+0xfb,0x12,0xd1,0x35,0x12,0xd1,0x2c,0x6d,0x33,0x7a,0x35,0xa, 0x12,0x58,0x15,0x74,
+0x50,0x7a,0xb3,0x3f,0x55,0x7e,0x24,0x3, 0x20,0x12,0x3f,0xf1,0xe4,0x12,0xd0,0x8b,
+0x6d,0x33,0x7a,0x37,0x40,0x32,0x2, 0x3d,0x99,0xe4,0x7a,0xb3,0x3f,0xe5,0x7a,0xb3,
+0x3f,0xe4,0x12,0x5c,0x6d,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x2, 0x74,0x3, 0x7a,0xb3,
+0x3f,0xe5,0x22,0xa, 0x25,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x22,0x6d,0xcc,
+0x7e,0x1f,0x3f,0xc2,0x79,0xc1,0x0, 0x10,0x22,0x7e,0x1f,0x3f,0xc2,0x2e,0x34,0x0,
+0xe, 0xb, 0x1a,0xc0,0x22,0x24,0xab,0x68,0x10,0x24,0xef,0x68,0x1c,0x24,0xde,0x68,
+0x26,0x24,0xde,0x78,0x2f,0x74,0x5, 0x80,0x2d,0x7e,0xb3,0x40,0x41,0xb4,0x5, 0x2a,
+0x12,0x3b,0x9b,0x12,0xc1,0x59,0x2, 0xc2,0x6c,0x7e,0xb3,0x40,0x41,0xb4,0x5, 0x1a,
+0x12,0x3b,0x9b,0x75,0xe9,0xff,0x22,0x7e,0xb3,0x40,0x41,0xb4,0x5, 0xc, 0x12,0x3b,
+0x9b,0x2, 0xc2,0x66,0x74,0x1, 0x7a,0xb3,0x40,0x41,0x22,0x7e,0x34,0x3, 0x9e,0x30,
+0xd, 0x4b,0xc2,0xd, 0x9, 0x53,0x0, 0x2, 0x12,0x3d,0xb3,0x7a,0x27,0x24,0x1b,0x9,
+0x53,0x0, 0x3, 0x12,0x3d,0xb3,0x7a,0x27,0x24,0x1d,0x9, 0x53,0x0, 0x4, 0x12,0x3d,
+0xb3,0x7a,0x27,0x24,0x1f,0x7e,0x39,0x50,0xa, 0x25,0x3e,0x24,0x3e,0x24,0x7a,0x27,
+0x24,0x26,0x9, 0x53,0x0, 0x1, 0xa, 0x25,0x3e,0x24,0x3e,0x24,0x7a,0x27,0x24,0x28,
+0x9, 0x73,0x0, 0x5, 0xa, 0x37,0x12,0x3e,0x7d,0x7a,0x37,0x24,0x2e,0x22,0x7e,0xf,
+0x3f,0xbe,0x69,0x20,0x0, 0xa0,0x5e,0x50,0x1f,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,
+0x34,0x3e,0x34,0x3e,0x34,0x22,0x7e,0x1f,0x3f,0xc2,0x79,0xc1,0x0, 0xe, 0x22,0x7e,
+0xf, 0x3f,0xc2,0x79,0x30,0x0, 0x10,0x22,0x7e,0xf, 0x3f,0xc2,0x79,0x30,0x0, 0xe,
+0x22,0x7c,0xab,0x80,0xe, 0x7e,0x70,0x3, 0x80,0x1, 0x0, 0x7c,0x67,0x1b,0x70,0xa5,
+0xbe,0x0, 0xf7,0x7c,0x6a,0x1b,0xa0,0xa5,0xbe,0x0, 0xea,0x22,0x7c,0x6b,0xa9,0xd5,
+0xcb,0x74,0xf, 0x12,0x3c,0xa, 0x7a,0x61,0xfc,0x12,0x3c,0x77,0x12,0x3f,0x5a,0xd2,
+0x3, 0x12,0x91,0x5f,0x12,0x3f,0x26,0x12,0x1d,0x89,0x2, 0x1d,0x58,0x12,0x3f,0xf8,
+0xc2,0x3, 0x12,0x3f,0xff,0xc2,0x5, 0x12,0x3f,0xc, 0xc2,0x3, 0x12,0x91,0x5f,0xa9,
+0xd5,0xcb,0x74,0xf, 0x12,0x0, 0x56,0x7a,0x1b,0xb0,0x74,0xf, 0x6c,0x77,0x12,0x3c,
+0xa, 0xe5,0xfc,0x7a,0xb, 0xb0,0x43,0xfc,0x10,0x2, 0x3c,0x77,0xa9,0xd0,0xce,0xa2,
+0x5, 0xa9,0x91,0xc9,0x22,0x30,0x4, 0x6, 0x12,0x3f,0x26,0x2, 0x1d,0x58,0x12,0x3f,
+0xf8,0xc2,0x5, 0x2, 0x3f,0xc, 0xd2,0x5, 0x12,0x3f,0xc, 0x74,0x1, 0x22,0x12,0x90,
+0x44,0x12,0x91,0x1c,0x75,0xcd,0x0, 0xa9,0xd6,0xeb,0xa9,0xd7,0xcd,0xc2,0xce,0x12,
+0xd1,0x12,0x12,0x3e,0xdd,0x74,0x1, 0x12,0x90,0x4b,0xa9,0xc6,0xeb,0xa9,0xc7,0xcd,
+0xd2,0xce,0xe5,0x25,0x7e,0x71,0x24,0x2, 0x3e,0xbc,0xca,0xf8,0xa2,0xaf,0xe4,0x33,
+0x7c,0xfb,0xd2,0x3, 0x12,0x3f,0xff,0xa9,0xd0,0xcb,0xc2,0xaf,0xa9,0xd0,0x9e,0x75,
+0x9d,0x0, 0xa9,0xd0,0x9e,0x75,0x9c,0x20,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0xa9,0xd0,
+0xcd,0x74,0x41,0x12,0x3e,0xa1,0xa9,0xd0,0x9e,0xa9,0xd7,0x9e,0x2e,0xf0,0xff,0x92,
+0xaf,0xda,0xf8,0x22,0xe4,0x12,0x91,0x2e,0x12,0xc2,0x8, 0x12,0x48,0x8b,0x12,0xc2,
+0x7b,0x12,0x3c,0x7e,0x12,0xc1,0x4f,0x12,0xc2,0x1f,0x12,0x0, 0xff,0x12,0xc2,0x2b,
+0x12,0x7c,0x4d,0xc2,0xae,0x12,0xc2,0x3b,0xd2,0xaf,0x12,0xc1,0xa1,0x12,0xc3,0x84,
+0x12,0x3c,0x10,0x12,0x3f,0x5a,0x7e,0x8, 0x3f,0xfe,0x12,0xa7,0x62,0x90,0x60,0x50,
+0xe4,0x93,0xca,0xb8,0x90,0x60,0x51,0xe4,0x93,0x7c,0x7b,0x7e,0x24,0xff,0xff,0xda,
+0xb8,0x2, 0x1c,0x12,0x2, 0x3f,0xe7,0xe4,0x7a,0xb3,0x24,0xde,0x7a,0xb3,0x24,0xfc,
+0x22,0x7d,0x32,0x74,0xfa,0x2, 0x17,0xcd,0xe4,0x12,0x1d,0x89,0x2, 0x1d,0x58,0xa9,
+0xd0,0xce,0xa2,0x3, 0xa9,0x95,0xc9,0x22,0x12,0x40,0x79,0xa, 0x2b,0xa, 0x3a,0x2d,
+0x32,0xb, 0x34,0x7e,0x60,0x1, 0x80,0x55,0xa5,0xbe,0x0, 0x6, 0xe4,0x12,0x40,0x72,
+0x80,0x49,0xbc,0xa6,0x40,0x20,0xa, 0x26,0x9, 0xb2,0x24,0x8c,0x19,0xb2,0x31,0x73,
+0xbe,0xb0,0x23,0x40,0x5, 0x74,0x22,0x12,0x40,0x72,0xa, 0x26,0x2e,0x24,0x31,0x73,
+0x7e,0x29,0xb0,0x4, 0x80,0x22,0xa, 0x1a,0xa, 0x26,0x9d,0x21,0x9, 0xb2,0x24,0xaf,
+0x12,0x40,0x72,0xbe,0xb0,0x24,0x40,0x5, 0x74,0x23,0x12,0x40,0x72,0xa, 0x26,0x2e,
+0x24,0x31,0x73,0x7e,0x29,0xb0,0x24,0x24,0x7a,0x29,0xb0,0xb, 0x60,0xbc,0x76,0x38,
+0xa7,0x22,0xa, 0x26,0x19,0xb2,0x31,0x73,0x22,0x90,0x60,0x50,0xe4,0x93,0x7c,0xab,
+0x90,0x60,0x51,0xe4,0x93,0x22,0xca,0x79,0x12,0x40,0x79,0x7c,0xeb,0x7e,0xb3,0x24,
+0x40,0xbc,0xbe,0x28,0x4, 0x7c,0xfb,0x80,0x2, 0x7c,0xfe,0x7a,0xa3,0x24,0x39,0x7a,
+0xe3,0x24,0x3a,0x7a,0xa3,0x24,0x3d,0x7a,0xe3,0x24,0x3e,0x7a,0xa3,0x24,0x3f,0x7a,
+0xe3,0x24,0x40,0x90,0x60,0xb0,0xe4,0x93,0x7c,0x7b,0x7a,0x73,0x24,0x43,0x90,0x60,
+0xb1,0xe4,0x93,0xa, 0x1b,0xa, 0x2a,0x9d,0x21,0x7c,0x65,0x7a,0x63,0x24,0x3b,0xa,
+0x27,0xa, 0x3e,0x9d,0x32,0x7c,0xb7,0x7a,0xb3,0x24,0x3c,0x90,0x60,0x99,0xe4,0x93,
+0x7a,0xb3,0x24,0x44,0x90,0x60,0x9c,0xe4,0x93,0x7a,0xb3,0x24,0x45,0xa, 0x3a,0xca,
+0x39,0x7e,0x34,0x60,0x52,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x24,0x46,0x12,0x29,0x4d,
+0x1b,0xfd,0xa, 0x3f,0xca,0x39,0x7e,0x34,0x60,0x75,0x7e,0x24,0x0, 0xff,0x7e,0x8,
+0x24,0x69,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x34,0x0, 0x23,0xca,0x39,0x7e,0x34,0x60,
+0xe0,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x24,0xff,0x12,0x29,0x4d,0x1b,0xfd,0x12,0x42,
+0x66,0x12,0x78,0x5b,0x12,0x6f,0xfe,0x74,0x1, 0x12,0x34,0x7d,0xe4,0x7a,0xb3,0x24,
+0xdd,0x7a,0xb3,0x24,0xde,0x12,0x77,0xfb,0x7a,0x1f,0x24,0xe9,0x74,0x3, 0x7a,0xb3,
+0x24,0xdf,0xe4,0x7a,0xb3,0x24,0xe0,0x74,0x2, 0x7a,0xb3,0x24,0xe1,0x7e,0x34,0x61,
+0x6b,0x12,0x2d,0x68,0x7a,0x37,0x24,0xe3,0x74,0x4, 0x7a,0xb3,0x24,0xe2,0x7e,0x34,
+0x0, 0xf, 0x7a,0x37,0x24,0xe5,0x7e,0x34,0x20,0x5f,0x7a,0x37,0x24,0xe7,0x90,0x61,
+0x2a,0xe4,0x93,0x7a,0xb3,0x25,0x48,0x90,0x61,0x2b,0xe4,0x93,0x7a,0xb3,0x24,0xee,
+0x90,0x61,0x2c,0xe4,0x93,0x7a,0xb3,0x24,0xef,0x74,0x4, 0x7a,0xb3,0x24,0xf1,0x90,
+0x60,0xdd,0xe4,0x93,0x12,0x42,0xca,0xe4,0x7a,0xb3,0x24,0xfb,0x7a,0xb3,0x24,0xfc,
+0x7e,0x34,0x61,0x32,0x12,0x2d,0x68,0x7a,0x37,0x24,0xf7,0x90,0x60,0xdb,0x93,0x7a,
+0xb3,0x24,0xf0,0x90,0x61,0x34,0xe4,0x93,0x7a,0xb3,0x24,0xfe,0x90,0x61,0x29,0xe4,
+0x93,0x7a,0xb3,0x24,0xfd,0x7e,0x34,0x61,0x2e,0x12,0x2d,0x68,0x7a,0x37,0x24,0xf3,
+0x7e,0x34,0x61,0x30,0x12,0x2d,0x68,0x7a,0x37,0x24,0xf5,0x90,0x61,0x2d,0xe4,0x93,
+0x7a,0xb3,0x24,0xf2,0x7e,0x34,0x0, 0x30,0x7a,0x37,0x25,0x50,0x74,0x3, 0x7a,0xb3,
+0x25,0x4d,0x6d,0x33,0x7a,0x37,0x25,0x4e,0xe4,0x7a,0xb3,0x25,0x4c,0x7e,0x34,0x4,
+0x2d,0x7a,0x37,0x25,0x52,0x7a,0xb3,0x25,0x49,0x7a,0xb3,0x25,0x4a,0x7a,0xb3,0x25,
+0x4b,0x74,0x1, 0x7a,0xb3,0x25,0x46,0xe4,0x7a,0xb3,0x25,0x47,0x7e,0x34,0x28,0xf9,
+0x7a,0x37,0x25,0x54,0x74,0x18,0x7a,0xb3,0x25,0x56,0x7e,0x34,0x29,0x11,0x7a,0x37,
+0x25,0x68,0x74,0x6, 0x7a,0xb3,0x25,0x6a,0x74,0x1, 0x7a,0xb3,0x25,0x6b,0xa, 0x3e,
+0xca,0x39,0x7e,0x34,0x61,0x3, 0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x25,0x22,0x12,0x29,
+0x4d,0x1b,0xfd,0xda,0x79,0x22,0x12,0xd1,0x12,0x12,0xc0,0x94,0x90,0x60,0x50,0xe4,
+0x93,0xa, 0x3b,0x7d,0x13,0x2e,0x14,0x24,0x46,0x6d,0x0, 0x9, 0xb3,0x24,0x45,0x12,
+0x42,0xb2,0x93,0xa, 0x3b,0x7d,0x13,0x2e,0x14,0x24,0xff,0x6d,0x0, 0x9, 0xb3,0x24,
+0xfe,0x12,0x42,0xb2,0x93,0xa, 0x1b,0x2e,0x14,0x24,0x48,0x12,0x42,0xbe,0xe5,0x25,
+0x12,0x42,0xb6,0x93,0xa, 0x1b,0x2e,0x14,0x25,0x1, 0x12,0x42,0xbe,0xe5,0x24,0x2,
+0x29,0x72,0x7e,0x34,0x0, 0x2, 0x12,0x29,0x72,0x90,0x60,0x50,0xe4,0x22,0x6d,0x0,
+0x90,0x60,0x99,0xe4,0x93,0xa, 0x3b,0x1b,0x35,0x22,0x7a,0xb3,0x24,0xed,0x12,0x42,
+0xd6,0x7a,0x37,0x24,0xf9,0x22,0xca,0x79,0x7e,0x23,0x24,0xed,0x12,0x47,0xe6,0x12,
+0x45,0xa2,0xac,0x23,0x2d,0x10,0xbe,0x14,0x0, 0xa, 0x50,0x4, 0x7e,0x14,0x0, 0xa,
+0x7e,0xe3,0x24,0xee,0xbe,0x14,0xb, 0xb8,0x40,0x4, 0x7e,0x14,0xb, 0xb8,0xbe,0x14,
+0x9, 0x60,0x28,0x3, 0xe4,0x80,0x26,0xbe,0x14,0x5, 0xdc,0x40,0x4, 0x74,0x3, 0x80,
+0x1c,0xbe,0x14,0x2, 0xee,0x40,0x14,0x12,0x47,0xef,0x28,0x9, 0xbe,0xa0,0x3, 0x68,
+0x4, 0x74,0x1, 0x80,0x8, 0x7a,0xa3,0x24,0xee,0x80,0x6, 0x74,0x2, 0x7a,0xb3,0x24,
+0xee,0x7e,0xf3,0x24,0xee,0xbe,0xf0,0x3, 0x78,0x7, 0x12,0xd0,0x49,0x74,0x30,0x80,
+0x2, 0x74,0x20,0x7a,0xb3,0x24,0xef,0xbc,0xfe,0x68,0x2, 0xd2,0xc, 0x7e,0x24,0x1,
+0xf4,0x7d,0x31,0x8d,0x32,0x7c,0x17,0xbe,0x10,0x7, 0x28,0x3, 0x7e,0x10,0x7, 0x7e,
+0x1f,0x3f,0xbe,0x69,0x51,0x0, 0xa0,0x54,0x1f,0xa, 0x1, 0x3e,0x4, 0x3e,0x4, 0x3e,
+0x4, 0x3e,0x4, 0x3e,0x4, 0x2d,0x5, 0x79,0x1, 0x0, 0xa0,0x12,0x47,0xfa,0xda,0x79,
+0x22,0x12,0x42,0xca,0x30,0xc, 0x6, 0x12,0xab,0x62,0x12,0x0, 0xa, 0x30,0x3, 0xa,
+0x12,0xab,0xe, 0x7e,0xb3,0x24,0xed,0x2, 0x44,0x2b,0x22,0xca,0xd8,0xca,0x79,0x7c,
+0xdb,0x7e,0xf0,0x5, 0xac,0xfd,0x9, 0x77,0x1f,0xa4,0x7a,0x73,0x24,0xed,0x9, 0x77,
+0x1f,0xa5,0x7a,0x73,0x24,0xf2,0x9, 0x77,0x1f,0xa6,0x7a,0x73,0x24,0xfd,0x9, 0x77,
+0x1f,0xa7,0x7a,0x73,0x24,0xfe,0x12,0x42,0xce,0x9, 0xb7,0x1f,0xa8,0x12,0xab,0x4a,
+0x12,0x44,0x27,0xe4,0x7a,0xb3,0x1f,0x5d,0xda,0x79,0xda,0xd8,0x22,0x7e,0xb3,0x3e,
+0x35,0x60,0x6, 0x14,0x7a,0xb3,0x3e,0x35,0x22,0x90,0x61,0xdb,0xe4,0x93,0xbe,0xb0,
+0x4, 0x28,0x3, 0x12,0x44,0x27,0x7e,0xb3,0x3, 0xa9,0x70,0x14,0x7e,0xb3,0x40,0x44,
+0xb4,0x1, 0xd, 0xe4,0x12,0x43,0x9b,0xe4,0x7a,0xb3,0x3e,0x38,0x7a,0xb3,0x3e,0x40,
+0x12,0x44,0xd7,0x12,0x46,0xaa,0x7e,0xa3,0x3, 0xa9,0x7a,0xa3,0x40,0x44,0xbe,0xb0,
+0xff,0x68,0x3, 0x2, 0x43,0x9b,0x22,0x7e,0xb3,0x24,0xed,0xca,0x3b,0x7c,0xfb,0x75,
+0x33,0x0, 0x90,0x61,0xdb,0xe4,0x93,0x7c,0xeb,0xbe,0xe0,0x4, 0x38,0x5, 0xe4,0x7a,
+0xb3,0x3e,0x41,0x6c,0xdd,0x7e,0xa3,0x3e,0x41,0xbc,0xae,0x40,0x2, 0x80,0x19,0xbe,
+0xa0,0x0, 0x28,0x19,0x74,0x5, 0xa4,0x9, 0x75,0x1f,0xa4,0xbc,0x7f,0x78,0xe, 0x7c,
+0xbe,0x14,0xbe,0xb3,0x3e,0x41,0x78,0x5, 0xe4,0x7a,0xb3,0x3e,0x41,0xe4,0x7a,0xb3,
+0x25,0x57,0x7e,0xc3,0x3e,0x41,0x80,0x47,0x7e,0xb3,0x3e,0x41,0x4, 0x7a,0xb3,0x3e,
+0x41,0x7e,0x50,0x5, 0xac,0x5c,0x9, 0xa2,0x1f,0xa4,0xbc,0xaf,0x68,0x2f,0xa, 0x3d,
+0x19,0xc3,0x3e,0x45,0x7e,0x70,0x5, 0xac,0x7d,0x19,0xa3,0x25,0x59,0x74,0x5, 0xac,
+0xbd,0x9, 0xb5,0x25,0x59,0x7c,0x7d,0x12,0x46,0x13,0x74,0x5, 0xac,0xbd,0x59,0x35,
+0x25,0x5a,0xb, 0xd0,0x5, 0x33,0xe5,0x33,0xbe,0xb0,0x3, 0x50,0x6, 0xb, 0xc0,0xbc,
+0xec,0x38,0xb5,0xe4,0x7a,0xb3,0x25,0x58,0x7e,0x8, 0x24,0x39,0x12,0x12,0xf5,0xe4,
+0x7a,0xb3,0x3e,0x42,0xda,0x3b,0x22,0x12,0x45,0x11,0x2, 0x44,0xdd,0x7e,0xb3,0x3e,
+0x38,0x60,0x6, 0x74,0x1, 0x7a,0xb3,0x3e,0x40,0x7e,0xb3,0x3e,0x40,0xb4,0x1, 0xc,
+0x74,0x3, 0x12,0x45,0x8, 0x12,0x2d,0x68,0x3e,0x34,0x80,0x7, 0xe4,0x12,0x45,0x8,
+0x12,0x2d,0x68,0x7a,0x37,0x24,0x2e,0x22,0x7a,0xb3,0x3b,0x8f,0x7e,0x34,0x61,0x6d,
+0x22,0x7e,0x17,0x3f,0xdb,0x12,0x45,0x9e,0x1e,0x4, 0xbd,0x1, 0x50,0x8, 0xe4,0x7a,
+0xb3,0x3e,0x36,0x12,0x46,0xa3,0x12,0x45,0x9e,0xbd,0x1, 0x50,0xb, 0xe4,0x7a,0xb3,
+0x3e,0x36,0x74,0x2, 0x7a,0xb3,0x3e,0x38,0x7e,0x7, 0x3e,0x3e,0xbd,0x1, 0x50,0x4,
+0x7a,0x17,0x3e,0x3e,0x12,0x47,0xde,0x38,0xa, 0x12,0x47,0xd6,0x38,0x5, 0x12,0x47,
+0xce,0x28,0x3f,0x12,0xa9,0x67,0x12,0x45,0x9e,0x1e,0x4, 0x1e,0x4, 0xbd,0x1, 0x28,
+0x27,0x7e,0xb3,0x3e,0x36,0x4, 0x7a,0xb3,0x3e,0x36,0x7e,0x73,0x3e,0x36,0xbe,0x70,
+0x32,0x28,0x1a,0x74,0x32,0x7a,0xb3,0x3e,0x36,0xe4,0x7a,0xb3,0x3e,0x38,0x7a,0xb3,
+0x3e,0x40,0x7a,0xb3,0x3e,0xab,0x80,0x5, 0xe4,0x7a,0xb3,0x3e,0x36,0x7d,0x31,0x2,
+0xaa,0xf, 0x2, 0x45,0x95,0x12,0xa9,0xdc,0xe4,0x7a,0xb3,0x3e,0x44,0x22,0x7e,0x34,
+0x61,0xde,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x0, 0x22,0x7e,0xa0,0x1, 0x7e,0x47,0xa,
+0x50,0x7e,0x34,0x61,0x65,0x12,0x45,0xa2,0x7e,0x34,0xff,0xfa,0xad,0x30,0x7e,0x14,
+0x0, 0x2, 0x12,0x46,0xb, 0x8, 0x12,0x7e,0xb3,0x22,0x1d,0x60,0x7, 0xe4,0x7a,0xb3,
+0x22,0x1e,0x80,0x32,0x7e,0xa0,0x5, 0x80,0x2d,0x7e,0x34,0xff,0xfb,0x12,0x46,0x9,
+0x8, 0x5, 0x7e,0xa0,0x4, 0x80,0x1f,0x7e,0x34,0xff,0xfc,0x12,0x46,0x9, 0x8, 0x5,
+0x7e,0xa0,0x3, 0x80,0x11,0x7e,0x34,0xff,0xfd,0x12,0x46,0x9, 0x8, 0x5, 0x7e,0xa0,
+0x2, 0x80,0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0xad,0x30,0x7d,0x21,0x12,0x26,0xc7,
+0xbd,0x34,0x22,0xca,0x69,0xca,0xf8,0x7c,0xf7,0x12,0x47,0xe6,0x12,0x45,0xa2,0xac,
+0x3b,0x2d,0x10,0xbe,0x14,0x0, 0xa, 0x50,0x4, 0x7e,0x14,0x0, 0xa, 0xbe,0x14,0xb,
+0xb8,0x40,0x4, 0x7e,0x14,0xb, 0xb8,0xbe,0x14,0x9, 0x60,0x28,0x4, 0x6c,0xaa,0x80,
+0x2e,0xbe,0x14,0x5, 0xdc,0x40,0x5, 0x7e,0xa0,0x3, 0x80,0x23,0xbe,0x14,0x2, 0xee,
+0x40,0x1a,0x12,0x47,0xef,0x28,0x18,0xbe,0xa0,0x3, 0x68,0x13,0x7e,0x70,0x1, 0x7e,
+0x10,0x5, 0xac,0x1f,0x19,0x70,0x25,0x5c,0x80,0xe, 0x80,0x3, 0x7e,0xa0,0x2, 0x7e,
+0x10,0x5, 0xac,0x1f,0x19,0xa0,0x25,0x5c,0x7e,0xd0,0x5, 0xac,0xdf,0x9, 0xb6,0x25,
+0x5c,0xb4,0x3, 0xb, 0x12,0xd0,0x49,0x74,0x30,0x19,0xb6,0x25,0x5d,0x80,0xc, 0x7e,
+0xa0,0x20,0x7e,0x10,0x5, 0xac,0x1f,0x19,0xa0,0x25,0x5d,0x12,0x47,0xfa,0xda,0xf8,
+0xda,0x69,0x22,0x74,0x1, 0x7a,0xb3,0x3e,0x38,0x22,0xca,0xd8,0xca,0x79,0x7e,0xe0,
+0xff,0x7e,0xb3,0x3e,0x3a,0xb4,0x1, 0x8, 0x12,0x88,0x1c,0xe4,0x7a,0xb3,0x3e,0x3a,
+0x7e,0xb3,0x3e,0x38,0xb4,0x2, 0x2, 0x80,0x2, 0xe1,0xb4,0x12,0x47,0xde,0x38,0xc,
+0x12,0x47,0xd6,0x38,0x7, 0x12,0x47,0xce,0x38,0x2, 0xe1,0xb4,0x90,0x61,0xdb,0xe4,
+0x93,0x7c,0xdb,0xa, 0x3d,0x1b,0x34,0xbe,0x34,0x0, 0x3, 0x48,0x4, 0x74,0x3, 0x80,
+0x3, 0x7c,0xbd,0x14,0x12,0xaa,0x97,0x7c,0xfb,0x7e,0xb3,0x3e,0x37,0x4, 0x7a,0xb3,
+0x3e,0x37,0x90,0x61,0xdb,0xe4,0x93,0x14,0x12,0xaa,0x97,0x7c,0xab,0xbe,0xa0,0xff,
+0x68,0x32,0xbe,0xf0,0xff,0x68,0x2b,0x7e,0x30,0xc, 0xac,0x3f,0x49,0x21,0x3e,0x4d,
+0x7e,0xf4,0x61,0xe2,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x30,0xbd,0x23,0x28,0x15,0x7e,
+0x70,0xc, 0xac,0x7a,0x49,0x33,0x3e,0x4d,0x3e,0x34,0xbd,0x23,0x28,0x6, 0x7c,0xfa,
+0x80,0x2, 0x7c,0xfa,0xbe,0xf0,0xff,0x78,0x11,0xe4,0x7a,0xb3,0x3e,0x37,0x7a,0xb3,
+0x3e,0x38,0x7a,0xb3,0x3e,0x44,0x74,0xff,0x80,0x6f,0x90,0x61,0xea,0xe4,0x93,0xbe,
+0xb3,0x3e,0x37,0x50,0x4f,0x74,0xc, 0xac,0xbf,0x49,0x25,0x3e,0x4d,0x7e,0x14,0x61,
+0xe2,0x12,0x8b,0x50,0xbd,0x23,0x50,0x34,0x7e,0x34,0x61,0xe8,0x12,0x2d,0x68,0xbe,
+0x37,0x3e,0x3e,0x50,0x27,0x74,0x5, 0xac,0xbf,0x9, 0x75,0x1f,0xa4,0xbe,0x73,0x24,
+0xed,0x68,0x19,0x7c,0xef,0xbe,0xe0,0x4, 0x50,0xc, 0x7e,0xb3,0x24,0xed,0x12,0xac,
+0x5c,0xbe,0xb0,0x4, 0x40,0x6, 0x74,0x1, 0x7a,0xb3,0x3e,0x3a,0xe4,0x7a,0xb3,0x3e,
+0x44,0x12,0x46,0xa3,0xbe,0xe0,0xff,0x68,0xe, 0xe4,0x7a,0xb3,0x3e,0x37,0x12,0x46,
+0xa3,0x6d,0x33,0x7a,0x37,0x3e,0x3e,0x7c,0xbe,0xda,0x79,0xda,0xd8,0x22,0x7e,0x73,
+0x20,0x66,0xbe,0x70,0x0, 0x22,0x7e,0x73,0x20,0x65,0xbe,0x70,0x0, 0x22,0x7e,0x73,
+0x22,0x3, 0xbe,0x70,0x0, 0x22,0x7e,0x33,0x3f,0x52,0x7e,0x34,0x60,0xde,0x22,0x90,
+0x61,0x2b,0xe4,0x93,0x7c,0xab,0xbe,0xa0,0x1, 0x22,0x6d,0x0, 0x7e,0x34,0xd0,0x0,
+0x7e,0x24,0x0, 0x7, 0x2, 0x27,0x66,0xca,0xd8,0xca,0x79,0x7e,0x74,0x2, 0x0, 0x7e,
+0x34,0x4, 0x0, 0x7e,0x8, 0x2c,0x49,0xe4,0x12,0x29,0x72,0x7e,0xb3,0x3f,0x3c,0xb4,
+0x1, 0x64,0x7e,0x73,0x3f,0x3d,0xbe,0x70,0x0, 0x28,0x5b,0x6c,0xdd,0x80,0x3c,0x12,
+0x48,0x8b,0x12,0x4b,0x7c,0x6d,0x33,0x80,0x28,0x7e,0x35,0x24,0x3e,0x34,0x49,0x33,
+0x13,0x1a,0x12,0x29,0xb4,0x7a,0x35,0x26,0x7e,0x35,0x24,0x7d,0x13,0x3e,0x14,0x49,
+0x21,0x2c,0x49,0xbe,0x25,0x26,0x58,0x7, 0x7e,0x25,0x26,0x59,0x21,0x2c,0x49,0xb,
+0x34,0x7a,0x35,0x24,0xbe,0x75,0x24,0x38,0xd0,0xb, 0xd0,0x7e,0x73,0x3f,0x3d,0xbc,
+0x7d,0x38,0xbc,0x7d,0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,0x2c,0x49,0x7e,0x8, 0x13,
+0x1a,0x12,0x29,0x4d,0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0x7e,0x34,0x3, 0xe8,0x6d,
+0x22,0x7a,0x27,0x3f,0xfa,0x7a,0x37,0x3f,0xfc,0x22,0x7e,0x34,0x60,0xab,0x12,0x2d,
+0x68,0x12,0x48,0x8f,0x12,0x3f,0x94,0x12,0x71,0x5f,0x74,0x1, 0x7a,0xb3,0x3, 0xc5,
+0x12,0x35,0xec,0x12,0x4b,0x1a,0x12,0xd0,0x89,0x12,0x71,0xb6,0x12,0x3d,0x99,0x12,
+0xab,0x40,0x7e,0xb3,0x24,0xed,0x2, 0x44,0x2b,0x7e,0xb3,0x3, 0xc3,0x14,0x68,0x64,
+0x14,0x78,0x2, 0x21,0x7d,0x14,0x68,0x77,0x24,0x3, 0x68,0x2, 0x21,0x72,0x12,0x4b,
+0x12,0x38,0xc, 0x30,0x10,0x13,0x7e,0xb3,0x3, 0xee,0xbe,0xb0,0x1, 0x68,0xa, 0x12,
+0x4b,0xb, 0xe4,0x7a,0xb3,0x40,0x38,0x21,0x7d,0x7e,0xb3,0x3, 0xa4,0x30,0xe0,0x7d,
+0x7e,0x73,0x3, 0xa5,0xa, 0x27,0x7e,0x34,0x4, 0x0, 0xad,0x32,0x7e,0xb3,0x3, 0xee,
+0xb4,0x1, 0xb, 0x7e,0x34,0x62,0x7a,0x12,0x2d,0x68,0x2e,0x34,0x4, 0x0, 0xbe,0x37,
+0x40,0x36,0x50,0x59,0x12,0x4b,0xb, 0x74,0x1, 0x7a,0xb3,0x3, 0xc3,0xe4,0x7a,0xb3,
+0x40,0x3a,0x80,0x49,0x12,0x4b,0x12,0x28,0x3f,0xe4,0x7a,0xb3,0x3, 0xc3,0x7e,0xb3,
+0x40,0x38,0xb4,0x1, 0x6, 0x74,0x1, 0x7a,0xb3,0x3, 0xc3,0xd2,0x17,0x80,0x29,0x74,
+0xff,0x7a,0xb3,0x3, 0x9d,0x7e,0x34,0x60,0xad,0x12,0x2d,0x68,0x12,0x48,0x8f,0x12,
+0x3f,0x2e,0x12,0x48,0x9a,0xe4,0x7a,0xb3,0x3, 0xc3,0x7a,0xb3,0x40,0x35,0xd2,0x17,
+0x80,0xb, 0x74,0x1, 0x7a,0xb3,0x3, 0xc3,0xe4,0x7a,0xb3,0x40,0x35,0x12,0x90,0xb4,
+0x2, 0x49,0x83,0xca,0x3b,0x7e,0xb3,0x3, 0xc3,0xb4,0x1, 0x2, 0x80,0x2, 0x61,0x8,
+0x6c,0xcc,0xc2,0x3, 0x7e,0xb3,0x3, 0xee,0xb4,0x1, 0xc, 0x90,0x61,0x72,0xe4,0x93,
+0x7c,0xeb,0x90,0x61,0x74,0x80,0xa, 0x90,0x61,0x71,0xe4,0x93,0x7c,0xeb,0x90,0x61,
+0x73,0xe4,0x93,0x7c,0xfb,0x12,0x91,0x94,0x7d,0xf3,0x12,0x4b,0x71,0x50,0xfb,0x74,
+0x1, 0x7a,0xb3,0x40,0x39,0x12,0x34,0x7d,0x12,0x5f,0xf5,0x74,0xa, 0x12,0x3e,0xa1,
+0x12,0xd1,0x24,0x7e,0x1f,0x24,0xe9,0x7a,0x1d,0x24,0x7e,0xd3,0x24,0xd6,0x74,0x4,
+0x7a,0xb3,0x24,0xd6,0x12,0xd0,0xb5,0x7e,0xb3,0x24,0xd6,0x12,0xc5,0xc9,0xa, 0x1b,
+0xad,0x1f,0x7e,0x34,0x0, 0x3, 0xad,0x31,0x12,0xf, 0xf5,0x1e,0x34,0x1e,0x34,0x7a,
+0x37,0x24,0xe3,0x12,0x5c,0xc2,0x41,0xe2,0xd2,0x4, 0x12,0x3f,0x15,0x12,0x48,0x8b,
+0x30,0xd, 0x2, 0x41,0xf0,0x7e,0xb3,0x3, 0xc5,0xb4,0x1, 0x2, 0x80,0x2, 0x41,0xf0,
+0x7c,0xbe,0x12,0x91,0xe0,0xe4,0x12,0x1d,0x89,0x12,0x5f,0x0, 0x12,0x5d,0xf2,0xa9,
+0xd1,0xcb,0x12,0x5d,0xde,0xc2,0x3, 0x80,0x42,0x30,0x19,0x33,0x20,0x3, 0x30,0xd2,
+0x4, 0x12,0x3f,0x15,0x12,0x8c,0xdb,0xd2,0x3, 0x7e,0x73,0x40,0xb, 0xa, 0x37,0x5e,
+0x34,0x0, 0x2, 0x68,0x6, 0x7e,0xb3,0x40,0x38,0x60,0x30,0xc2,0x4, 0x12,0x3f,0x15,
+0x80,0xd, 0x12,0x90,0x44,0xe4,0x12,0x90,0x4b,0x20,0x3, 0x3, 0x20,0x19,0x3, 0x20,
+0x93,0xf0,0x30,0x19,0x3, 0x30,0x3, 0x3, 0x12,0x90,0xdc,0x7e,0xb3,0x3, 0xc5,0xb4,
+0x1, 0x6, 0x30,0x17,0xb4,0x30,0x3, 0xb1,0x30,0x19,0xae,0x7e,0xa3,0x40,0x38,0x4c,
+0xaa,0x78,0x6, 0x74,0x1, 0x7a,0xb3,0x40,0x39,0x4c,0xaa,0x68,0xb, 0x7e,0xb3,0x3,
+0xee,0x70,0x5, 0xe4,0x7a,0xb3,0x40,0x38,0x7e,0x73,0x40,0xb, 0xa, 0x37,0x5e,0x34,
+0x0, 0x2, 0x78,0x15,0x7e,0xb3,0x40,0x38,0x60,0xf, 0xe4,0x7a,0xb3,0x40,0x38,0x7a,
+0xb3,0x23,0x87,0x7a,0xb3,0x23,0x88,0x80,0x27,0x7e,0x73,0x40,0xb, 0xa, 0x37,0x5e,
+0x34,0x0, 0x2, 0x68,0xd, 0x7e,0xb3,0x40,0x38,0x70,0x7, 0xe4,0x7a,0xb3,0x3, 0xc3,
+0x80,0xe, 0x7c,0xac,0xb, 0xc0,0xa, 0x2a,0xa, 0x3f,0xbd,0x23,0x58,0x2, 0x41,0x8,
+0xe4,0x7a,0xb3,0x24,0xe0,0x7e,0x1d,0x24,0x7a,0x1f,0x24,0xe9,0x7a,0xd3,0x24,0xd6,
+0xd2,0x4, 0x12,0x3f,0x15,0x12,0x3d,0x99,0xda,0x3b,0x22,0x6d,0x33,0x7a,0x37,0x40,
+0x36,0x22,0x7e,0x73,0x23,0x87,0xbe,0x70,0x0, 0x22,0x7e,0x34,0xd, 0xac,0x12,0x48,
+0x8f,0x12,0x5e,0x3c,0x12,0x4b,0x4b,0x2, 0x4b,0x2a,0x30,0xf, 0x8, 0x12,0x5a,0x71,
+0x12,0xac,0xcd,0xc2,0xf, 0x22,0x12,0x4b,0x71,0x50,0xfb,0x12,0xd0,0x89,0x12,0x4b,
+0xb, 0x7a,0x37,0x40,0x32,0x12,0x4b,0x1a,0x2, 0x3d,0x99,0x7e,0xb3,0x24,0xfc,0x70,
+0x1f,0x12,0x48,0x8b,0x12,0x4b,0x71,0x50,0xfb,0x12,0x5a,0x71,0x12,0x88,0x19,0x20,
+0xf, 0x3, 0x12,0xac,0xcd,0x74,0x2, 0x7a,0xb3,0x24,0xfc,0xe4,0x7a,0xb3,0x1f,0x5d,
+0x22,0x7e,0xb3,0x3f,0xe5,0xb4,0x1, 0x2, 0xc3,0x22,0xd3,0x22,0xca,0x3b,0x12,0x4b,
+0x71,0x50,0xfb,0x7e,0xf3,0x24,0xed,0x7c,0xbf,0x12,0xa7,0x1e,0x12,0xa5,0xd1,0x12,
+0xa4,0xdb,0x7e,0xb3,0x24,0xfd,0xf5,0x28,0x7e,0xc3,0x24,0xfe,0x7e,0xb3,0x3, 0xc5,
+0xb4,0x1, 0xf, 0x12,0x43,0xdd,0x7e,0xb3,0x1f,0x5d,0x70,0x6, 0x12,0x3d,0x99,0xc3,
+0x81,0x74,0x12,0x4d,0x6b,0x3e,0x34,0xca,0x39,0x7e,0x18,0x7, 0x2c,0x7e,0x8, 0x4,
+0x86,0x12,0x29,0x4d,0x1b,0xfd,0x12,0x4d,0x6b,0x3e,0x34,0xca,0x39,0x7e,0x18,0x8,
+0xbe,0x7e,0x8, 0x4, 0x0, 0x12,0x29,0x4d,0x1b,0xfd,0x7e,0xb3,0x3, 0xc5,0xb4,0x3,
+0x7, 0x12,0xa7,0xf7,0x7a,0x37,0x3f,0x68,0x74,0x1, 0x7a,0xb3,0x1f,0x5c,0x12,0x4b,
+0x21,0x12,0xa7,0xe3,0x12,0x3d,0x99,0x7e,0x8, 0x4, 0x86,0x7a,0xd, 0x29,0x7e,0x18,
+0x6, 0x9e,0x7e,0xb3,0x25,0x6e,0x12,0xc6,0xa9,0x7e,0x8, 0x4, 0x0, 0x7a,0xd, 0x29,
+0x7e,0x18,0x6, 0x18,0x7e,0xb3,0x1f,0x61,0x12,0xc6,0xa9,0x7e,0xd3,0x24,0xfd,0x7e,
+0xe3,0x24,0xfe,0xe5,0x28,0x7a,0xb3,0x24,0xfd,0x7a,0xc3,0x24,0xfe,0x7e,0x34,0xa,
+0x62,0x7e,0x4, 0x13,0x1a,0x7d,0x20,0x7d,0x10,0x12,0x5b,0xd6,0x7a,0xd3,0x24,0xfd,
+0x7a,0xe3,0x24,0xfe,0x7c,0xbf,0x12,0xab,0xfc,0x12,0xa7,0x88,0x7e,0xb3,0x40,0x35,
+0x4, 0x7a,0xb3,0x40,0x35,0x7e,0x73,0x40,0x35,0xbe,0x70,0xfa,0x28,0x6, 0x74,0x64,
+0x7a,0xb3,0x40,0x35,0x7e,0xb3,0x1f,0x5c,0x60,0x9, 0x7e,0xb3,0x1f,0x5d,0x60,0x3,
+0xd3,0x80,0x1, 0xc3,0xda,0x3b,0x22,0x12,0x4b,0x36,0x7e,0xb3,0x3, 0xc5,0xb4,0x1,
+0x62,0x12,0xc2,0x82,0x7e,0x34,0x60,0xad,0x12,0x2d,0x68,0x12,0x48,0x8f,0x12,0x91,
+0x9b,0x12,0x3e,0x1b,0x12,0x4b,0x7c,0x50,0xe1,0x12,0xa1,0xda,0x7e,0xb3,0x3, 0xc2,
+0xb4,0x1, 0x4, 0xe4,0x12,0x81,0x15,0x12,0x4f,0x83,0x12,0x63,0x5, 0x40,0xcb,0x12,
+0x88,0x59,0x12,0x63,0x5, 0x40,0xc3,0x12,0x4e,0x32,0x12,0x4d,0x7a,0x12,0x7e,0x5b,
+0x12,0x5f,0xfc,0x12,0x93,0xe1,0x12,0x72,0x59,0x12,0x76,0x4a,0x12,0x81,0x28,0x12,
+0x97,0x3f,0x12,0x8d,0x5f,0x12,0x7e,0xd9,0x12,0x62,0xef,0x12,0x91,0x74,0x12,0x62,
+0xbf,0x80,0x97,0x12,0x4e,0x2c,0x2, 0x4c,0xe9,0x7e,0xb3,0x3, 0xc2,0xb4,0x1, 0x4,
+0xe4,0x2, 0x81,0x15,0x22,0x12,0x3d,0x6c,0x7e,0xb3,0x3, 0xc5,0xb4,0x3, 0x66,0x12,
+0xc2,0x82,0x12,0x48,0x8b,0x12,0x37,0xfc,0x7e,0xb3,0x3f,0x21,0x30,0xe7,0xe9,0x12,
+0x4b,0x7c,0x12,0x4d,0x6b,0x3e,0x34,0xca,0x39,0x7e,0x18,0x4, 0x0, 0x7e,0x8, 0x5,
+0xc, 0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x73,0x24,0x40,0xa, 0x37,0x3e,0x34,0xca,0x39,
+0x7e,0x18,0x4, 0x86,0x7e,0x8, 0x5, 0x92,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0xb3,0x24,
+0xfb,0xb4,0x1, 0x12,0x12,0xa1,0xda,0x12,0x4f,0x83,0x12,0x88,0x59,0x12,0x4e,0x32,
+0x12,0x4d,0x7a,0x12,0x48,0x7, 0x12,0x57,0xfb,0x7e,0xb3,0x3f,0x21,0x54,0x7f,0x7a,
+0xb3,0x3f,0x21,0x80,0x93,0x12,0x4e,0x2c,0x2, 0x3f,0xe4,0x7e,0x73,0x24,0x40,0xa,
+0x27,0x7e,0x73,0x24,0x3f,0xa, 0x37,0x2d,0x32,0x22,0x12,0x6f,0x9d,0x12,0x4d,0xe7,
+0x12,0x4d,0xe7,0x12,0x67,0xaa,0x12,0x4d,0xe7,0x12,0x63,0x25,0x12,0x4d,0xe7,0x12,
+0x55,0x7b,0x12,0x68,0x78,0x2, 0x4d,0x98,0x7e,0xa3,0x21,0xf5,0xe4,0x7a,0xb3,0x3b,
+0x83,0x6c,0x33,0x80,0x3d,0x7e,0x70,0x2, 0xac,0x73,0x9, 0x23,0x20,0x6c,0x7e,0x10,
+0x1, 0x6c,0x0, 0x80,0x27,0xbc,0x3, 0x68,0x21,0x7e,0x70,0x2, 0xac,0x70,0x9, 0x93,
+0x20,0x6c,0xa, 0x29,0xa, 0x32,0x12,0x6c,0x4b,0x18,0x2, 0xb, 0x10,0xbe,0x10,0x2,
+0x40,0x8, 0x74,0x2, 0x7a,0xb3,0x3b,0x83,0x80,0x6, 0xb, 0x0, 0xbc,0xa0,0x38,0xd5,
+0xb, 0x30,0xbc,0xa3,0x38,0xbf,0x22,0xca,0x79,0x6c,0xff,0x6c,0xee,0x80,0x31,0x7c,
+0xbe,0x12,0x55,0x62,0x60,0x28,0x7e,0x34,0x0, 0x2, 0xca,0x39,0xac,0x7e,0x2e,0x34,
+0x20,0x6b,0x6d,0x22,0x7e,0x30,0x2, 0xac,0x3f,0x2e,0x14,0x20,0x6b,0x6d,0x0, 0x12,
+0x29,0x4d,0x1b,0xfd,0x7c,0xbf,0x7e,0x70,0x1, 0x12,0x65,0xe0,0xb, 0xf0,0xb, 0xe0,
+0x12,0x6f,0x96,0x38,0xca,0x7a,0xf3,0x21,0xf5,0xda,0x79,0x22,0x12,0x4b,0x71,0x50,
+0xfb,0x22,0x12,0x4e,0x3a,0x7a,0xb3,0x23,0x91,0x22,0xca,0x3b,0x6d,0xee,0x7e,0xc3,
+0x24,0x3a,0x7e,0xd3,0x24,0x39,0x7e,0xb3,0x3, 0xee,0xb4,0x1, 0x3, 0xe4,0xe1,0x69,
+0x7e,0xb3,0x21,0xf5,0x70,0x2, 0xc1,0xd7,0x7e,0xb3,0x23,0x88,0x60,0x2, 0x80,0x77,
+0x7e,0xa3,0x20,0x6b,0x7e,0x73,0x20,0x6c,0x7a,0x71,0x24,0x6c,0xee,0x6d,0xff,0x6c,
+0xff,0xa, 0x47,0x80,0x1c,0x12,0xaf,0xf1,0x8, 0x1d,0xb, 0xe0,0xbe,0xa0,0x0, 0x28,
+0x6, 0x7c,0xba,0x14,0x12,0x4f,0x79,0x12,0xd1,0x1b,0x58,0x3, 0x12,0x4f,0x76,0x1b,
+0x44,0xbe,0x44,0x0, 0x0, 0x58,0xde,0xe5,0x24,0xa, 0x4b,0x80,0x1a,0x12,0xaf,0xf1,
+0x8, 0x21,0xb, 0xe0,0xbe,0xa0,0x0, 0x28,0x6, 0x7c,0xba,0x14,0x12,0x4f,0x79,0x12,
+0xd1,0x1b,0x58,0x3, 0x12,0x4f,0x76,0x7d,0x24,0xb, 0x24,0x7d,0x42,0xa, 0x3c,0xbd,
+0x23,0x48,0xda,0xbe,0xe0,0x3, 0x50,0x2, 0x80,0xd, 0xa, 0x2f,0x7d,0x3f,0x12,0x26,
+0xc7,0xbe,0x34,0x0, 0x28,0x8, 0x7, 0xe4,0x7a,0xb3,0x3c,0x1e,0xe1,0x69,0x6d,0xdd,
+0xbe,0xa0,0x0, 0x28,0x8, 0x7c,0xba,0x14,0x12,0x4f,0x6c,0x2d,0xd3,0xa, 0x3d,0x1b,
+0x34,0xa, 0xca,0xbd,0xc3,0x58,0xb, 0x7c,0xba,0x4, 0x7e,0x71,0x24,0x12,0x4f,0x6f,
+0x2d,0xd3,0x7e,0x70,0x8, 0x80,0x25,0x7e,0x50,0x2, 0xac,0x57,0x7d,0xc2,0x2e,0xc4,
+0x29,0x94,0x7d,0x1c,0x12,0xd1,0x9, 0x1a,0xcb,0xbd,0xcd,0x8, 0xf, 0x7d,0xc2,0x2e,
+0xc4,0x29,0x95,0x7d,0x2c,0x12,0x7a,0xb8,0x1a,0xcb,0x2d,0xec,0x7c,0x67,0x1b,0x70,
+0xa5,0xbe,0x0, 0xd3,0x7c,0xba,0x7e,0x71,0x24,0x12,0x4f,0x6f,0x12,0x29,0xb4,0xbe,
+0x34,0xa, 0xf0,0x8, 0x4, 0x2e,0xe4,0x0, 0x28,0xbe,0xe4,0x0, 0xfa,0x28,0x4, 0x7e,
+0xe4,0x0, 0xfa,0x7e,0xb3,0x3c,0x1e,0xa, 0x3b,0xbd,0x3e,0x50,0x8, 0x7d,0x3e,0x7c,
+0xb7,0x7a,0xb3,0x3c,0x1e,0x7e,0xb3,0x3c,0x1e,0xda,0x3b,0x22,0x7e,0x71,0x24,0x12,
+0x57,0xe5,0xb, 0x1a,0x30,0x22,0x7c,0xba,0x4, 0x7c,0x79,0x12,0x4f,0x6f,0x2d,0xf3,
+0xb, 0xf0,0x22,0x12,0x2d,0xe1,0xe4,0x7a,0xb3,0x40,0x3f,0x2, 0x4f,0x8e,0xca,0x3b,
+0xe4,0x7a,0xb3,0x22,0x4, 0x12,0xc7,0x86,0x7e,0xb3,0x1f,0x5d,0xb4,0x1, 0x8, 0x7e,
+0x73,0x21,0xf5,0x7a,0x73,0x22,0x3, 0x7e,0x18,0x5, 0xc, 0x7a,0x1f,0x7, 0x28,0x12,
+0xd0,0xac,0x12,0x51,0xe6,0x7e,0x73,0x1f,0xf6,0xbe,0x70,0x2, 0x50,0x3, 0x2, 0x50,
+0x59,0x6c,0xff,0x2, 0x50,0x48,0xa, 0x5f,0xb, 0x54,0x7c,0xab,0x6c,0xee,0x80,0xc,
+0xa, 0x3e,0x9, 0xb3,0x1f,0xe0,0xbc,0xbf,0x68,0xa, 0xb, 0xe0,0x7e,0xb3,0x1f,0xf6,
+0xbc,0xbe,0x38,0xec,0x7e,0x33,0x1f,0xf6,0xbc,0x3e,0x68,0x5a,0x6c,0xee,0x80,0x12,
+0xa, 0x3e,0x9, 0x23,0x1f,0xe0,0xa, 0x22,0xa, 0x3f,0xb, 0x35,0xbd,0x23,0x68,0x6,
+0xb, 0xe0,0xbc,0x3e,0x38,0xea,0xbc,0x3e,0x78,0x4, 0xb, 0xf1,0x80,0x38,0x12,0x53,
+0x72,0x7f,0x75,0x1b,0xf5,0xb, 0x7a,0x30,0x7e,0xc4,0x0, 0x3, 0x12,0x53,0x50,0xb,
+0x5a,0x40,0xbd,0x43,0x8, 0x20,0x69,0x5, 0x0, 0x2, 0x7d,0x30,0x12,0x53,0x35,0xbd,
+0x43,0x8, 0x13,0xb, 0x7a,0x40,0x2d,0x40,0x12,0x51,0xda,0xb, 0x1a,0x30,0x9d,0x43,
+0x12,0x51,0xda,0x1b,0x1a,0x40,0xb, 0xf0,0x7e,0x23,0x24,0x3a,0xa, 0x22,0x1b,0x25,
+0xa, 0x3f,0xbd,0x32,0x58,0x3, 0x2, 0x4f,0xc6,0x7e,0x73,0x1f,0xf5,0xbe,0x70,0x2,
+0x50,0x2, 0x1, 0xfb,0x6c,0xff,0x1, 0xf1,0xa, 0x1f,0x7e,0x73,0x24,0x3a,0xa, 0x57,
+0x2d,0x51,0xb, 0x54,0x7c,0xab,0x6c,0xee,0x80,0xc, 0xa, 0xe, 0x9, 0xb0,0x1f,0xcc,
+0xbc,0xbf,0x68,0xa, 0xb, 0xe0,0x7e,0xb3,0x1f,0xf5,0xbc,0xbe,0x38,0xec,0x7e,0x13,
+0x1f,0xf5,0xbc,0x1e,0x68,0x59,0x6c,0xee,0x80,0x12,0xa, 0x3e,0x9, 0x3, 0x1f,0xcc,
+0xa, 0x20,0x7d,0x31,0xb, 0x35,0xbd,0x23,0x68,0x6, 0xb, 0xe0,0xbc,0x1e,0x38,0xea,
+0xbc,0x1e,0x78,0x4, 0xb, 0xf1,0x80,0x37,0x12,0x53,0x72,0x7f,0x15,0x1b,0x35,0xb,
+0x1a,0xf0,0x7e,0xc4,0x0, 0x3, 0x7d,0x3f,0x12,0x53,0x50,0xb, 0x5a,0xe0,0xbd,0xe3,
+0x8, 0x1d,0x69,0x45,0x0, 0x2, 0x7d,0x34,0x12,0x53,0x35,0xbd,0xe3,0x8, 0x10,0x2d,
+0x4f,0x12,0x53,0x66,0xb, 0x1a,0x30,0x9d,0x43,0x12,0x53,0x66,0x1b,0x1a,0x40,0xb,
+0xf0,0x7e,0x3, 0x24,0x39,0xbc,0xf, 0x28,0x2, 0x1, 0x68,0x12,0x51,0xe6,0x6c,0xff,
+0x80,0x47,0xa, 0x4f,0x9, 0xb4,0x1f,0xe0,0x7c,0xab,0xbe,0xb0,0x2, 0x40,0x12,0x12,
+0x53,0xd5,0x8, 0xd, 0x12,0x53,0xc0,0x8, 0x8, 0x12,0x53,0x7e,0x2d,0x31,0x1b,0x1a,
+0x40,0xa, 0x3f,0x9, 0xb3,0x1f,0xe0,0xa, 0x2b,0x7e,0xb3,0x24,0x3a,0xa, 0x3b,0x1b,
+0x35,0xbd,0x23,0x58,0x12,0x12,0x53,0xab,0x8, 0xd, 0x12,0x53,0x9b,0xbd,0x30,0x8,
+0x6, 0x12,0x51,0xd6,0x1b,0x1a,0x10,0xb, 0xf0,0x7e,0xb3,0x1f,0xf6,0xbc,0xbf,0x38,
+0xb1,0x6c,0xff,0x80,0x51,0xa, 0x4f,0x9, 0xb4,0x1f,0xcc,0xa, 0x2b,0x7e,0xa3,0x24,
+0x3a,0xa, 0x3a,0x2d,0x32,0x7c,0xa7,0xbe,0xb0,0x2, 0x40,0x12,0x12,0x53,0xd5,0x8,
+0xd, 0x12,0x53,0xc0,0x8, 0x8, 0x12,0x53,0x7e,0x2d,0x31,0x1b,0x1a,0x40,0xa, 0x3f,
+0x9, 0xb3,0x1f,0xcc,0xa, 0x2b,0x7e,0xb3,0x24,0x39,0xa, 0x3b,0x1b,0x35,0xbd,0x23,
+0x58,0x12,0x12,0x53,0xab,0x8, 0xd, 0x12,0x53,0x9b,0xbd,0x30,0x8, 0x6, 0x12,0x51,
+0xd6,0x1b,0x1a,0x10,0xb, 0xf0,0x7e,0xb3,0x1f,0xf5,0xbc,0xbf,0x38,0xa7,0x12,0x51,
+0xe6,0x12,0x54,0x6, 0x7e,0xb3,0x1f,0x5c,0xb4,0x1, 0x18,0x7e,0x73,0x1f,0xf4,0x7a,
+0x73,0x20,0x64,0x7e,0x73,0x1f,0xf6,0x7a,0x73,0x20,0x66,0x7e,0x73,0x1f,0xf5,0x7a,
+0x73,0x20,0x65,0xda,0x3b,0x22,0x79,0x7, 0x0, 0x2, 0x7e,0x10,0x2, 0xac,0x1a,0x7e,
+0x1f,0x7, 0x28,0x2d,0x30,0x22,0x7e,0x8, 0x1f,0xf7,0x7e,0x34,0x0, 0x3, 0xe4,0x12,
+0x29,0x72,0x7e,0x8, 0x1f,0xfa,0x7e,0x34,0x0, 0x3, 0x12,0x29,0x72,0x7a,0xb3,0x1f,
+0xf4,0x7a,0xb3,0x1f,0xf5,0x7a,0xb3,0x1f,0xf6,0x7a,0xb3,0x20,0x61,0x7a,0xb3,0x20,
+0x62,0x7a,0xb3,0x20,0x63,0x7e,0x18,0x1f,0xe0,0x12,0x53,0x8b,0x6c,0x55,0x12,0x52,
+0xac,0x7a,0xb3,0x1f,0xf6,0x7e,0x18,0x1f,0xcc,0x12,0x53,0xed,0x6c,0x55,0x12,0x52,
+0xac,0x7a,0xb3,0x1f,0xf5,0x6c,0x77,0x80,0x14,0x12,0x53,0x3c,0x60,0x5, 0x3e,0x24,
+0x14,0x78,0xfb,0x12,0x53,0x45,0x2e,0x24,0x1f,0xf7,0x12,0x53,0x5b,0x7e,0x63,0x1f,
+0xf5,0xbc,0x67,0x38,0xe4,0x6c,0x77,0x80,0x14,0x12,0x53,0x3c,0x60,0x5, 0x3e,0x24,
+0x14,0x78,0xfb,0x12,0x53,0x45,0x2e,0x24,0x1f,0xfa,0x12,0x53,0x5b,0x7e,0xa3,0x1f,
+0xf6,0xbc,0xa7,0x38,0xe4,0x7e,0xb3,0x1f,0xf5,0xa4,0x7a,0xb3,0x1f,0xf4,0x7e,0x18,
+0x20,0x57,0x12,0x53,0x8b,0x7e,0x50,0x1, 0x12,0x52,0xac,0x7a,0xb3,0x20,0x63,0x7e,
+0x18,0x20,0x4d,0x12,0x53,0xed,0x7e,0x50,0x1, 0x12,0x52,0xac,0x7c,0xab,0x7a,0xa3,
+0x20,0x62,0x7e,0xb3,0x20,0x63,0xa4,0x7a,0xb3,0x20,0x61,0x22,0xca,0x69,0xca,0xf8,
+0x7c,0x4b,0x6c,0xaa,0x6d,0xff,0x6c,0xff,0x80,0x70,0x7e,0xd0,0x2, 0xac,0xdf,0x7f,
+0x60,0x2d,0xd6,0xb, 0x6a,0xe0,0x4c,0x55,0x68,0x6, 0x6e,0xe4,0xff,0xff,0xb, 0xe4,
+0xbd,0x3e,0x58,0x54,0x4c,0xff,0x78,0x8, 0x6d,0x44,0x69,0xf0,0x0, 0x2, 0x80,0x1b,
+0x7c,0xb4,0x14,0xbc,0xbf,0x7f,0x56,0x78,0x9, 0x1b,0xb5,0xb, 0x5a,0x40,0x6d,0xff,
+0x80,0x9, 0x1b,0xb5,0xb, 0x5a,0x40,0x69,0xf6,0x0, 0x2, 0x4c,0x55,0x68,0xc, 0x6e,
+0x44,0xff,0xff,0xb, 0x44,0x6e,0xf4,0xff,0xff,0xb, 0xf4,0xbd,0x4e,0x58,0x19,0xbd,
+0xfe,0x18,0x15,0xa, 0xba,0x7e,0x6d,0x24,0x2d,0xdb,0x7a,0x6b,0xf0,0xb, 0xa0,0x90,
+0x60,0xa3,0xe4,0x93,0xbc,0xba,0x28,0x6, 0xb, 0xf0,0xbc,0x4f,0x38,0x8c,0x7c,0xba,
+0xda,0xf8,0xda,0x69,0x22,0xad,0x3c,0x7d,0x2d,0x2, 0x26,0xc7,0x7c,0xb7,0x54,0x7,
+0x7e,0x24,0x0, 0x1, 0x22,0x7c,0xa5,0x7c,0xb7,0xc4,0x23,0x54,0x1f,0xa, 0x2b,0x22,
+0xad,0x3c,0x7e,0xd4,0x0, 0x4, 0x7d,0x2d,0x2, 0x26,0xc7,0x7e,0x29,0x60,0x4c,0x6a,
+0x7a,0x29,0x60,0xb, 0x70,0x22,0x7e,0xd0,0x2, 0xac,0xda,0x7e,0x1f,0x7, 0x28,0x2d,
+0x36,0x22,0x7e,0x70,0x2, 0xac,0x7a,0x7e,0x5f,0x7, 0x28,0x2d,0xb3,0x22,0x1b,0xa,
+0xf0,0x7e,0x30,0x2, 0xac,0x3a,0x7e,0x1f,0x7, 0x28,0x22,0x7a,0x1d,0x24,0x7e,0xf,
+0x7, 0x28,0x7e,0xb3,0x24,0x3a,0x7e,0x37,0x24,0x1f,0x22,0x69,0x17,0x0, 0x2, 0x7e,
+0x24,0x0, 0xa, 0x7d,0x31,0x12,0x26,0xc7,0x2d,0x31,0x22,0x7e,0x70,0x2, 0xac,0x7a,
+0x7e,0x7f,0x7, 0x28,0x2d,0xf3,0xb, 0x7a,0x0, 0x69,0x17,0x0, 0x4, 0xbd,0x10,0x22,
+0x1b,0x15,0xb, 0xa, 0x40,0x7e,0x24,0x0, 0xa, 0x7d,0x34,0x12,0x26,0xc7,0x7d,0xe4,
+0x2d,0xe3,0xbd,0xef,0x22,0x7e,0x70,0x2, 0xac,0x7a,0x7e,0xf, 0x7, 0x28,0x2d,0x13,
+0x7f,0x10,0x1b,0x36,0xb, 0x1a,0xe0,0xb, 0xa, 0xf0,0xbd,0xef,0x22,0x7a,0x1d,0x24,
+0x7e,0xa3,0x24,0x3a,0x74,0x2, 0xa4,0x7e,0xf, 0x7, 0x28,0x2d,0x15,0x7e,0xb3,0x24,
+0x39,0x7e,0x37,0x24,0x1d,0x22,0xca,0x3b,0x7e,0xd4,0x7f,0xff,0x7d,0x1d,0x7d,0xd,
+0x6d,0x22,0x7d,0x32,0x6c,0x88,0x6c,0xaa,0x7e,0x78,0x5, 0xc, 0x7e,0x58,0x5, 0x92,
+0xe4,0x7a,0xb3,0xa, 0x60,0x7a,0xb3,0xa, 0x61,0x7a,0xb3,0x20,0x67,0x7a,0xb3,0x20,
+0x69,0x7a,0xb3,0x20,0x68,0x7a,0xb3,0x20,0x6a,0x6c,0x99,0x80,0x6a,0x12,0x55,0x58,
+0xb, 0x4a,0xc0,0xbd,0xc1,0x58,0x2, 0x7d,0x1c,0xbd,0xc3,0x8, 0x2, 0x7d,0x3c,0x7f,
+0x45,0x2d,0x97,0xb, 0x4a,0x90,0xbd,0x9d,0x58,0x2, 0x7d,0xd9,0x7e,0x87,0x24,0x1f,
+0x7e,0x94,0x0, 0x3, 0xad,0x98,0xbd,0xc9,0x8, 0x2, 0xb, 0x80,0x12,0x55,0x58,0xb,
+0x4a,0x90,0x7e,0x74,0x62,0x26,0x7e,0x64,0x0, 0xff,0xb, 0x3a,0xc0,0xbd,0x9c,0x8,
+0xb, 0x7e,0xb3,0x20,0x68,0x4, 0x7a,0xb3,0x20,0x68,0x80,0x19,0x12,0x55,0x58,0xb,
+0x4a,0x90,0x6e,0xc4,0xff,0xff,0xb, 0xc4,0xbd,0x9c,0x58,0x9, 0x7e,0xb3,0x20,0x6a,
+0x4, 0x7a,0xb3,0x20,0x6a,0xb, 0x90,0x7e,0xb3,0x24,0x40,0xbc,0xb9,0x38,0x8e,0x7a,
+0x17,0xa, 0x56,0x7a,0x37,0xa, 0x5a,0x7a,0x83,0xa, 0x61,0x7a,0xd7,0xa, 0x5e,0x7e,
+0xb3,0x24,0x40,0x7e,0x90,0x2, 0xac,0x9b,0x2d,0xf4,0x6c,0x99,0x80,0x5f,0x12,0x57,
+0xdd,0x2d,0xd7,0xb, 0x6a,0xc0,0xbd,0xc0,0x58,0x2, 0x7d,0xc, 0xbd,0xc2,0x8, 0x2,
+0x7d,0x2c,0x7e,0xa7,0x24,0x1d,0x7e,0xb4,0x0, 0x3, 0xad,0xba,0xbd,0xcb,0x8, 0x2,
+0xb, 0xa0,0x7e,0xb4,0x62,0x26,0x7e,0xa4,0x0, 0xff,0xb, 0x5a,0xd0,0xbd,0xcd,0x8,
+0xb, 0x7e,0xb3,0x20,0x67,0x4, 0x7a,0xb3,0x20,0x67,0x80,0x1f,0x7e,0xf0,0x2, 0xac,
+0xf9,0x7f,0x57,0x2d,0xb7,0xb, 0x5a,0xc0,0x6e,0xd4,0xff,0xff,0xb, 0xd4,0xbd,0xcd,
+0x58,0x9, 0x7e,0xb3,0x20,0x69,0x4, 0x7a,0xb3,0x20,0x69,0xb, 0x90,0x7e,0xb3,0x24,
+0x3f,0xbc,0xb9,0x38,0x99,0x7a,0x7, 0xa, 0x54,0x7a,0x27,0xa, 0x58,0x7a,0xa3,0xa,
+0x60,0xbd,0x1, 0x58,0x2, 0x7d,0x10,0x7a,0x17,0xa, 0x50,0xbd,0x32,0x58,0x2, 0x7d,
+0x32,0x7a,0x37,0xa, 0x52,0xda,0x3b,0x22,0x7e,0xf0,0x2, 0xac,0xf9,0x7f,0x47,0x2d,
+0x97,0x22,0x7c,0x7b,0x12,0x53,0x49,0x9, 0xa2,0x20,0xe3,0x7c,0xb7,0x54,0x7, 0xa,
+0x3b,0x2e,0x34,0x0, 0x4e,0x12,0x57,0xbb,0x5c,0xba,0x22,0xca,0x3b,0x75,0x24,0x0,
+0x6c,0xcc,0x6c,0xdd,0x7e,0xc4,0x0, 0x3c,0xca,0xc9,0x7e,0x18,0x3d,0x79,0x7e,0x8,
+0x3d,0x3d,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0xf3,0x21,0xf5,0xa, 0xcf,0x3e,0xc4,0xca,
+0xc9,0x7e,0x18,0x20,0x6b,0x7e,0x8, 0x31,0xbb,0x12,0x29,0x4d,0x1b,0xfd,0x6c,0x88,
+0x6c,0xee,0xc1,0x4f,0x7e,0xc4,0x3, 0xff,0x7e,0xc0,0xff,0x6c,0x99,0x80,0x4c,0x74,
+0x2, 0xac,0xb9,0x9, 0xb5,0x31,0xbb,0xbe,0xb0,0xff,0x68,0x3d,0x7c,0xb9,0x12,0x55,
+0x62,0x60,0x36,0x74,0x2, 0xac,0xb9,0x9, 0x75,0x31,0xbc,0xa, 0x27,0x74,0x2, 0xac,
+0xbe,0x9, 0x75,0x3d,0x7a,0x12,0x57,0x74,0x7d,0x13,0x74,0x2, 0xac,0xb9,0x9, 0x75,
+0x31,0xbb,0xa, 0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x3d,0x79,0x12,0x57,0x74,0x2d,
+0x13,0xbd,0xc1,0x28,0x4, 0x7d,0xc1,0x7c,0xc9,0xb, 0x90,0xbc,0xf9,0x38,0xb0,0xbe,
+0xc0,0xff,0x68,0x39,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x31,0xbb,0x9, 0x73,0x31,
+0xbc,0x12,0x4f,0x6f,0xbe,0x37,0x24,0x26,0x48,0x23,0x7e,0x70,0x2, 0xac,0x7c,0x9,
+0x53,0x31,0xbb,0x74,0x2, 0xac,0xbd,0x19,0x55,0x31,0xf7,0x9, 0x53,0x31,0xbc,0x19,
+0x55,0x31,0xf8,0x74,0xff,0x19,0xb3,0x31,0xbb,0xb, 0x80,0xb, 0xd0,0xb, 0xe0,0x7e,
+0x73,0x3d,0x33,0xbc,0x7e,0x28,0x2, 0xa1,0xb4,0x7c,0xe8,0x80,0x7c,0x7e,0x80,0xff,
+0x12,0x9b,0xcd,0x7d,0xd3,0x6c,0x99,0x80,0x48,0x7c,0xb9,0x12,0x55,0x62,0x60,0x3f,
+0x7e,0x70,0x2, 0xac,0x79,0x9, 0xb3,0x31,0xbb,0xbe,0xb0,0xff,0x68,0x31,0x9, 0x73,
+0x31,0xbc,0x12,0x57,0xe5,0x7f,0x71,0xb, 0x7a,0x50,0xbe,0x54,0x0, 0x0, 0x58,0x5,
+0x6d,0x55,0x1b,0x7a,0x50,0xb, 0x7a,0xc0,0xbd,0xcd,0x8, 0x13,0x7e,0x70,0x2, 0xac,
+0x79,0x9, 0xb3,0x31,0xbb,0xf5,0x24,0x9, 0xc3,0x31,0xbc,0x7d,0xdc,0x7c,0x89,0xb,
+0x90,0xbc,0xf9,0x38,0xb4,0xbe,0x80,0xff,0x68,0x1d,0x7e,0x71,0x24,0x74,0x2, 0xac,
+0xbd,0x19,0x75,0x31,0xf7,0x19,0xc5,0x31,0xf8,0x7e,0xa0,0xff,0x7e,0x70,0x2, 0xac,
+0x78,0x19,0xa3,0x31,0xbb,0xb, 0xd0,0xb, 0xe0,0x90,0x60,0xa1,0xe4,0x93,0xbc,0xbe,
+0x28,0x2, 0xc1,0x5d,0x90,0x60,0xa2,0xe4,0x93,0x7c,0xab,0x74,0x2, 0xa4,0xca,0x59,
+0x7e,0x18,0x31,0xf7,0x7e,0x8, 0x31,0xbb,0x12,0x29,0x4d,0x1b,0xfd,0x7c,0xfd,0x12,
+0x57,0x62,0x7e,0x8, 0x3d,0x79,0x74,0xff,0x12,0x29,0x72,0xbe,0xf0,0x0, 0x28,0x38,
+0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x18,0x31,0xbb,0x7e,0x8, 0x20,0x6b,0x12,0x29,
+0x4d,0x1b,0xfd,0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x18,0x31,0xbb,0x7e,0x8, 0x3d,
+0x79,0x12,0x29,0x4d,0x1b,0xfd,0x6c,0xee,0x80,0xa, 0x7c,0xbe,0x7e,0x70,0x1, 0x12,
+0x65,0xe0,0xb, 0xe0,0xbc,0xfe,0x38,0xf2,0x7a,0xf3,0x3d,0x33,0x7a,0xf3,0x21,0xf5,
+0x90,0x60,0xa1,0xe4,0x93,0xbe,0xb3,0x21,0xf5,0x50,0x4, 0x7a,0xb3,0x21,0xf5,0xda,
+0x3b,0x22,0x90,0x60,0xa1,0xe4,0x93,0x7c,0x7b,0x74,0x2, 0xac,0x7b,0x22,0xa, 0x27,
+0x7e,0x73,0x1f,0xcc,0xa, 0x37,0x9d,0x32,0x2, 0x29,0xb4,0x12,0x57,0x62,0x7e,0x8,
+0x3b,0x90,0xe4,0x12,0x29,0x72,0x90,0x60,0xa1,0x12,0x57,0x66,0x7e,0x8, 0x3b,0x63,
+0xe4,0x2, 0x29,0x72,0x7c,0x7b,0x12,0x53,0x49,0x9, 0xa2,0x1f,0xfa,0x7c,0xb7,0x54,
+0x7, 0xa, 0x3b,0x2e,0x34,0x0, 0x4e,0x12,0x57,0xbb,0x5c,0xba,0x22,0x7e,0x1d,0x27,
+0x2d,0x3f,0x7e,0x1b,0x80,0xa, 0x38,0x2e,0x34,0x29,0x29,0x7a,0x71,0x82,0x7a,0x61,
+0x83,0xe4,0x93,0x22,0x7c,0x7b,0x12,0x53,0x49,0x9, 0xa2,0x1f,0xf7,0x7c,0xb7,0x54,
+0x7, 0xa, 0x3b,0x2e,0x34,0x0, 0x4e,0x12,0x57,0xbb,0x5c,0xba,0x22,0x7e,0xf0,0x2,
+0xac,0xf9,0x7f,0x67,0x22,0x7e,0x13,0x24,0x3a,0xac,0x1b,0x3e,0x4, 0x7e,0x30,0x2,
+0xac,0x37,0x2d,0x10,0x7e,0x1f,0x1b,0xd6,0x2d,0x31,0x22,0xa2,0xa, 0xe4,0x33,0x7a,
+0xb3,0x3f,0x4f,0x7e,0x73,0x3f,0x53,0xbe,0x73,0x24,0xed,0x68,0x7, 0xe5,0xc, 0x70,
+0x3, 0x12,0x58,0x15,0x22,0x7e,0x73,0x24,0xed,0x7a,0x73,0x3f,0x53,0x7e,0x73,0x24,
+0xfd,0x7a,0x73,0x3f,0x43,0x7e,0x73,0x24,0xfe,0x7a,0x73,0x3f,0x42,0x7e,0x73,0x24,
+0xf2,0x7a,0x73,0x3f,0x44,0x7e,0x73,0x25,0x48,0x7a,0x73,0x3f,0x54,0x22,0xca,0xd8,
+0xca,0x79,0x7c,0xdb,0x90,0x61,0xdb,0xe4,0x93,0x7c,0xab,0xbe,0xd0,0x80,0x78,0x18,
+0x7e,0xe0,0xff,0x6c,0xff,0x80,0xb, 0x12,0x58,0xaa,0x38,0x4, 0x7c,0xeb,0x7c,0xdf,
+0xb, 0xf0,0xbc,0xaf,0x38,0xf1,0x80,0x1a,0xbe,0xd0,0x81,0x78,0x15,0x6c,0xee,0x6c,
+0xff,0x80,0xb, 0x12,0x58,0xaa,0x40,0x4, 0x7c,0xeb,0x7c,0xdf,0xb, 0xf0,0xbc,0xaf,
+0x38,0xf1,0xbc,0xad,0x38,0x2, 0x6c,0xdd,0x7c,0xbd,0x12,0x43,0x9b,0x12,0x58,0xb6,
+0x12,0x59,0x6e,0x12,0x59,0x77,0x7e,0x73,0x24,0xed,0x7a,0x73,0x3f,0x53,0x12,0x58,
+0x35,0x7a,0xd3,0x3f,0x2b,0xda,0x79,0xda,0xd8,0x22,0x7e,0x90,0x5, 0xac,0x9f,0x9,
+0xb4,0x1f,0xa4,0xbc,0xbe,0x22,0x7e,0x73,0x24,0xf2,0x7a,0x73,0x3f,0x44,0x22,0x74,
+0x40,0x7a,0xb3,0x24,0xfe,0x74,0x1, 0x12,0x58,0xe3,0x7e,0x43,0x3f,0x40,0x7e,0x50,
+0x64,0xac,0x45,0x12,0x87,0xfa,0x7a,0xb3,0x24,0xfd,0x12,0x59,0x77,0x12,0x59,0x6e,
+0x2, 0x58,0xb6,0xca,0x3b,0x7c,0xdb,0xe4,0x7a,0xb3,0x24,0xf2,0x12,0x5a,0x30,0x7e,
+0xc0,0xa, 0x12,0x5b,0x1, 0x12,0x0, 0x1e,0x30,0xb, 0xfd,0x74,0x1, 0x12,0x0, 0xe,
+0x7e,0x1f,0x3f,0xdf,0x12,0x59,0xd5,0x7d,0x73,0xbe,0x74,0xff,0xff,0x78,0xb, 0x12,
+0x59,0x60,0x6c,0x44,0x2e,0x24,0x0, 0x3, 0x80,0x1a,0xbe,0x74,0x80,0x0, 0x28,0x9,
+0x12,0x59,0x60,0x6c,0x44,0xb, 0x25,0x80,0xb, 0xbe,0x74,0x40,0x0, 0x28,0x12,0x12,
+0x59,0x60,0xb, 0x24,0x6c,0x44,0x6c,0x77,0x4d,0x32,0x1b,0xa, 0x30,0x1b,0xc0,0x78,
+0xb1,0xbe,0xd0,0x1, 0x78,0x9, 0x7e,0x1f,0x3f,0xdf,0x12,0x59,0x80,0x7d,0x73,0x7e,
+0x1f,0x3f,0xc6,0x69,0x31,0x0, 0x1a,0x7a,0x73,0x24,0xf2,0x7d,0x37,0xda,0x3b,0x22,
+0x7e,0xf, 0x3f,0xc6,0x2e,0x14,0x0, 0x1a,0xb, 0xa, 0x30,0x7d,0x23,0x22,0x7e,0x73,
+0x24,0xfd,0x7a,0x73,0x3f,0x43,0x22,0x7e,0x73,0x24,0xfe,0x7a,0x73,0x3f,0x42,0x22,
+0xca,0xf8,0x7e,0xf3,0x24,0x3c,0x7a,0x37,0x31,0xc1,0x7e,0x34,0x1e,0x6a,0x7a,0x37,
+0x31,0xc3,0xe4,0x7a,0xb3,0x31,0xbb,0x7a,0xb3,0x31,0xbc,0x7e,0x73,0x24,0x3b,0x7a,
+0x73,0x31,0xbd,0x7a,0xf3,0x31,0xbe,0x7a,0xb3,0x31,0xbf,0x7a,0xb3,0x31,0xc0,0x7e,
+0x8, 0x31,0xbb,0x12,0x6f,0xee,0x6d,0x22,0x7d,0x3, 0x6d,0x11,0x7e,0x37,0x1e,0x6c,
+0x2f,0x10,0x7e,0x33,0x31,0xbd,0x6d,0x0, 0x12,0x27,0x15,0xa, 0x1f,0x6d,0x0, 0x12,
+0x27,0x15,0xda,0xf8,0x22,0x7a,0x37,0x31,0xbf,0x7e,0x34,0x1e,0x74,0x7a,0x37,0x31,
+0xc3,0x7e,0x34,0x1e,0x6a,0x7a,0x37,0x31,0xc1,0x7e,0x73,0x24,0x3b,0x7a,0x73,0x31,
+0xbc,0x7e,0x73,0x24,0x3c,0x7a,0x73,0x31,0xbb,0x7e,0x37,0x24,0x28,0x7a,0x37,0x31,
+0xc5,0x7e,0x37,0x24,0x2a,0x7a,0x37,0x31,0xc7,0x7e,0x37,0x24,0x2c,0x7a,0x37,0x31,
+0xc9,0x74,0x1, 0x12,0xa5,0xa3,0x7e,0x8, 0x31,0xbb,0x7e,0x18,0x31,0xcd,0x12,0x12,
+0x18,0x7e,0x37,0x31,0xd7,0x7e,0x27,0x31,0xd3,0xbd,0x23,0x28,0x2, 0x7d,0x32,0x22,
+0x7e,0x8, 0x24,0x39,0x2, 0x16,0x52,0x74,0x1, 0x12,0x1d,0x89,0xe4,0x12,0x5f,0xe7,
+0x12,0x5a,0x30,0x2, 0x5a,0x46,0x7e,0x63,0x24,0xed,0x7e,0x73,0x3f,0x52,0x7e,0x14,
+0x60,0xde,0x12,0x6f,0xe6,0xac,0x67,0x2d,0x32,0x7e,0x24,0x1, 0xf4,0x8d,0x32,0xbe,
+0x70,0x7, 0x28,0x3, 0x7e,0x70,0x7, 0x12,0x3e,0x6e,0x2d,0x32,0x79,0x30,0x0, 0xa0,
+0x22,0x7e,0xf, 0x1b,0xd6,0x7e,0x18,0xa, 0x62,0xca,0x3b,0x7a,0x1d,0x29,0x7f,0x30,
+0x12,0x5c,0x50,0x7a,0x55,0x31,0x7e,0xb3,0x24,0xfb,0xf5,0x2e,0xe4,0x7a,0xb3,0x24,
+0xfb,0x7f,0x3, 0x7e,0x1d,0x29,0x12,0x78,0xa4,0x74,0x1, 0x12,0x1d,0x89,0xe4,0x12,
+0x0, 0x6, 0x12,0x5a,0x30,0x75,0x2d,0x0, 0x12,0x5b,0x1, 0x12,0x5a,0x46,0x12,0x0,
+0x1e,0x30,0xb, 0xfd,0x74,0x1, 0x12,0xd1,0x4f,0x7e,0x14,0x80,0x0, 0x7d,0x21,0x7d,
+0x7, 0x12,0x5b,0xd6,0x12,0xac,0x83,0x6d,0x33,0x80,0x19,0x7e,0x35,0x2f,0x3e,0x34,
+0x7f,0x3, 0x2d,0x13,0xb, 0xa, 0x20,0x7e,0xd, 0x29,0x2d,0x13,0x12,0x5e,0xf7,0x7e,
+0x35,0x2f,0xb, 0x34,0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe,0x35,0x2f,0x38,0xdc,0x5,
+0x2d,0xe5,0x2d,0xbe,0xb0,0x1, 0x40,0xb0,0xe5,0x2e,0x7a,0xb3,0x24,0xfb,0xda,0x3b,
+0x22,0xe4,0x12,0x0, 0xe, 0x74,0x1, 0x7e,0x70,0x99,0x2, 0x1c,0xd1,0xca,0x3b,0x7f,
+0x30,0x7c,0xab,0x7e,0xb3,0x24,0xfb,0xf5,0x2e,0x7e,0xb3,0x24,0xed,0xf5,0x2f,0x7e,
+0xb3,0x24,0xf2,0xf5,0x30,0x7e,0xb3,0x24,0xfd,0xf5,0x31,0x7e,0xb3,0x24,0xfe,0xf5,
+0x32,0x74,0x1, 0x7a,0xb3,0x24,0xfb,0x7e,0x70,0x5, 0xac,0x7a,0x9, 0xb3,0x1f,0xa5,
+0x7a,0xb3,0x24,0xf2,0x7e,0x70,0x5, 0xac,0x7a,0x9, 0xb3,0x1f,0xa6,0x7a,0xb3,0x24,
+0xfd,0x7e,0x70,0x5, 0xac,0x7a,0x9, 0xb3,0x1f,0xa7,0x7a,0xb3,0x24,0xfe,0x7e,0x90,
+0x5, 0xac,0x9a,0x9, 0xb4,0x1f,0xa8,0xbe,0xb3,0x25,0x48,0x68,0x6, 0x7a,0xb3,0x25,
+0x48,0xd2,0xc, 0xc2,0x3, 0x74,0x5, 0xa4,0x9, 0xb5,0x1f,0xa4,0x12,0x43,0x81,0x12,
+0x5a,0x30,0x12,0x5b,0x1, 0x12,0x0, 0x1e,0x30,0xb, 0xfd,0x74,0x1, 0x12,0x0, 0xe,
+0x7e,0x14,0x80,0x0, 0x7d,0x31,0x7e,0x2f,0x1b,0xd2,0x7d,0x25,0x7e,0x4, 0x13,0x1a,
+0x12,0x5b,0xd6,0x12,0x5c,0x50,0x7a,0x55,0x33,0x7f,0x3, 0x7e,0x18,0x13,0x1a,0x12,
+0xa4,0xf, 0x12,0xa4,0x94,0xe5,0x2e,0x7a,0xb3,0x24,0xfb,0xe5,0x2f,0x7a,0xb3,0x24,
+0xed,0xe5,0x30,0x7a,0xb3,0x24,0xf2,0xe5,0x31,0x7a,0xb3,0x24,0xfd,0xe5,0x32,0x7a,
+0xb3,0x24,0xfe,0xda,0x3b,0x22,0x7e,0xb3,0x24,0x39,0xca,0xf8,0x7c,0xfb,0x7d,0xc0,
+0x7d,0xd1,0x7d,0xf2,0x7d,0xe3,0x7a,0xf3,0x31,0xbb,0x7e,0x73,0x24,0x3c,0x7a,0x73,
+0x31,0xbc,0xe4,0x7a,0xb3,0x31,0xbe,0x74,0x6, 0x7a,0xb3,0x31,0xbd,0x7a,0xd7,0x31,
+0xbf,0x7a,0xd7,0x31,0xc3,0x7e,0x8, 0x31,0xbb,0x7e,0x73,0x24,0xfd,0xa, 0x37,0x12,
+0x18,0xcb,0x7a,0xc7,0x31,0xc3,0xe4,0x7a,0xb3,0x31,0xbd,0x12,0xa7,0x59,0x7a,0xf3,
+0x31,0xbb,0x7e,0xb3,0x24,0xfb,0x70,0xf, 0xe4,0x7a,0xb3,0x31,0xbe,0x7a,0xd7,0x31,
+0xbf,0x7e,0x34,0x0, 0x20,0x80,0x10,0x74,0x1, 0x7a,0xb3,0x31,0xbe,0x7a,0xe7,0x31,
+0xbf,0x7a,0xf7,0x31,0xc1,0x6d,0x33,0x12,0xa7,0x36,0x12,0x18,0x0, 0xda,0xf8,0x22,
+0x7e,0xa3,0x24,0x3a,0x7e,0xb3,0x24,0x39,0xa4,0x22,0xb4,0x3, 0x5, 0x12,0x5a,0x37,
+0x80,0x2, 0xe4,0x22,0x12,0x5b,0x5, 0x12,0x0, 0x1e,0x74,0x1, 0x22,0x12,0x5f,0xd3,
+0x38,0x2, 0xe4,0x22,0x12,0x5f,0xcb,0x49,0x55,0x3f,0xe6,0xbe,0xb0,0x2, 0x38,0x3,
+0x2, 0x5c,0x86,0x2, 0x5c,0x5a,0xca,0xf8,0x7c,0xfb,0x7e,0x6f,0x24,0xe9,0xbe,0xf0,
+0x1, 0x28,0x3, 0xe4,0x80,0x29,0x7c,0xbf,0x12,0x5d,0xe5,0x4c,0xff,0x78,0x3, 0x12,
+0xd0,0xb5,0x12,0x5c,0xc2,0x7a,0x6f,0x24,0xe9,0x7e,0x73,0x24,0xd6,0xa, 0x37,0x3e,
+0x34,0x3e,0x34,0xe4,0x7e,0x50,0x1, 0x12,0x1c,0xa6,0x12,0x5d,0xde,0x74,0x1, 0xda,
+0xf8,0x22,0x7e,0x8, 0x24,0x39,0x2, 0xd, 0x0, 0xca,0x3b,0x7e,0xe3,0x24,0x40,0x7e,
+0xf3,0x24,0xd6,0x74,0x1, 0x7a,0xb3,0x24,0xd6,0x12,0x5c,0xc2,0x12,0xd1,0x24,0x7e,
+0x8, 0x31,0xbb,0x7e,0x34,0x0, 0x86,0x12,0x29,0x72,0x7e,0xd0,0x8, 0x12,0x48,0x8b,
+0x6c,0xcc,0x80,0x1c,0x7e,0x14,0x0, 0x1, 0x7c,0xbd,0x60,0x5, 0x3e,0x14,0x14,0x78,
+0xfb,0x7e,0x50,0x2, 0xac,0x5c,0x12,0x5d,0xae,0x4d,0x31,0x1b,0x28,0x30,0xb, 0xc0,
+0x12,0x5d,0xcb,0x48,0xdf,0x7e,0x34,0x0, 0x86,0xca,0x39,0x12,0x5d,0xc0,0x12,0x29,
+0x4d,0x1b,0xfd,0x12,0x5d,0xb6,0x12,0x37,0x3e,0x74,0x2, 0x12,0x0, 0x6, 0xe4,0x12,
+0x5f,0x0, 0x12,0x5d,0xf2,0x12,0x5d,0xde,0x30,0x19,0xfd,0x74,0x1, 0x12,0x0, 0xe,
+0x7e,0x8, 0x7, 0x2c,0x7e,0xb3,0x24,0x3f,0x7c,0x7e,0x12,0xe, 0x24,0x6c,0xcc,0x80,
+0x2c,0x7e,0x50,0x2, 0xac,0x5c,0x49,0x32,0x7, 0x2c,0xbe,0x34,0x15,0x40,0x50,0x1b,
+0x7e,0x34,0x0, 0x1, 0x7c,0xbd,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7d,0x13,0x6e,
+0x14,0xff,0xff,0x12,0x5d,0xae,0x5d,0x31,0x1b,0x28,0x30,0xb, 0xc0,0x12,0x5d,0xcb,
+0x48,0xcf,0x1b,0xd0,0xbe,0xd0,0x0, 0x48,0x2, 0x81,0xed,0x7e,0x34,0x0, 0x86,0xca,
+0x39,0x12,0x5d,0xc0,0x12,0x29,0x4d,0x1b,0xfd,0x12,0x5d,0xb6,0x12,0x37,0x3e,0x74,
+0x2, 0x12,0x0, 0x6, 0x7a,0xf3,0x24,0xd6,0x12,0x5c,0xc2,0xda,0x3b,0x22,0x2e,0x24,
+0x31,0xbb,0xb, 0x28,0x30,0x22,0x74,0x2, 0x12,0x0, 0x6, 0x7e,0xb3,0x24,0xd8,0x22,
+0x7e,0x17,0x24,0xda,0x6d,0x0, 0x7e,0x18,0x31,0xbb,0x22,0x7e,0x73,0x24,0x40,0xa,
+0x37,0x7e,0x53,0x24,0x3f,0xa, 0x25,0x2d,0x23,0xa, 0x3c,0xbd,0x32,0x22,0x7e,0xb3,
+0x24,0xd8,0x2, 0x0, 0x76,0x7c,0xab,0x12,0x36,0xbe,0x7c,0xba,0x12,0x5f,0xf5,0x2,
+0x5d,0xf2,0x7e,0x33,0x24,0xd4,0x7e,0x23,0x24,0xd5,0xa, 0x32,0x6d,0x22,0xa, 0x13,
+0x6d,0x0, 0x2f,0x1, 0x74,0x4, 0x2f,0x0, 0x14,0x78,0xfb,0x2e,0x8, 0x0, 0x2a,0x12,
+0x47,0xfc,0x7e,0x24,0x1, 0xf4,0x8d,0x32,0xbe,0x70,0x7, 0x28,0x3, 0x7e,0x70,0x7,
+0x12,0x3e,0x6e,0x2d,0x32,0x79,0x30,0x0, 0xa0,0x22,0x7c,0xa7,0x12,0x34,0x7d,0x7c,
+0xba,0x12,0x1d,0x1e,0x74,0xa, 0x12,0x3e,0xa1,0x2, 0x5c,0xc9,0x7e,0xb3,0x24,0xde,
+0x70,0x3c,0x12,0x4b,0x71,0x50,0xfb,0xe4,0x6c,0x77,0x12,0x5e,0x2a,0x7e,0x8, 0x7,
+0x2c,0x7e,0x1f,0x7, 0x24,0x7e,0xb3,0x25,0x6e,0x12,0x5e,0x7f,0x74,0x1, 0x7e,0x70,
+0x1, 0x12,0x5e,0x2a,0x7e,0x8, 0x8, 0xbe,0x7e,0x1f,0x7, 0x24,0x7e,0xb3,0x1f,0x61,
+0x12,0x5e,0x7f,0x74,0x2, 0x7a,0xb3,0x24,0xde,0xe4,0x7a,0xb3,0x1f,0x5c,0x22,0xca,
+0x3b,0xf5,0x2d,0x7f,0x31,0x7a,0xd, 0x29,0x7f,0x13,0x12,0x78,0xc7,0x12,0x5f,0xee,
+0x75,0x2e,0x0, 0xe4,0x12,0x5f,0x0, 0x12,0x5d,0xde,0x30,0x19,0xfd,0x74,0x1, 0x12,
+0x0, 0xe, 0x7e,0xd, 0x29,0x12,0x5f,0xdc,0x75,0x2f,0x0, 0x80,0x1d,0x7e,0xa1,0x2f,
+0x74,0x2, 0xa4,0x7e,0x1d,0x29,0x2d,0x35,0xb, 0x1a,0x20,0x7e,0xa1,0x2f,0x74,0x2,
+0xa4,0x7f,0x3, 0x2d,0x15,0x12,0x5e,0xf7,0x5, 0x2f,0x7e,0x73,0x24,0x40,0xa, 0x7,
+0x7e,0x63,0x24,0x3f,0xa, 0x16,0x2d,0x10,0xe5,0x2f,0xa, 0x2b,0xbd,0x21,0x48,0xcd,
+0x5, 0x2e,0xe5,0x2e,0xbe,0xb0,0x1, 0x40,0xaa,0x7f,0x3, 0xe5,0x2d,0x2e,0x73,0x24,
+0x3f,0x12,0x5f,0x36,0xda,0x3b,0x22,0xb, 0xa, 0x30,0x2d,0x32,0x1b,0xa, 0x30,0x22,
+0x12,0x0, 0xe, 0x74,0x6, 0x7e,0x70,0x9b,0x12,0x1c,0xd1,0x6c,0xaa,0x80,0x1e,0xa,
+0x3a,0x9, 0x73,0x24,0xb0,0x12,0x57,0xb7,0x7c,0x7b,0xa, 0x47,0x7e,0x50,0x2, 0xac,
+0x5a,0x7e,0xf, 0x3f,0xbe,0x2d,0x12,0x79,0x40,0x0, 0x52,0xb, 0xa0,0x7e,0x63,0x24,
+0x40,0xbc,0x6a,0x38,0xda,0x22,0xca,0xf8,0x7c,0xf7,0x7f,0x70,0x12,0xc5,0xc9,0x7c,
+0x7b,0xa, 0x17,0x6d,0x0, 0x7e,0x18,0x80,0x0, 0x12,0x27,0x15,0x74,0x1, 0x7a,0xb3,
+0x31,0xbb,0x7a,0xf3,0x31,0xbc,0x7a,0xb3,0x31,0xbe,0x74,0xb, 0x7a,0xb3,0x31,0xbd,
+0x7d,0x1f,0x7a,0x17,0x31,0xbf,0x7a,0x17,0x31,0xc3,0x7e,0x8, 0x31,0xbb,0x12,0x18,
+0xcb,0xda,0xf8,0x22,0x30,0x19,0x5, 0x74,0x6, 0x12,0x5b,0x7, 0x7e,0xb3,0x3f,0xe5,
+0xb4,0x1, 0x47,0x12,0x5f,0xcb,0x49,0x35,0x3f,0xe6,0x49,0x15,0x3f,0xe8,0x6d,0x0,
+0xbe,0x8, 0x0, 0x0, 0x68,0x12,0xbe,0x70,0x0, 0x40,0xd, 0xbe,0x70,0x2, 0x38,0x8,
+0x74,0x1, 0x12,0x0, 0xe, 0x12,0x5f,0xdc,0x7e,0xb3,0x3f,0xe4,0x4, 0x7a,0xb3,0x3f,
+0xe4,0x12,0x5f,0xd3,0x28,0xe, 0x12,0x5c,0x6d,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x6,
+0x74,0x3, 0x80,0x2, 0x74,0x2, 0x7a,0xb3,0x3f,0xe5,0x22,0x7e,0xa3,0x3f,0xe4,0x74,
+0x4, 0xa4,0x22,0x7e,0x73,0x3f,0xe3,0xbe,0x73,0x3f,0xe4,0x22,0x7e,0xb3,0x24,0x3f,
+0x7e,0x73,0x24,0x40,0x2, 0xe, 0x24,0x12,0x0, 0x6, 0xe4,0x2, 0x0, 0xe, 0x7e,0x8,
+0x24,0x39,0x2, 0x0, 0x2e,0x12,0x1d,0x1e,0xe4,0x2, 0x0, 0xe, 0x2, 0x6e,0xd7,0xff,
+0x70,0x8f,0x0, 0xff,0x60,0x9f,0x8d,0x72,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x59,0x46,0x30,0x31,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x9, 0xf6,0x30,0x32,0x31,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x10,0x20,0xf, 0x1, 0x0, 0x3, 0x5, 0x4, 0x7, 0x6, 0xa, 0x9, 0xd, 0xc, 0x8, 0xb,
+0x11,0x10,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x0, 0x3, 0x5, 0x2, 0xe, 0xa, 0xb, 0x6, 0xf,
+0xd, 0x8, 0x7, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x1a,0x19,0x1b,0x1c,0x1e,
+0x1d,0x1f,0x22,0x23,0x21,0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x4, 0xff,0x1f,0x24,0x4,
+0x5c,0xa, 0x1e,0xa, 0x64,0x2d,0x10,0x0, 0x4, 0x0, 0x64,0xd, 0xac,0x0, 0xc8,0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x19,0x28,0x1, 0xf4,
+0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x0, 0x5, 0x58,0x20,0x1, 0x20,0x1, 0x0, 0x0,
+0x0, 0x0, 0x1, 0xf4,0x40,0x40,0x10,0x20,0x30,0x15,0x13,0x3, 0x80,0x15,0x13,0x3,
+0xa0,0x8, 0x10,0x4, 0x20,0x1, 0x0, 0x4, 0x38,0x31,0x40,0x1, 0x88,0x1, 0x88,0x1,
+0x18,0x1, 0x9, 0x8, 0x70,0x31,0x31,0x1, 0xb0,0x1, 0xb0,0x1, 0x12,0x1, 0x12,0x1,
+0x4a,0x1, 0x2c,0x1, 0x2c,0x1, 0x18,0x0, 0x8c,0x1, 0x18,0x1, 0x18,0xa, 0x0, 0x1,
+0x9a,0xf, 0x10,0x42,0x3e,0x1, 0x5, 0xc, 0x1e,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52,0xb,
+0x0, 0x1, 0x54,0x1, 0x0, 0x9, 0x1, 0x60,0x1, 0x1, 0x0, 0x8d,0x1, 0x1, 0x1, 0x0,
+0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55,0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64,
+0x1, 0x2c,0x0, 0x50,0x0, 0x40,0x0, 0x2, 0x0, 0x2, 0x1, 0x4, 0x1, 0x90,0x0, 0xc8,
+0x0, 0x50,0x0, 0xc8,0x0, 0x96,0x1, 0x2c,0x1, 0x2c,0x4, 0x28,0x1, 0x58,0x40,0x20,
+0x15,0x2, 0x36,0x40,0x30,0x20,0x2, 0x38,0x40,0x30,0x49,0x1, 0x44,0x40,0x30,0x28,
+0x1, 0x58,0x40,0x20,0x28,0x1, 0x58,0x40,0x20,0x28,0x1, 0x58,0x40,0x20,0x28,0x1,
+0x58,0x40,0x20,0x4, 0x5, 0x13,0x14,0x15,0x16,0x17,0x4, 0x0, 0xd2,0x2, 0x30,0x64,
+0x0, 0xc8,0x1, 0x5e,0x0, 0x64,0x0, 0x64,0x0, 0x96,0x0, 0x64,0xb, 0xb8,0x8, 0x5,
+0x6, 0x80,0x1, 0x90,0x1, 0x2c,0x1, 0xc2,0x3, 0x20,0xf, 0xa0,0x1, 0x3, 0x20,0x4,
+0xb0,0x3, 0x20,0x1, 0x2, 0x2, 0x4, 0x4, 0x6, 0x40,0x1, 0x5e,0x1, 0x2c,0x1, 0x90,
+0x1, 0x90,0x1, 0x90,0x0, 0xfa,0x0, 0xc8,0x1, 0x2c,0x0, 0xfa,0x0, 0xfa,0x0, 0x50,
+0x0, 0x32,0x0, 0x64,0x0, 0x64,0x0, 0x64,0x1, 0x18,0x1, 0x18,0xa, 0x5, 0x0, 0x50,
+0x3, 0xe8,0x0, 0x50,0x8, 0x20,0x0, 0x32,0x1, 0xf4,0x1, 0xf4,0x3, 0x20,0x0, 0xc8,
+0x0, 0x43,0x0, 0x1e,0x0, 0x80,0x1, 0xe, 0x1, 0xe, 0x0, 0x3c,0x3, 0xe8,0x2, 0x1c,
+0x0, 0x87,0x0, 0x3c,0x3, 0xe8,0x0, 0x0, 0x4, 0x38,0x0, 0x0, 0x8, 0x70,0x2, 0x1c,
+0x2, 0xd0,0x0, 0x64,0x0, 0xa0,0x0, 0xa0,0x13,0x88,0x1, 0x2c,0x0, 0xa0,0x0, 0xa0,
+0x10,0x0, 0xc, 0x0, 0xe, 0xe, 0x5, 0x7, 0xa, 0xa, 0x6, 0x6, 0xc, 0x64,0xc8,0x7e,
+0x8, 0x3, 0xfd,0x12,0x62,0xd3,0x12,0x62,0xe8,0x2, 0x62,0xcc,0x7e,0x8, 0x40,0x21,
+0x2, 0x62,0xd3,0xb, 0xa, 0x30,0xe5,0x64,0xa, 0x2b,0xbd,0x32,0x28,0x4, 0x9d,0x32,
+0x80,0x2, 0x6d,0x33,0x1b,0xa, 0x30,0x22,0x7e,0x8, 0x37,0x5b,0x2, 0x62,0xd3,0x7e,
+0x73,0x22,0x4, 0x7a,0x73,0x22,0x5, 0x7e,0x73,0x23,0x87,0x7a,0x73,0x23,0x88,0xe4,
+0x7a,0xb3,0x23,0x8b,0x22,0xc2,0x3, 0x7e,0xb3,0x1f,0x5d,0x60,0x6, 0x7e,0xb3,0x1f,
+0x5c,0x70,0x7, 0x12,0x63,0x1d,0x28,0x2, 0xd2,0x3, 0xa2,0x3, 0x22,0x7e,0x73,0x21,
+0xf5,0xbe,0x70,0x1, 0x22,0xca,0x79,0xc2,0x3, 0x7e,0xf0,0x3, 0x7e,0xe3,0x23,0x88,
+0x7e,0x34,0x31,0xbb,0x7a,0x37,0x2, 0xab,0x6c,0x11,0x80,0x52,0x6c,0x0, 0x80,0x1d,
+0x74,0x2, 0xac,0xb0,0x9, 0x75,0x20,0x6b,0xa, 0x37,0xa, 0x21,0x9, 0x52,0x1f,0xcc,
+0x9d,0x32,0x12,0x29,0xb4,0xbe,0x34,0x0, 0x4, 0x48,0x7, 0xb, 0x0, 0x12,0x64,0xc1,
+0x38,0xde,0x12,0x64,0xc1,0x78,0x25,0xa, 0x11,0x9, 0x71,0x1f,0xcc,0xa, 0x37,0x7e,
+0x53,0x24,0x3a,0xa, 0x15,0x2d,0x13,0x3e,0x14,0x49,0x11,0x5, 0xc, 0xbe,0x17,0xa,
+0x58,0x68,0x9, 0x7c,0xb1,0x6c,0x77,0x6c,0x66,0x12,0x64,0xf4,0xb, 0x10,0x7e,0x73,
+0x1f,0xf5,0xbc,0x71,0x38,0xa6,0x6c,0x11,0x80,0x4a,0x6c,0x0, 0x80,0x1d,0x74,0x2,
+0xac,0xb0,0x9, 0x75,0x20,0x6c,0xa, 0x37,0xa, 0x21,0x9, 0x52,0x1f,0xe0,0x9d,0x32,
+0x12,0x29,0xb4,0xbe,0x34,0x0, 0x3, 0x48,0x7, 0xb, 0x0, 0x12,0x64,0xc1,0x38,0xde,
+0x12,0x64,0xc1,0x78,0x1d,0xa, 0x11,0x9, 0xa1,0x1f,0xe0,0x74,0x2, 0xa4,0x49,0x15,
+0x5, 0xc, 0xbe,0x17,0xa, 0x5a,0x68,0xa, 0x7c,0xb1,0x6c,0x77,0x7e,0x60,0x1, 0x12,
+0x64,0xf4,0xb, 0x10,0x7e,0x73,0x1f,0xf6,0xbc,0x71,0x38,0xae,0x12,0x65,0x3f,0x12,
+0x63,0x1d,0x38,0x2, 0x81,0xb8,0x12,0x66,0x29,0x92,0x9, 0x12,0x64,0xc8,0x7c,0xbf,
+0x12,0xaf,0xfd,0x4c,0xee,0x68,0xe, 0x7e,0xa3,0x2, 0x87,0x4c,0xaa,0x78,0xa, 0x7e,
+0xb3,0x2, 0x88,0x70,0x4, 0xd2,0x3, 0x80,0x25,0xbe,0xe0,0x1, 0x28,0xb, 0xe5,0x1f,
+0xbe,0xb0,0x8, 0x28,0x4, 0xd2,0x3, 0x80,0x15,0xd2,0x3, 0x7e,0xb3,0x21,0xf5,0xbc,
+0xbe,0x78,0xb, 0x4c,0xaa,0x78,0x7, 0x20,0x9, 0x4, 0x6c,0xff,0xc2,0x3, 0x20,0x3,
+0x5, 0x7c,0xbf,0x12,0xaf,0xfd,0x7e,0x8, 0x2, 0x8d,0x12,0xb8,0x41,0x7a,0xb3,0x2,
+0x8b,0xbe,0xb3,0x21,0xf5,0x50,0x40,0x7e,0x33,0x2, 0x8b,0x80,0x2c,0x7e,0x70,0x2,
+0xac,0x73,0x9, 0x23,0x2, 0xad,0x9, 0x13,0x2, 0xae,0x2e,0x37,0x2, 0xab,0xb, 0x38,
+0x50,0x7e,0x93,0x24,0x3a,0xac,0x92,0xa, 0x31,0x2d,0x43,0x3e,0x44,0x7e,0x1f,0x1b,
+0xd6,0x2d,0x34,0x1b,0x1a,0x50,0x12,0x65,0xdb,0x7c,0x3, 0x1b,0x30,0xa5,0xb8,0x0,
+0xcc,0x74,0x1, 0x7a,0xb3,0x2, 0x89,0x7e,0xa3,0x2, 0x8b,0x7a,0xa3,0x21,0xf5,0x74,
+0x2, 0xa4,0xca,0x59,0x7e,0x18,0x2, 0xad,0x7e,0x8, 0x20,0x6b,0x12,0x29,0x4d,0x1b,
+0xfd,0x12,0x7d,0xde,0xf5,0x1f,0x80,0x6, 0x75,0x1f,0x64,0x12,0xbf,0x79,0xda,0x79,
+0x22,0x7e,0x73,0x21,0xf5,0xbc,0x70,0x22,0x6c,0xaa,0x12,0xd0,0xd0,0x12,0x64,0xea,
+0x54,0xfe,0x12,0x64,0xe7,0x54,0x7, 0x12,0x64,0xe7,0x54,0xfb,0x7a,0xb, 0xb0,0xb,
+0xa0,0xbe,0xa0,0x1e,0x40,0xe4,0x22,0x7a,0xb, 0xb0,0x7f,0x1, 0x2e,0x14,0x0, 0x5,
+0x7e,0xb, 0xb0,0x22,0x7c,0x56,0x12,0x66,0x1a,0xa, 0x1b,0x2e,0x14,0x0, 0x4e,0x12,
+0xd1,0x9, 0x7c,0x7b,0xa5,0xbd,0x0, 0x18,0x4c,0x66,0x68,0x8, 0xa, 0x2a,0x2e,0x24,
+0x1f,0xf7,0x80,0x1a,0x7c,0xb7,0x64,0xff,0xa, 0x2a,0x2e,0x24,0x1f,0xf7,0x80,0x1b,
+0xa5,0xbd,0x1, 0x1a,0x4c,0x66,0x68,0x9, 0xa, 0x2a,0x2e,0x24,0x1f,0xfa,0x2, 0x66,
+0x11,0x7c,0xb7,0x64,0xff,0xa, 0x2a,0x2e,0x24,0x1f,0xfa,0x12,0x66,0x8, 0x22,0xca,
+0xd8,0xca,0x79,0x6c,0xdd,0x6c,0xff,0x6c,0xee,0x80,0x30,0x7c,0xbe,0x12,0x57,0xc4,
+0x60,0x27,0x7e,0x34,0x0, 0x1, 0xca,0x39,0xa, 0x3e,0x2e,0x34,0x1f,0xcc,0x6d,0x22,
+0xa, 0x1d,0x2e,0x14,0x1f,0xcc,0x6d,0x0, 0x12,0x29,0x4d,0x1b,0xfd,0x7c,0xbd,0x7e,
+0x70,0x1, 0x6c,0x66,0x12,0x64,0xf4,0xb, 0xd0,0xb, 0xe0,0x7e,0x73,0x1f,0xf5,0xbc,
+0x7e,0x38,0xc8,0x7a,0xd3,0x1f,0xf5,0x6c,0xee,0x80,0x31,0x7c,0xbe,0x12,0x57,0x94,
+0x60,0x28,0x7e,0x34,0x0, 0x1, 0xca,0x39,0xa, 0x3e,0x2e,0x34,0x1f,0xe0,0x6d,0x22,
+0xa, 0x1f,0x2e,0x14,0x1f,0xe0,0x6d,0x0, 0x12,0x29,0x4d,0x1b,0xfd,0x7c,0xbf,0x7e,
+0x70,0x1, 0x7e,0x60,0x1, 0x12,0x64,0xf4,0xb, 0xf0,0xb, 0xe0,0x7e,0x73,0x1f,0xf6,
+0xbc,0x7e,0x38,0xc7,0x7a,0xf3,0x1f,0xf6,0x7e,0x63,0x1f,0xf6,0x7e,0x73,0x1f,0xf5,
+0xac,0x76,0x7a,0x73,0x1f,0xf4,0xda,0x79,0xda,0xd8,0x22,0x7c,0xb3,0x7e,0x70,0x1,
+0x12,0x66,0x1a,0xa, 0x2b,0x2e,0x24,0x0, 0x4e,0x12,0x7a,0xb8,0x7c,0x7b,0x4c,0x66,
+0x68,0x9, 0xa, 0x2a,0x2e,0x24,0x20,0xe3,0x2, 0x66,0x11,0x7c,0xb7,0x64,0xff,0xa,
+0x2a,0x2e,0x24,0x20,0xe3,0x2, 0x66,0x8, 0x7e,0x29,0x70,0x5c,0x7b,0x7a,0x29,0x70,
+0x22,0x7e,0x29,0xb0,0x4c,0xb7,0x7a,0x29,0xb0,0x22,0x7c,0x67,0x7c,0x7b,0xc4,0x23,
+0x54,0x1f,0x7c,0xab,0x7c,0xb7,0x54,0x7, 0x22,0xca,0x3b,0x7e,0xe3,0x21,0xf5,0x6c,
+0xdd,0x6c,0xff,0x74,0x6, 0xac,0xbd,0x12,0x67,0xf, 0x30,0xe0,0x3d,0x6c,0xcc,0x80,
+0x2d,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x20,0x6b,0x7a,0xb3,0x31,0xf7,0x9, 0xa3,
+0x20,0x6c,0x7a,0xa3,0x31,0xf8,0x7f,0x7, 0x12,0x66,0x85,0x50,0xf, 0x7f,0x7, 0x7e,
+0xb3,0x31,0xf8,0x6c,0x77,0x12,0x66,0x88,0x50,0x2, 0xb, 0xf0,0xb, 0xc0,0xbc,0xec,
+0x38,0xcf,0xbe,0xf0,0x2, 0x40,0x3, 0xd3,0x80,0x8, 0xb, 0xd0,0xbe,0xd0,0x1e,0x40,
+0xb0,0xc3,0xda,0x3b,0x22,0x7e,0x70,0x1, 0x7c,0x87,0x7c,0x9b,0x29,0xa0,0x0, 0x3,
+0x29,0x60,0x0, 0x1, 0x7e,0x70,0x1, 0xbe,0x80,0x1, 0x78,0x7, 0x29,0xa0,0x0, 0x2,
+0x7e,0xb, 0x60,0xa, 0x7, 0xa, 0x29,0x2d,0x2, 0xa, 0x16,0xbd,0x1, 0x48,0xc, 0xa,
+0x17,0xa, 0x3a,0x2d,0x31,0xbd,0x23,0x18,0x2, 0xd3,0x22,0xc3,0x22,0xca,0x3b,0x12,
+0xd1,0x0, 0x75,0x5f,0x0, 0x7e,0xa1,0x5f,0x74,0x6, 0xa4,0x12,0x67,0xf, 0x30,0xe1,
+0x31,0x7f,0x7, 0x7c,0xbc,0x7e,0x70,0x1, 0x12,0x66,0x88,0x50,0x25,0x7f,0x7, 0x7c,
+0xbe,0x12,0x66,0x85,0x50,0x1c,0x7f,0x7, 0x7c,0xbd,0x6c,0x77,0x12,0x66,0x88,0x50,
+0x11,0x7f,0x7, 0x7c,0xbf,0x6c,0x77,0x12,0x66,0x88,0x50,0x6, 0x29,0xb7,0x0, 0x4,
+0x80,0xa, 0x5, 0x5f,0xe5,0x5f,0xbe,0xb0,0x1e,0x40,0xba,0xe4,0xda,0x3b,0x22,0x7d,
+0xf5,0x2e,0xf4,0x2, 0xe9,0x6d,0xee,0x29,0xb7,0x0, 0x5, 0x22,0xca,0x3b,0x7e,0xf3,
+0x24,0x40,0x12,0x8a,0x35,0x40,0x76,0x6d,0x33,0x9e,0x37,0x24,0x1b,0x3e,0x34,0xbe,
+0x37,0xa, 0x50,0x18,0x68,0x7e,0xb3,0x1f,0x5e,0x70,0x62,0x7e,0xb3,0x22,0x19,0xb4,
+0x1, 0x58,0x7e,0x37,0x24,0x1d,0x7a,0x35,0x26,0x7e,0x67,0x24,0x1f,0x6c,0xee,0x80,
+0x44,0x7c,0xbe,0x12,0x55,0x62,0x60,0x3b,0x12,0x67,0xa0,0xf5,0x24,0x9, 0xa3,0x20,
+0x6c,0x7a,0xa1,0x25,0x74,0x2, 0xa4,0x49,0x35,0x5, 0xc, 0xbd,0x36,0x48,0x13,0xe5,
+0x24,0xa, 0x2b,0xa, 0x3f,0x2d,0x32,0x3e,0x34,0x49,0x33,0x5, 0xc, 0xbe,0x35,0x26,
+0x58,0x11,0x7c,0xbe,0x6c,0x77,0x12,0x65,0xe0,0x12,0x67,0xa0,0x9, 0x73,0x20,0x6c,
+0x12,0x9e,0xb1,0xb, 0xe0,0x12,0x6f,0x96,0x38,0xb7,0x12,0x8e,0xf1,0xda,0x3b,0x22,
+0x7e,0x70,0x2, 0xac,0x7e,0x9, 0xb3,0x20,0x6b,0x22,0x12,0x9f,0xbd,0x12,0x9c,0x32,
+0x12,0x67,0x1c,0x12,0x9c,0xea,0x2, 0x67,0xb9,0xca,0x3b,0x12,0x4d,0xe7,0x7e,0xb3,
+0x21,0xf5,0x60,0x6, 0x7e,0xb3,0x3e,0x2e,0x60,0x9, 0xe4,0x7a,0xb3,0x3e,0x30,0x7a,
+0xb3,0x3d,0xb5,0x7e,0xb3,0x3e,0x2e,0x70,0x67,0x6c,0x99,0x80,0x5b,0x74,0x2, 0xac,
+0xb9,0x9, 0x85,0x20,0x6b,0x9, 0xf5,0x20,0x6c,0x7c,0xb9,0x12,0x9e,0xcc,0x40,0x46,
+0x6c,0xee,0x80,0x3a,0x74,0x2, 0xac,0xbe,0x9, 0xd5,0x3d,0xb6,0x9, 0xc5,0x3d,0xb7,
+0xa, 0x28,0xa, 0x3d,0x12,0x68,0x63,0x78,0x23,0xa, 0x2f,0xa, 0x3c,0x12,0x68,0x63,
+0x78,0x1a,0x7c,0xb9,0x12,0x68,0x6b,0x7e,0x14,0x62,0x41,0x12,0x6f,0xe6,0xbd,0x32,
+0x58,0xa, 0x12,0x6e,0xd0,0x7c,0xb8,0x7c,0x7f,0x12,0x9e,0xb1,0xb, 0xe0,0x7e,0x73,
+0x3e,0x30,0xbc,0x7e,0x38,0xbe,0xb, 0x90,0x7e,0x73,0x21,0xf5,0xbc,0x79,0x38,0x9d,
+0x7e,0x73,0x3d,0xb5,0x7a,0x73,0x3e,0x30,0xa, 0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,
+0x3d,0xf2,0x7e,0x8, 0x3d,0xb6,0x12,0x29,0x4d,0x1b,0xfd,0xe4,0x7a,0xb3,0x3e,0x2e,
+0xda,0x3b,0x22,0x9d,0x32,0x12,0x29,0xb4,0x4d,0x33,0x22,0x7c,0xab,0x7e,0x70,0x2,
+0xac,0x7a,0x12,0x9e,0xa8,0x2, 0x4f,0x6f,0xca,0x79,0x7e,0xc4,0x0, 0x6, 0x7e,0xb3,
+0x21,0xf5,0x70,0x20,0x6d,0xcc,0x7a,0xc7,0x3d,0x37,0x7a,0xc7,0x3d,0x35,0xc2,0x11,
+0x7e,0x8, 0x3d,0x39,0x7e,0x34,0x0, 0x4, 0x74,0xff,0x12,0x29,0x72,0xe4,0x7a,0xb3,
+0x3d,0x34,0x41,0x82,0x12,0x6c,0x1f,0x38,0x2, 0x21,0xc3,0x6c,0xee,0x21,0x6e,0x6c,
+0xff,0x21,0x65,0x12,0x6a,0x8d,0xa, 0x27,0xa, 0x3e,0x9, 0x73,0x3d,0x39,0x12,0x6c,
+0x4b,0x8, 0x2, 0x21,0x52,0x12,0x6a,0x9a,0xa, 0x27,0xa, 0x3e,0x9, 0x73,0x3d,0x3b,
+0x12,0x6c,0x4b,0x18,0x7d,0x12,0x6a,0xbd,0x58,0xb, 0x12,0x6c,0x2f,0x28,0xf, 0x7e,
+0xc4,0x0, 0x8, 0x80,0x9, 0xbe,0xf0,0x0, 0x28,0x4, 0x7e,0xc4,0x0, 0xb, 0x12,0x6a,
+0xa7,0x68,0x5, 0x12,0x6a,0x85,0x78,0x4, 0x7e,0xc4,0x0, 0x4, 0xbd,0xc4,0x58,0x18,
+0x7e,0x34,0x1, 0x90,0x74,0x2, 0xac,0xbe,0x12,0x6a,0xa3,0x68,0x5, 0x12,0x6a,0x85,
+0x78,0x13,0x7e,0x34,0x3, 0x20,0x80,0xa, 0x7d,0x5c,0x1b,0x55,0xbd,0x54,0x48,0x5,
+0x6d,0x33,0x12,0x6c,0x37,0x7e,0x70,0x2, 0xac,0x7e,0x49,0x53,0x3d,0x35,0xbe,0x54,
+0x0, 0x0, 0x28,0x19,0x2e,0x34,0x3d,0x35,0x1b,0x54,0x1b,0x38,0x50,0x12,0x6a,0x8d,
+0xa, 0x5e,0x12,0x6a,0x96,0xa, 0x5e,0x19,0x75,0x3d,0x3b,0x80,0x1f,0x12,0x6e,0x86,
+0x80,0x1a,0x7e,0xb3,0x21,0xf5,0x14,0xbc,0xbf,0x78,0x8, 0x6d,0x33,0x12,0x6c,0x37,
+0x12,0x6e,0x86,0xb, 0xf0,0x12,0x6a,0xf0,0x28,0x2, 0x1, 0xb3,0xb, 0xe0,0x7e,0x73,
+0x3d,0x34,0xbc,0x7e,0x28,0x2, 0x1, 0xaf,0x7e,0x57,0x3d,0x35,0x4d,0x55,0x78,0x29,
+0x12,0x6c,0x40,0x28,0x24,0x7a,0x57,0x3d,0x35,0x7e,0x73,0x3d,0x3a,0x7a,0x73,0x3d,
+0x39,0x7e,0x73,0x3d,0x3c,0x7a,0x73,0x3d,0x3b,0x6d,0x55,0x7a,0x57,0x3d,0x37,0x74,
+0xff,0x7a,0xb3,0x3d,0x3a,0x7a,0xb3,0x3d,0x3c,0xe4,0x7a,0xb3,0x3d,0x34,0x7e,0x57,
+0x3d,0x35,0xbe,0x54,0x0, 0x0, 0x28,0x3, 0x12,0x6a,0xb3,0x12,0x6c,0x40,0x28,0x3,
+0x12,0x6a,0xb3,0x7e,0x73,0x3d,0x34,0xbe,0x70,0x2, 0x40,0x2, 0x41,0x74,0x7e,0x73,
+0x21,0xf5,0xbe,0x73,0x3d,0x34,0x38,0x2, 0x41,0x74,0x6c,0xff,0x41,0x6d,0x12,0x6a,
+0x8d,0xa, 0x27,0x7e,0x73,0x3d,0x39,0x12,0x57,0x74,0xbe,0x34,0x0, 0x1, 0x18,0x12,
+0x12,0x6a,0x9a,0xa, 0x27,0x7e,0x73,0x3d,0x3b,0x12,0x57,0x74,0xbe,0x34,0x0, 0x1,
+0x8, 0x69,0x12,0x6a,0xbd,0x58,0xb, 0x12,0x6c,0x2f,0x28,0xf, 0x7e,0xc4,0x0, 0x8,
+0x80,0x9, 0xbe,0xf0,0x0, 0x28,0x4, 0x7e,0xc4,0x0, 0xb, 0x12,0x6a,0xa7,0x68,0x5,
+0x12,0x6a,0x85,0x78,0x4, 0x7e,0xc4,0x0, 0x4, 0xbd,0xc4,0x58,0x35,0x7e,0x34,0x1,
+0x90,0x12,0x6c,0x27,0x12,0x6a,0xa3,0x68,0x5, 0x12,0x6a,0x85,0x78,0xb, 0x7e,0x34,
+0x3, 0x20,0x12,0x6c,0x27,0x59,0x35,0x3d,0x35,0x12,0x6a,0x8d,0x7e,0x63,0x3d,0x34,
+0xa, 0x56,0x12,0x6a,0x96,0x7e,0x63,0x3d,0x34,0xa, 0x56,0x19,0x75,0x3d,0x3b,0x12,
+0x6a,0xb3,0x7e,0xb3,0x3d,0x34,0xbe,0xb0,0x2, 0x68,0x9, 0xb, 0xf0,0x12,0x6a,0xf0,
+0x28,0x2, 0x21,0xde,0x12,0x6c,0x1f,0x28,0x7, 0x20,0x11,0x6, 0xd2,0x11,0x80,0x2,
+0xc2,0x11,0xda,0x79,0x22,0x7e,0xb3,0x24,0x3b,0x14,0xbc,0xab,0x22,0x74,0x2, 0xac,
+0xbf,0x9, 0x75,0x20,0x6b,0x22,0x19,0x75,0x3d,0x39,0x74,0x2, 0xac,0xbf,0x9, 0x75,
+0x20,0x6c,0x22,0x59,0x35,0x3d,0x35,0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xa3,0x20,0x6b,
+0x4c,0xaa,0x22,0x7e,0xb3,0x3d,0x34,0x4, 0x7a,0xb3,0x3d,0x34,0x22,0x7c,0xbf,0x12,
+0x6a,0xd0,0x1a,0x4b,0x7c,0xbf,0x12,0x68,0x6b,0x7d,0xd3,0xbe,0xd4,0x2, 0xbc,0x22,
+0xca,0xf8,0x7c,0xfb,0x7e,0x70,0x2, 0x6c,0x66,0x12,0x9d,0xa5,0x7f,0x71,0x7c,0xbf,
+0x12,0x68,0x6b,0x12,0x6e,0xaa,0x7f,0x17,0x12,0x27,0x66,0x7c,0xb7,0xda,0xf8,0x22,
+0x7e,0x73,0x21,0xf5,0xbc,0x7f,0x22,0xca,0x79,0x7e,0xa3,0x24,0x3a,0x7e,0x37,0x22,
+0xa, 0xe4,0x7a,0xb3,0x22,0x17,0x7a,0xb3,0x40,0x2f,0x7e,0xb3,0x20,0x61,0xbe,0xb0,
+0x0, 0x28,0x51,0x7e,0x53,0x21,0xf6,0xbe,0x50,0x0, 0x28,0x48,0x6c,0xff,0x80,0x40,
+0x7e,0x30,0x2, 0xac,0x3f,0x9, 0x41,0x20,0xa7,0x9, 0xe1,0x20,0xa8,0x7e,0x30,0x2,
+0xac,0x3e,0x49,0x1, 0x5, 0xc, 0x6d,0x11,0x9e,0x17,0x24,0x1f,0xbd,0x1, 0x58,0x1e,
+0xa, 0x4, 0xa, 0x1a,0x2d,0x10,0x3e,0x14,0x49,0x1, 0x5, 0xc, 0x6d,0x11,0x9e,0x17,
+0x24,0x1d,0xbd,0x1, 0x58,0x8, 0x74,0x1, 0x7a,0xb3,0x22,0x17,0x80,0x6, 0xb, 0xf0,
+0xbc,0x5f,0x38,0xbc,0xe4,0x7a,0xb3,0x22,0x18,0x7e,0xb3,0x1f,0xf4,0x70,0x45,0x7e,
+0xa3,0x21,0xf5,0xbe,0xa0,0x0, 0x28,0x3c,0x6c,0xff,0x80,0x34,0x7e,0x50,0x2, 0xac,
+0x5f,0x9, 0xe2,0x20,0x6c,0x7e,0x50,0x2, 0xac,0x5e,0x49,0x12,0x5, 0x92,0x6d,0x22,
+0x9d,0x23,0xbd,0x12,0x58,0x18,0x74,0x1, 0x7a,0xb3,0x22,0x18,0x7e,0x27,0x40,0x32,
+0xbe,0x24,0xb, 0xb8,0x50,0xe, 0x74,0x16,0x7a,0xb3,0x40,0x2f,0x80,0x6, 0xb, 0xf0,
+0xbc,0xaf,0x38,0xc8,0x12,0xae,0x27,0xe4,0x7a,0xb3,0x22,0x1a,0x7e,0x37,0x21,0xf9,
+0x2e,0x37,0x21,0xf7,0xbe,0x37,0x22,0x10,0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x22,0x1a,
+0x74,0x1, 0x7a,0xb3,0x22,0x1b,0x6c,0xff,0x80,0x21,0x12,0x6c,0x17,0xac,0xbf,0x49,
+0x25,0x1f,0x68,0x7d,0x43,0x9d,0x42,0x7d,0x34,0x12,0x29,0xb4,0xbe,0x37,0x22,0xe,
+0x8, 0x7, 0xe4,0x7a,0xb3,0x22,0x1b,0x80,0x7, 0xb, 0xf0,0x12,0x6a,0xf0,0x38,0xda,
+0x6c,0xff,0x80,0xb, 0x12,0x6c,0x17,0xac,0xbf,0x59,0x35,0x1f,0x68,0xb, 0xf0,0x12,
+0x6a,0xf0,0x38,0xf0,0xda,0x79,0x22,0x7c,0xbf,0x12,0x68,0x6b,0x74,0x2, 0x22,0x7e,
+0x73,0x3d,0x34,0xbe,0x70,0x0, 0x22,0x7e,0xa3,0x3d,0x34,0x74,0x2, 0xa4,0x22,0x7e,
+0xc4,0x0, 0x4, 0xbe,0xf0,0x0, 0x22,0x74,0x2, 0xac,0xbe,0x59,0x35,0x3d,0x35,0x22,
+0x7e,0x57,0x3d,0x37,0xbe,0x54,0x0, 0x0, 0x22,0x1a,0x3b,0x9d,0x32,0x12,0x29,0xb4,
+0xbe,0x34,0x0, 0x1, 0x22,0xca,0x3b,0x7a,0x41,0x2a,0x12,0xd1,0x0, 0x74,0x9, 0xac,
+0xbf,0x7d,0x95,0x2e,0x94,0x20,0xe7,0x6d,0x88,0x7e,0xe7,0x24,0x32,0xe4,0x39,0xb4,
+0x0, 0x6, 0x12,0x67,0xa0,0xf5,0x35,0x9, 0xb3,0x20,0x6c,0xf5,0x36,0x7e,0x73,0x24,
+0x3a,0x7c,0x6d,0x7e,0x8, 0x0, 0x39,0x12,0x6f,0x28,0xf5,0x37,0xe5,0x35,0x7e,0x73,
+0x24,0x39,0x7c,0x6c,0x7e,0x8, 0x0, 0x38,0x12,0x6f,0x28,0x7c,0xab,0xe5,0x38,0x7e,
+0x71,0x39,0x12,0x57,0xe5,0x7d,0xf3,0x7a,0xf5,0x41,0x7e,0xf4,0x1e,0x6a,0x7a,0xf5,
+0x43,0x85,0x38,0x3b,0x85,0x39,0x3c,0x7a,0xa1,0x3d,0x85,0x37,0x3e,0x7e,0xb3,0x24,
+0x25,0xf5,0x3f,0x75,0x40,0x0, 0xe5,0x2a,0xb4,0x1, 0x8, 0xe5,0x3f,0x1e,0xb0,0x1e,
+0xb0,0xf5,0x3f,0x7e,0x8, 0x0, 0x3b,0x12,0x6f,0xee,0x7d,0x23,0x6d,0x33,0x7e,0xb7,
+0x1e,0x6c,0x6d,0xaa,0x2f,0x51,0x7e,0x37,0x1e,0x6e,0x6d,0x22,0x7d,0x3, 0x6d,0x11,
+0x7e,0x37,0x1e,0x70,0x2f,0x10,0x7a,0x1d,0x2b,0x7e,0x37,0x1e,0x72,0x6d,0x22,0x7d,
+0x3, 0x7e,0x37,0x1e,0x74,0x2f,0x10,0x7a,0x1d,0x2f,0x7f,0x65,0xa, 0x4c,0xe5,0x35,
+0xa, 0x5b,0x9d,0x54,0xf5,0x33,0xa1,0xf3,0xa, 0x4d,0xe5,0x36,0xa, 0x5b,0x9d,0x54,
+0xf5,0x34,0xa1,0xdd,0xe5,0x33,0xbe,0xb0,0x0, 0x58,0x2, 0xa1,0xdb,0x7e,0x73,0x24,
+0x39,0xbe,0x71,0x33,0x18,0x2, 0xa1,0xdb,0xe5,0x34,0xbe,0xb0,0x0, 0x58,0x2, 0xa1,
+0xdb,0x7e,0x73,0x24,0x3a,0xbe,0x71,0x34,0x18,0x2, 0xa1,0xdb,0xe5,0x33,0x7e,0x71,
+0x34,0x12,0x4f,0x6f,0x7e,0x53,0x24,0x25,0xa, 0x25,0x7d,0xf3,0x9d,0xf2,0xbe,0xf4,
+0x0, 0x0, 0x8, 0x77,0xbd,0xef,0x18,0xd, 0x7f,0x14,0x2e,0x34,0x0, 0x6, 0x7e,0x1b,
+0xb0,0x4, 0x7a,0x1b,0xb0,0xe5,0x35,0xa, 0x2b,0xe5,0x33,0x12,0x6c,0x49,0x18,0xb,
+0xe5,0x36,0xa, 0x2b,0xe5,0x34,0x12,0x6c,0x49,0x8, 0x50,0xe5,0x33,0x7e,0x71,0x34,
+0x7c,0x6e,0x12,0xbf,0x23,0xf5,0x3a,0xb4,0x2, 0x6, 0x7d,0x3f,0xe, 0x34,0x9d,0xf3,
+0xe5,0x3a,0xbe,0xb0,0x2, 0x68,0x5, 0xe5,0x3a,0xb4,0x1, 0x2f,0x12,0x6e,0x78,0xe5,
+0x33,0x12,0x6e,0x7f,0x7f,0x1, 0x7e,0x1d,0x2b,0x9f,0x10,0x7a,0x1d,0x2b,0x12,0x6e,
+0x78,0xe5,0x34,0x12,0x6e,0x7f,0x7f,0x1, 0x7e,0x1d,0x2f,0x9f,0x10,0x7a,0x1d,0x2f,
+0x12,0x6e,0x78,0x9f,0x51,0x1a,0x26,0x1a,0x24,0x9f,0x61,0x5, 0x34,0xa, 0x2d,0xe5,
+0x36,0xa, 0x3b,0x2d,0x32,0x1a,0x27,0xe5,0x34,0x1a,0x3b,0xbd,0x32,0x18,0x2, 0xa1,
+0x24,0x5, 0x33,0xa, 0x2c,0xe5,0x35,0xa, 0x3b,0x2d,0x32,0x1a,0x37,0xe5,0x33,0x1a,
+0xfb,0xbd,0xf3,0x18,0x2, 0xa1,0x18,0xbe,0x58,0x0, 0x0, 0x78,0x2, 0xb, 0x5c,0xbe,
+0x68,0x0, 0x0, 0x78,0x2, 0xb, 0x6c,0x7e,0x1d,0x2b,0x7f,0x5, 0x12,0x6e,0x93,0x1b,
+0x4a,0x30,0x7e,0x1d,0x2f,0x7f,0x6, 0x12,0x6e,0x93,0x79,0x34,0x0, 0x2, 0x7e,0xb3,
+0x24,0x31,0x60,0xd, 0x1e,0xd4,0x1e,0xc4,0x50,0x4, 0x4e,0xd4,0x80,0x0, 0x14,0x78,
+0xf3,0xbe,0x68,0x0, 0x7f,0x28,0x4, 0x7e,0x68,0x0, 0x7f,0x7d,0x3d,0x39,0x74,0x0,
+0x5, 0x74,0x9, 0xac,0xbe,0x9, 0x75,0x20,0xed,0x39,0x74,0x0, 0x6, 0x7e,0xa1,0x35,
+0x7e,0x70,0x9, 0xac,0x7f,0x19,0xa3,0x20,0xee,0x7e,0xa1,0x36,0x7e,0x70,0x9, 0xac,
+0x7f,0x19,0xa3,0x20,0xef,0xda,0x3b,0x22,0x7d,0x3f,0x1a,0x26,0x1a,0x24,0x22,0x1a,
+0x1b,0x1a,0x2, 0x2, 0x26,0xf9,0x74,0xff,0xa, 0x3e,0x19,0xb3,0x3d,0x39,0x19,0xb3,
+0x3d,0x3b,0x22,0x7c,0x45,0x7c,0x56,0x7c,0x67,0x6c,0x77,0x12,0x27,0x15,0x2e,0x18,
+0x0, 0x80,0x22,0x7c,0xb9,0x7c,0x78,0x12,0x4f,0x6f,0x7d,0x13,0x1a,0x2, 0x1a,0x0,
+0x22,0x6c,0x99,0x80,0x10,0x7c,0xb9,0x12,0x68,0x6b,0xbe,0x37,0x24,0x28,0x58,0x3,
+0x12,0x6e,0xd0,0xb, 0x90,0x7e,0x83,0x21,0xf5,0xbc,0x89,0x38,0xe8,0x2, 0x4d,0xe7,
+0x7c,0xb9,0x6c,0x77,0x2, 0x65,0xe0,0xca,0x79,0x6c,0xff,0x7e,0xd7,0x24,0x26,0x6c,
+0xee,0x80,0x35,0x7c,0xbe,0x12,0x68,0x6b,0xbd,0x3d,0x48,0x2a,0x7c,0xbe,0x12,0x55,
+0x62,0x60,0x23,0x7e,0xc4,0x0, 0x9, 0xca,0xc9,0x7e,0x70,0x9, 0xac,0x7e,0x2e,0x34,
+0x20,0xe7,0x6d,0x22,0x7e,0x30,0x9, 0xac,0x3f,0x2e,0x14,0x22,0x1f,0x6d,0x0, 0x12,
+0x29,0x4d,0x1b,0xfd,0xb, 0xf0,0xb, 0xe0,0x12,0x6f,0x96,0x38,0xc6,0x7a,0x73,0x22,
+0x4, 0x7a,0xf3,0x23,0x87,0xda,0x79,0x22,0xca,0xf8,0x7c,0xf6,0x7c,0x87,0x7c,0x9b,
+0xa, 0x2f,0x7d,0x32,0x3e,0x34,0xb, 0x34,0x7c,0xb7,0xbc,0xf9,0x38,0x14,0xa, 0xf8,
+0x1b,0xf4,0xa, 0x3f,0x9d,0xf3,0xa, 0x39,0xbd,0x3f,0x18,0x6, 0x7c,0xab,0xa, 0x39,
+0x80,0x1d,0xbc,0xf9,0x28,0xd, 0xa, 0x39,0xa, 0x5f,0x2d,0x53,0xb, 0x54,0x7c,0xab,
+0xe4,0x80,0x10,0xa, 0x3f,0xa, 0x58,0x2d,0x53,0xa, 0x39,0x9d,0x53,0x7c,0xab,0x9d,
+0x32,0x7c,0xb7,0x7a,0xb, 0xb0,0x7c,0xba,0xda,0xf8,0x22,0x7e,0x37,0x3f,0xfa,0xb,
+0x34,0x7a,0x37,0x3f,0xfa,0x7e,0x37,0x3f,0xfc,0xbe,0x37,0x3f,0xfa,0x28,0x3, 0x2,
+0xc1,0x45,0x22,0x2, 0x6f,0x7b,0x7e,0x73,0x21,0xf5,0xbc,0x7e,0x22,0xca,0xd8,0xca,
+0x79,0x6c,0xff,0x6c,0xee,0x80,0x16,0x7c,0xbe,0x12,0x55,0x62,0x60,0xd, 0x7c,0xbe,
+0x12,0x91,0xea,0x7c,0xdb,0xbc,0xdf,0x28,0x2, 0x7c,0xfd,0xb, 0xe0,0x12,0x6f,0x96,
+0x38,0xe5,0x7c,0xbf,0x12,0x92,0xf7,0x12,0x6f,0xcf,0xda,0x79,0xda,0xd8,0x22,0x30,
+0x10,0x13,0x12,0x6f,0xf6,0x68,0x6, 0x7e,0xb3,0x40,0x2d,0x60,0x8, 0x7e,0x34,0xb,
+0xb8,0x7a,0x37,0x3, 0xfd,0x22,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x20,0x22,0x12,0x17,
+0x5b,0x7e,0x37,0x1e,0x6a,0x22,0x7e,0xb3,0x22,0x19,0xbe,0xb0,0x1, 0x22,0x7e,0x34,
+0x0, 0x4, 0xca,0x39,0x7e,0x34,0x61,0x3d,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x25,0x6c,
+0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x34,0x23,0x93,0x7a,0x37,0x25,0x72,0xe4,0x7a,0xb3,
+0x25,0x70,0x7a,0xb3,0x25,0x71,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x70,0x4b,0x7e,
+0x8, 0x1f,0x5f,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x34,0x25,0x74,0x7a,0x37,0x1f,0x65,
+0x74,0x1, 0x7a,0xb3,0x1f,0x63,0x7a,0xb3,0x1f,0x64,0x22,0x7e,0x34,0x61,0x39,0x7e,
+0x24,0x0, 0xff,0x22,0xe4,0x7a,0xb3,0x3f,0x21,0x7a,0xb3,0x3f,0x22,0x90,0x60,0x50,
+0x93,0x7a,0xb3,0x3f,0x23,0x90,0x60,0x51,0xe4,0x93,0x7a,0xb3,0x3f,0x24,0xe4,0x7a,
+0xb3,0x3f,0x25,0x90,0x60,0xa1,0x93,0x7a,0xb3,0x3f,0x26,0xe4,0x7a,0xb3,0x3f,0x27,
+0x7a,0xb3,0x3f,0x28,0x90,0x61,0xda,0x93,0x7a,0xb3,0x3f,0x2a,0x7e,0x34,0x61,0x5f,
+0x12,0x2d,0x68,0x1e,0x34,0x1e,0x34,0x7a,0x73,0x3f,0x2e,0x7e,0x34,0x61,0x65,0x12,
+0x2d,0x68,0x1e,0x34,0x1e,0x34,0x7a,0x73,0x3f,0x2f,0x74,0x64,0x7a,0xb3,0x3f,0x40,
+0x90,0x61,0x28,0xe4,0x93,0x7a,0xb3,0x3f,0x41,0x90,0x61,0x27,0xe4,0x93,0x7a,0xb3,
+0x3f,0x2d,0x90,0x61,0x29,0xe4,0x93,0x7a,0xb3,0x3f,0x43,0x90,0x61,0x34,0xe4,0x93,
+0x7a,0xb3,0x3f,0x42,0x90,0x61,0x2d,0xe4,0x93,0x7a,0xb3,0x3f,0x44,0x90,0x61,0x35,
+0xe4,0x93,0x7a,0xb3,0x3f,0x3f,0x74,0x1, 0x7a,0xb3,0x3f,0x3b,0xe4,0x7a,0xb3,0x3f,
+0x3c,0x7a,0xb3,0x3f,0x3d,0x7e,0x8, 0x3f,0x45,0x7e,0x34,0x0, 0x2c,0x12,0x29,0x72,
+0x7e,0x34,0x60,0xde,0x12,0x2d,0x68,0xa, 0x36,0x7a,0x73,0x3f,0x50,0x7e,0x34,0x60,
+0xde,0x12,0x2d,0x68,0x7a,0x73,0x3f,0x51,0x90,0x60,0xdc,0x93,0x7a,0xb3,0x3f,0x52,
+0x90,0x60,0xdd,0xe4,0x93,0x7a,0xb3,0x3f,0x53,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,
+0x70,0x4b,0x7e,0x8, 0x3f,0x61,0x12,0x29,0x4d,0x1b,0xfd,0x74,0x6, 0x7a,0xb3,0x3f,
+0x6e,0x74,0x1, 0x7a,0xb3,0x3f,0x65,0x7e,0x34,0x0, 0x28,0xca,0x39,0x7e,0x34,0x61,
+0xeb,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x1f,0xa4,0x12,0x29,0x4d,0x1b,0xfd,0x22,0x12,
+0x70,0x54,0x12,0x40,0x86,0x12,0x0, 0x49,0x12,0xd0,0xac,0x7e,0x18,0x4, 0x0, 0x7a,
+0x1f,0x7, 0x28,0x7e,0xf, 0x7, 0x28,0x7e,0x1f,0x7, 0x24,0x12,0x78,0xc7,0x7e,0x18,
+0xa, 0x62,0x7a,0x1f,0x1b,0xd2,0x7e,0x18,0x13,0x1a,0x7a,0x1f,0x1b,0xd6,0x7e,0xf,
+0x1b,0xd6,0x7e,0x1f,0x1b,0xd2,0x12,0x78,0xa4,0x12,0x78,0x58,0x12,0x2e,0x83,0x12,
+0x75,0x46,0x12,0x71,0xff,0x2, 0x71,0xa8,0xe4,0x7a,0xb3,0x3f,0xe3,0x7a,0xb3,0x3f,
+0xe4,0x7a,0xb3,0x3f,0xe5,0x22,0x12,0x71,0xa8,0x12,0x71,0xeb,0x2, 0x71,0xbf,0x7e,
+0x34,0x0, 0x3, 0x6d,0x22,0x2, 0x71,0xc8,0x7d,0x43,0x7e,0xa3,0x3f,0xe3,0xbe,0xa0,
+0x5, 0x50,0x16,0x7e,0x70,0x4, 0xac,0x7a,0x59,0x43,0x3f,0xe6,0x59,0x23,0x3f,0xe8,
+0x7c,0xba,0x4, 0x7a,0xb3,0x3f,0xe3,0xc3,0x22,0xd3,0x22,0x6d,0x33,0x7e,0x24,0x7,
+0x2c,0x12,0x71,0xc8,0x7e,0x34,0x0, 0x1, 0x7e,0x24,0x8, 0xbe,0x2, 0x71,0xc8,0x12,
+0x75,0x84,0x7e,0x24,0x0, 0x3, 0xad,0x32,0x7e,0x8, 0x22,0x1f,0x74,0xff,0x12,0x29,
+0x72,0x12,0x9b,0xc1,0x7e,0x8, 0x23,0x2d,0x12,0x72,0x27,0x7e,0x8, 0x23,0x87,0x7e,
+0x34,0x0, 0xb, 0xe4,0x2, 0x29,0x72,0x6c,0xaa,0x80,0x20,0x74,0x3, 0x12,0xa7,0x3f,
+0x7f,0x10,0x2d,0x34,0x39,0xb1,0x0, 0xa, 0x12,0x75,0x5, 0x7f,0x70,0x2d,0xf3,0x79,
+0x47,0x0, 0x14,0x2d,0x31,0x79,0x41,0x0, 0x28,0xb, 0xa0,0x12,0x72,0x51,0x38,0xdb,
+0x22,0x90,0x60,0xa1,0xe4,0x93,0xbc,0xba,0x22,0xca,0x3b,0x7e,0x38,0x23,0x2d,0x6c,
+0xaa,0x80,0x1f,0x7e,0x70,0xff,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x72,0x22,0x23,0xe4,
+0xa, 0x4a,0x19,0xb4,0x31,0xbb,0x74,0xff,0x19,0xb4,0x31,0xcd,0x19,0xb4,0x31,0xd7,
+0xb, 0xa0,0x12,0x72,0x51,0x38,0xdc,0x7e,0x73,0x23,0x87,0xa5,0xbf,0x0, 0x1f,0x7e,
+0xb3,0x40,0x42,0x70,0x2, 0x81,0x74,0x6c,0xaa,0x80,0xc, 0x7e,0x44,0x7f,0xff,0x12,
+0x75,0xf, 0x12,0x75,0x25,0xb, 0xa0,0x12,0x72,0x51,0x38,0xef,0x81,0x74,0x7e,0xb3,
+0x40,0x42,0x70,0x3e,0xbe,0x70,0x0, 0x28,0x39,0x6c,0xaa,0x80,0x2b,0x7e,0x70,0x9,
+0xac,0x7a,0x49,0x43,0x22,0x1f,0x12,0x75,0xf, 0x49,0x33,0x22,0x21,0x7f,0x3, 0x2d,
+0x12,0x79,0x30,0x0, 0x28,0x74,0x1, 0xa, 0x4a,0x19,0xb4,0x31,0xbb,0x7e,0x70,0x9,
+0xac,0x7a,0x19,0xa3,0x22,0x23,0xb, 0xa0,0x7e,0xb3,0x23,0x87,0xbc,0xba,0x38,0xcd,
+0x81,0x74,0x6c,0xaa,0x80,0x17,0x12,0x75,0x5, 0x3e,0x34,0x59,0x43,0x1e,0x1a,0x59,
+0x43,0x1e,0x1c,0x59,0x43,0x1e,0x42,0x59,0x43,0x1e,0x44,0xb, 0xa0,0x12,0x72,0x51,
+0x38,0xe4,0x6c,0xaa,0x80,0x3d,0x75,0x24,0x0, 0x80,0x31,0x7e,0x71,0x24,0x74,0x2,
+0xac,0x7b,0x7f,0x3, 0x2d,0x13,0x69,0x30,0x0, 0x14,0xbe,0x34,0x7f,0xff,0x68,0x1a,
+0x12,0x75,0x2e,0xb4,0xff,0x14,0x12,0x75,0x1d,0x59,0x32,0x1e,0x1a,0x69,0x30,0x0,
+0x28,0x59,0x32,0x1e,0x1c,0x12,0x75,0x37,0x80,0x7, 0x5, 0x24,0x12,0x74,0xfc,0x38,
+0xca,0xb, 0xa0,0x7e,0xb3,0x40,0x42,0xbc,0xba,0x38,0xbb,0x6c,0xaa,0x80,0x22,0xa,
+0x3a,0x9, 0xb3,0x31,0xcd,0xb4,0xff,0x17,0x75,0x24,0x0, 0x80,0xd, 0x12,0x75,0x2e,
+0xb4,0xff,0x5, 0x12,0x75,0x37,0x80,0x7, 0x5, 0x24,0x12,0x74,0xfc,0x38,0xee,0xb,
+0xa0,0x12,0x72,0x51,0x38,0xd9,0x6c,0xaa,0x80,0x1a,0x7e,0x70,0x9, 0xac,0x7a,0x49,
+0x43,0x22,0x1f,0x12,0x75,0x1d,0x59,0x42,0x1e,0x42,0x49,0x33,0x22,0x21,0x59,0x32,
+0x1e,0x44,0xb, 0xa0,0x7e,0xb3,0x23,0x87,0xbc,0xba,0x38,0xde,0x7e,0x34,0x1e,0x1a,
+0x7a,0x37,0x31,0xc7,0x7e,0x34,0x1e,0x42,0x7a,0x37,0x31,0xc9,0x7e,0x34,0x1e,0x6a,
+0x7a,0x37,0x31,0xcb,0x7e,0x73,0x40,0x42,0x7a,0x73,0x31,0xc5,0x7e,0x73,0x23,0x87,
+0x7a,0x73,0x31,0xc6,0x7e,0x8, 0x31,0xc5,0x12,0x10,0x0, 0x6c,0xaa,0x80,0x64,0x7e,
+0x70,0xff,0x75,0x24,0x0, 0x80,0x1d,0x7e,0x51,0x24,0x74,0x2, 0xac,0x5b,0x49,0x12,
+0x1e,0x6a,0xa, 0x2a,0xbd,0x21,0x78,0xa, 0xe5,0x24,0xa, 0x3b,0x9, 0x73,0x31,0xcd,
+0x80,0x7, 0x5, 0x24,0x12,0x74,0xfc,0x38,0xde,0xbe,0x70,0xff,0x68,0x33,0x7e,0x50,
+0x9, 0xac,0x5a,0x19,0x72,0x22,0x23,0x74,0x1, 0xa, 0x47,0x19,0xb4,0x31,0xbb,0x7e,
+0x50,0x9, 0xac,0x5a,0x49,0x42,0x22,0x1f,0x7e,0x50,0x2, 0xac,0x57,0x12,0x75,0x14,
+0x7e,0x50,0x9, 0xac,0x5a,0x49,0x42,0x22,0x21,0x7e,0x50,0x2, 0xac,0x57,0x12,0x75,
+0x25,0xb, 0xa0,0x7e,0x63,0x23,0x87,0xbc,0x6a,0x38,0x94,0x6c,0xaa,0x80,0x20,0xa,
+0x3a,0x9, 0xb3,0x31,0xbb,0xbe,0xb0,0x1, 0x68,0x13,0x12,0x75,0x5, 0x7f,0x3, 0x2d,
+0x13,0x79,0x40,0x0, 0x14,0x2d,0x37,0x7d,0x26,0x79,0x41,0x0, 0x28,0xb, 0xa0,0x12,
+0x72,0x51,0x38,0xdb,0x7e,0xb3,0x23,0x87,0x7a,0xb3,0x40,0x42,0xf5,0x24,0x6c,0xaa,
+0x80,0x6b,0xa, 0x3a,0x9, 0xb3,0x31,0xbb,0xb4,0x1, 0x2c,0x12,0x74,0xf5,0x29,0xb1,
+0x0, 0xa, 0xb4,0x1, 0x6, 0x74,0x3, 0x39,0xb1,0x0, 0xa, 0x12,0x74,0xf5,0x29,0x31,
+0x0, 0xa, 0xa5,0xbb,0x3, 0x6, 0xe4,0x7a,0x1b,0xb0,0x80,0x35,0xa5,0xbb,0x0, 0x31,
+0x74,0x2, 0x7a,0x1b,0xb0,0x80,0x2a,0x12,0x74,0xf5,0x29,0xb1,0x0, 0xa, 0xbe,0xb0,
+0x2, 0x68,0x2, 0x70,0x17,0x74,0x1, 0x7a,0x1b,0xb0,0x7e,0x31,0x24,0x7c,0xb3,0x4,
+0xf5,0x24,0x74,0x9, 0xac,0x3b,0x19,0xa1,0x22,0x23,0x80,0x5, 0x74,0x3, 0x7a,0x1b,
+0xb0,0x12,0x74,0xf5,0x7e,0x1b,0xb0,0x39,0xb1,0x0, 0xa, 0xb, 0xa0,0x12,0x72,0x51,
+0x38,0x90,0xda,0x3b,0x22,0xa, 0x3a,0x2d,0x37,0x7d,0x26,0x22,0x90,0x60,0xa1,0xe4,
+0x93,0xbe,0xb1,0x24,0x22,0x7e,0x44,0x7f,0xff,0x7e,0x70,0x2, 0xac,0x7a,0x22,0x7e,
+0x50,0x2, 0xac,0x5a,0x7f,0x3, 0x2d,0x12,0x79,0x40,0x0, 0x14,0x22,0x7e,0x50,0x2,
+0xac,0x5a,0x3e,0x24,0x22,0x7f,0x3, 0x2d,0x12,0x79,0x40,0x0, 0x28,0x22,0xe5,0x24,
+0xa, 0x4b,0x9, 0xb4,0x31,0xd7,0x22,0xe5,0x24,0xa, 0x3a,0x19,0xb3,0x31,0xcd,0x74,
+0x1, 0x19,0xb4,0x31,0xd7,0x22,0x7e,0x8, 0x1f,0xcc,0x7e,0x34,0x2, 0x3a,0xe4,0x12,
+0x29,0x72,0x90,0x60,0xa4,0x93,0xa, 0x3b,0x3e,0x34,0x7e,0x8, 0x1f,0xfd,0x74,0xff,
+0x12,0x29,0x72,0x90,0x60,0xa4,0xe4,0x93,0xa, 0x3b,0x3e,0x34,0x7e,0x8, 0x20,0x25,
+0x74,0xff,0x12,0x29,0x72,0x90,0x60,0xa2,0x12,0x75,0x87,0x7e,0x8, 0x20,0xe7,0x74,
+0xff,0x2, 0x29,0x72,0x90,0x60,0xa1,0xe4,0x93,0x7c,0x7b,0x74,0x9, 0xac,0x7b,0x22,
+0x7c,0x67,0x7c,0x7b,0xa5,0xbf,0x0, 0x17,0xbe,0x60,0x0, 0x28,0xf, 0x74,0x1, 0x7a,
+0xb3,0x23,0x8c,0xe4,0x7a,0xb3,0x23,0x8e,0x7a,0xb3,0x23,0x8f,0x2, 0x57,0x7b,0xa5,
+0xbe,0x0, 0x1d,0x6c,0xaa,0x80,0xe, 0x7e,0x60,0xff,0x7e,0x50,0x9, 0xac,0x5a,0x19,
+0x62,0x22,0xd7,0xb, 0xa0,0x12,0x72,0x51,0x38,0xed,0x74,0x1, 0x7a,0xb3,0x23,0x8b,
+0x6c,0xaa,0x80,0x1a,0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x22,0x1f,0x12,0x75,0xf3,
+0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x22,0x21,0x12,0x75,0xf3,0xb, 0xa0,0xbc,0x7a,
+0x38,0xe2,0x22,0xb, 0x18,0x20,0x3e,0x24,0x3e,0x24,0x1b,0x18,0x20,0x22,0xca,0x79,
+0x7e,0xf3,0x23,0x87,0x7e,0xe3,0x23,0x88,0x7c,0xbf,0x7c,0x7e,0x12,0x75,0x90,0x7c,
+0xbf,0x12,0x99,0xc2,0x4c,0xee,0x78,0x14,0x12,0x81,0x1d,0xca,0x59,0x7e,0x18,0x22,
+0x1f,0x7e,0x8, 0x22,0xd3,0x12,0x29,0x4d,0x1b,0xfd,0x80,0xb, 0x7e,0xb3,0x23,0x8e,
+0x70,0x5, 0x7c,0xbf,0x12,0x76,0xab,0x7c,0xbf,0x12,0x76,0x56,0xbe,0xf0,0x0, 0x28,
+0x6, 0x74,0x1, 0x7a,0xb3,0x23,0x90,0xda,0x79,0x22,0x7e,0xb3,0x3, 0xee,0x70,0x3,
+0x12,0x97,0xc8,0x2, 0x75,0xfe,0x6c,0xaa,0x80,0x4b,0x7e,0x50,0x9, 0xac,0x5a,0x49,
+0x32,0x22,0xd3,0x1e,0x34,0x1e,0x34,0x59,0x32,0x22,0x1f,0x7e,0x50,0x9, 0xac,0x5a,
+0x49,0x32,0x22,0xd5,0x1e,0x34,0x1e,0x34,0x59,0x32,0x22,0x21,0x7e,0x90,0x9, 0xac,
+0x9a,0x9, 0xb4,0x22,0xd7,0x19,0xb4,0x22,0x23,0x7e,0x90,0x9, 0xac,0x9a,0x9, 0xb4,
+0x22,0xd8,0x19,0xb4,0x22,0x24,0x7e,0x90,0x9, 0xac,0x9a,0x9, 0xb4,0x22,0xd9,0x19,
+0xb4,0x22,0x25,0xb, 0xa0,0x12,0x72,0x51,0x38,0xb0,0x22,0xca,0x3b,0x7c,0xfb,0x6c,
+0xee,0x80,0x65,0x6c,0xdd,0x80,0x16,0x74,0x9, 0xac,0xbd,0x9, 0x65,0x22,0xd7,0x74,
+0x9, 0xac,0xbe,0x9, 0x75,0x22,0x23,0xbc,0x67,0x68,0x7, 0xb, 0xd0,0x12,0x77,0x1f,
+0x38,0xe5,0x12,0x77,0x1f,0x28,0x45,0x74,0x9, 0xac,0xbd,0x9, 0xc5,0x22,0xd7,0x12,
+0x77,0xe7,0x74,0x9, 0xac,0xbd,0x12,0xd0,0xc3,0x9d,0x32,0x12,0x29,0xb4,0x2d,0x31,
+0x7a,0x35,0x24,0xa, 0x3c,0x9, 0xb3,0x23,0x2d,0xb4,0x1, 0xe, 0x6d,0x33,0x74,0x2,
+0xac,0xbc,0x59,0x35,0x3b,0x63,0x59,0x35,0x3b,0x90,0x7e,0x35,0x24,0x7c,0xbd,0x7c,
+0x5e,0x7c,0x4c,0x12,0x77,0x27,0xb, 0xe0,0xbc,0xfe,0x38,0x97,0xda,0x3b,0x22,0x90,
+0x60,0xa1,0xe4,0x93,0xbc,0xbd,0x22,0x2, 0x77,0x2a,0xca,0x79,0x7c,0xe5,0x7c,0xfb,
+0x7e,0xe4,0xff,0xfc,0x7c,0xb4,0x12,0x9b,0x71,0x7d,0x3, 0x12,0x7e,0x5e,0x50,0x35,
+0x7e,0xb3,0x3b,0xa4,0x70,0x2, 0x1e,0x4, 0x7e,0xb3,0x3d,0x34,0xb4,0x2, 0x26,0x7e,
+0x73,0x3d,0x3c,0xa, 0x27,0x7e,0x73,0x3d,0x3b,0x12,0x57,0x74,0x7d,0x13,0x7e,0x73,
+0x3d,0x3a,0xa, 0x27,0x7e,0x73,0x3d,0x39,0x12,0x57,0x74,0x2d,0x13,0xbe,0x14,0x0,
+0xa, 0x58,0x2, 0x1e,0x4, 0x74,0x9, 0xac,0xbf,0x12,0xd0,0xc3,0x12,0x77,0xf3,0x12,
+0xd0,0x94,0x7e,0x70,0x9, 0xac,0x7f,0x49,0xf3,0x22,0xd3,0x74,0x9, 0xac,0xbe,0x49,
+0x25,0x22,0x1f,0xbd,0x2f,0x28,0xf, 0x7d,0x53,0x2e,0x54,0x22,0xd3,0x7d,0x2f,0x2d,
+0x21,0x1b,0x58,0x20,0x80,0x9, 0x2e,0x34,0x22,0xd3,0x9d,0xf1,0x1b,0x38,0xf0,0x74,
+0x9, 0xac,0xbf,0x12,0x77,0xe7,0x12,0xd0,0x94,0x7e,0x50,0x9, 0xac,0x5f,0x49,0x32,
+0x22,0xd5,0x74,0x9, 0xac,0xbe,0x49,0x5, 0x22,0x21,0xbd,0x3, 0x28,0xd, 0x7d,0x2,
+0x2e,0x4, 0x22,0xd5,0x2d,0x13,0x1b,0x8, 0x10,0x80,0x9, 0x2e,0x24,0x22,0xd5,0x9d,
+0x31,0x1b,0x28,0x30,0xda,0x79,0x22,0x49,0x25,0x22,0xd5,0x74,0x9, 0xac,0xbe,0x49,
+0x35,0x22,0x21,0x9d,0x32,0x12,0x29,0xb4,0x7d,0x13,0x22,0x9f,0x11,0x6c,0x33,0x80,
+0x23,0xa, 0x3, 0x9, 0x20,0x24,0xb0,0x7e,0xa0,0x3, 0x7c,0xb2,0x84,0x7c,0x2a,0x74,
+0x3, 0xac,0xb2,0xa, 0x2, 0xb, 0x4, 0x60,0x5, 0x3e,0x4, 0x14,0x78,0xfb,0x7d,0x50,
+0x4d,0x35,0xb, 0x30,0x7e,0x13,0x24,0x40,0xbc,0x13,0x38,0xd5,0x6c,0x33,0x80,0x1f,
+0xa, 0x3, 0x9, 0x20,0x24,0x8d,0xbe,0x20,0xb, 0x38,0x5, 0x4e,0x60,0x8, 0x80,0xd,
+0xbe,0x20,0x17,0x38,0x5, 0x4e,0x60,0x50,0x80,0x3, 0x4e,0x50,0x6, 0xb, 0x30,0x7e,
+0x23,0x24,0x3f,0xbc,0x23,0x38,0xd9,0x22,0x2, 0x2d,0x70,0xca,0xf8,0x7e,0x73,0x24,
+0x44,0xa, 0x47,0x7e,0x73,0x24,0x3d,0xa, 0x57,0x2d,0x54,0x7e,0xa3,0x24,0x3f,0xbc,
+0xab,0x28,0x2, 0x7c,0xba,0x7e,0xf3,0x24,0x3e,0x7e,0xa3,0x24,0x40,0xbc,0xaf,0x28,
+0x2, 0x7c,0xfa,0x75,0x24,0xb, 0x7e,0x8, 0x24,0x8d,0x7e,0x18,0x24,0x46,0x12,0x1a,
+0x34,0x75,0x24,0xb, 0x7e,0x8, 0x24,0xb0,0x7e,0x18,0x24,0x69,0x7c,0xbf,0x12,0x1b,
+0x31,0xda,0xf8,0x22,0x7f,0x60,0x7e,0xa3,0x24,0x39,0x7e,0xb3,0x24,0x3a,0xa4,0x7d,
+0xf5,0x3e,0xf4,0x7f,0x1, 0x7d,0x3f,0xe4,0x12,0x29,0x72,0x7f,0x6, 0x7d,0x3f,0x12,
+0x29,0x72,0x7a,0xb3,0x1f,0x5d,0x22,0x7f,0x70,0x7e,0x33,0x24,0x40,0xa, 0x43,0x7e,
+0x33,0x24,0x3f,0xa, 0x53,0x2d,0x54,0x3e,0x54,0x7c,0xab,0xe4,0x7a,0xb3,0x1f,0x5c,
+0x7f,0x1, 0xa, 0x3a,0x12,0x29,0x72,0x7f,0x7, 0xa, 0x3a,0x2, 0x29,0x72,0x7e,0xa3,
+0x3b,0x4c,0x7e,0x70,0x4, 0xac,0x7a,0xb, 0x34,0xbe,0x37,0x3f,0x72,0x40,0x39,0x7e,
+0x37,0x3f,0x72,0xb, 0x34,0x7a,0x37,0x3f,0x72,0xbe,0x34,0x0, 0x1, 0x78,0x5, 0x7e,
+0xb3,0x3, 0xf1,0x22,0xbe,0x34,0x0, 0x2, 0x78,0x3, 0x7c,0xba,0x22,0xbe,0x34,0x0,
+0x2, 0x50,0x9, 0x7d,0x23,0x1b,0x25,0x9, 0xb2,0x40,0x23,0x22,0x9e,0x34,0x0, 0x3,
+0x2e,0x37,0x37,0x5d,0x7e,0x39,0xb0,0x22,0x74,0xff,0x22,0x70,0x5, 0x7e,0xb3,0x3f,
+0x21,0x22,0xbe,0xb0,0x3, 0x38,0x15,0x75,0x1c,0x0, 0x30,0xe, 0x6, 0x7e,0x18,0x3c,
+0x5c,0x80,0x4, 0x7e,0x18,0x3c,0x9a,0x7a,0x1d,0x14,0x80,0x8, 0xbe,0xb0,0x5e,0x38,
+0x10,0x75,0x1c,0x0, 0xa, 0x1b,0x7e,0x1d,0x14,0x2d,0x31,0x1b,0x34,0x7e,0x1b,0xb0,
+0x22,0xbe,0xb0,0xd3,0x68,0x3, 0xb4,0xd4,0x10,0xb4,0xd3,0x8, 0x6d,0x33,0x7a,0x37,
+0x3f,0x72,0x80,0x2, 0x15,0x1b,0x2, 0x78,0xee,0xb4,0xa0,0x3, 0x74,0xb, 0x22,0xbe,
+0xb0,0x80,0x40,0xc, 0xbe,0xb0,0xdf,0x38,0x7, 0xa, 0x3b,0x9, 0xb3,0x3, 0x1e,0x22,
+0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x3, 0x2, 0x7a,0x42,0xb4,0xfc,0x5, 0x7e,0xb3,
+0x3, 0xc5,0x22,0xb4,0xfd,0x17,0x6c,0xaa,0x7e,0xb3,0x22,0x19,0x60,0x3, 0x4e,0xa0,
+0x1, 0x7e,0xb3,0x3e,0x40,0x60,0x3, 0x4e,0xa0,0x2, 0x7c,0xba,0x22,0xb4,0xfe,0x5,
+0x7e,0xb3,0x24,0xed,0x22,0x74,0xff,0x22,0x7c,0x7b,0x6c,0xaa,0x12,0x7a,0x3a,0x78,
+0x9, 0x7c,0xb7,0x12,0x79,0x3b,0x7c,0xab,0x80,0xa, 0xb4,0x4, 0x7, 0x7c,0xb7,0x12,
+0x2f,0x9a,0x7c,0xab,0x7c,0xba,0x22,0x30,0x90,0x1c,0xc2,0x90,0xe5,0x1a,0x70,0x9,
+0x75,0x1a,0x1, 0xe5,0x91,0xf5,0x1b,0x80,0x14,0x7e,0x71,0x91,0xe5,0x1b,0x12,0x7a,
+0x25,0x5, 0x1b,0x75,0x1a,0x2, 0x30,0x91,0xb, 0xc2,0x91,0x5, 0x1b,0xe5,0x1b,0x12,
+0x79,0xd8,0xf5,0x91,0x22,0x7c,0x6b,0x12,0x7a,0x3a,0x78,0x5, 0x7c,0xb6,0x2, 0x7a,
+0x74,0xb4,0x4, 0x5, 0x7c,0xb6,0x2, 0x31,0xe1,0x22,0x7e,0xb3,0x3f,0x21,0xc4,0x54,
+0x7, 0x22,0xb4,0xeb,0x5, 0xe4,0x7a,0xb3,0x3f,0x76,0x7e,0x73,0x3f,0x76,0xa, 0x27,
+0x2e,0x24,0x0, 0x25,0x12,0x7a,0xb8,0x7c,0xab,0x7c,0xb7,0x4, 0x7a,0xb3,0x3f,0x76,
+0xb4,0x3, 0xb, 0xe4,0x7a,0xb3,0x3f,0x76,0x6d,0x33,0x7a,0x37,0x3f,0x74,0x75,0x1b,
+0xeb,0x7c,0xba,0x22,0x7c,0xa7,0x7c,0x3b,0xa5,0xbb,0x0, 0x7, 0x7c,0xba,0x12,0x7b,
+0xb1,0x80,0x25,0xbe,0x30,0xeb,0x68,0x4, 0xa5,0xbb,0xec,0x9, 0x7c,0xb3,0x7c,0x7a,
+0x12,0x7c,0xa, 0x80,0x13,0xbe,0x30,0x80,0x40,0xe, 0xbe,0x30,0xdf,0x38,0x9, 0x7c,
+0xb3,0x24,0x80,0x7c,0x7a,0x12,0x7b,0xdc,0xa5,0xbb,0xfc,0x5, 0x7c,0xba,0x2, 0x3d,
+0xd5,0x74,0x1, 0x7a,0xb3,0x40,0x41,0x22,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,
+0x22,0xca,0xd8,0xca,0x79,0x7c,0xeb,0x7e,0x8, 0x31,0xbb,0x7e,0x34,0x0, 0x48,0x74,
+0x3f,0x12,0x7b,0x74,0xf5,0x24,0x7e,0x73,0x24,0x40,0x6c,0xdd,0x80,0x3a,0xa, 0x2d,
+0x9, 0xa2,0x24,0xb0,0xbe,0xa0,0x24,0x50,0x2d,0xa, 0x2a,0x2e,0x24,0x29,0x29,0x12,
+0x7a,0xb8,0x7c,0xab,0xa, 0xfa,0x7e,0x4, 0x0, 0x3, 0x8d,0xf0,0x7e,0xf4,0x0, 0xc,
+0xad,0xfe,0xa, 0x1a,0x8d,0x10,0x7d,0x21,0x2d,0x2f,0x7c,0xf5,0x7e,0x63,0x24,0xd7,
+0xa, 0x2f,0x19,0x62,0x31,0xbb,0xb, 0xd0,0xbc,0x7d,0x38,0xc2,0x6c,0xdd,0x80,0x2e,
+0xa, 0x3d,0x9, 0xa3,0x24,0x8d,0xbe,0xa0,0x23,0x50,0x21,0xa, 0xfa,0x7e,0x24,0x0,
+0xc, 0x8d,0xf2,0x7e,0x14,0x0, 0xc, 0xad,0x1f,0xa, 0x3a,0x12,0x7b,0x8c,0x2d,0x31,
+0x7c,0xf7,0x7e,0xb3,0x24,0xd7,0xa, 0x4f,0x19,0xb4,0x31,0xbb,0xb, 0xd0,0xe5,0x24,
+0xbc,0xbd,0x38,0xcc,0x6c,0xdd,0x7e,0x30,0xc, 0xac,0x3d,0x2e,0x14,0x31,0xbb,0x6d,
+0x0, 0x7c,0xbe,0x7c,0x7d,0x12,0x1b,0xc9,0xb, 0xd0,0xbe,0xd0,0x6, 0x40,0xe7,0xda,
+0x79,0xda,0xd8,0x22,0x12,0x29,0x72,0x7e,0xb3,0x24,0x3f,0x22,0xa, 0x5c,0x7e,0x24,
+0x0, 0xc, 0x8d,0x52,0x7e,0x14,0x0, 0xc, 0xad,0x15,0xa, 0x3c,0x8d,0x32,0x7d,0x32,
+0x2e,0x34,0x0, 0x24,0x22,0xca,0x7b,0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0x83,0xc0,
+0x82,0x12,0x79,0xf7,0xd0,0x82,0xd0,0x83,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x7b,
+0x32,0x7a,0xb3,0x3f,0x21,0xc4,0x54,0x7, 0xbe,0xb0,0x4, 0x68,0x3, 0xb4,0x2, 0x4,
+0x74,0x3, 0x80,0x7, 0x60,0x3, 0xb4,0x1, 0x7, 0x74,0x1, 0x7a,0xb3,0x3, 0xc5,0x22,
+0x74,0x1, 0x7a,0xb3,0x3, 0xc5,0xe4,0x7a,0xb3,0x3f,0x21,0x22,0x7c,0x6b,0x2e,0x60,
+0xdd,0x68,0x26,0x2e,0x60,0xfd,0x68,0x21,0x1b,0x61,0x68,0x1d,0x1b,0x62,0x68,0x19,
+0x1b,0x61,0x68,0x15,0x1b,0x60,0x68,0x11,0x2e,0x60,0xa, 0x78,0x4, 0x7a,0x73,0x3,
+0x9d,0xa, 0x2b,0x19,0x72,0x3, 0x9e,0xd2,0xd, 0x22,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,
+0xec,0x33,0x7e,0x27,0x3f,0x74,0x4d,0x22,0x78,0xe, 0xa5,0xbf,0xaa,0xa, 0x7e,0x24,
+0x0, 0x1, 0x7a,0x27,0x3f,0x74,0x15,0x1b,0x7e,0x27,0x3f,0x74,0xbe,0x24,0x0, 0x1,
+0x78,0x10,0xa5,0xbf,0x9, 0x6, 0x7e,0x34,0x0, 0x2, 0x80,0x2, 0x6d,0x33,0x7a,0x37,
+0x3f,0x74,0x75,0x1b,0xea,0x22,0xa9,0xc0,0x93,0x75,0x1a,0x0, 0x32,0xe4,0x7a,0xb3,
+0x3f,0x21,0x7e,0x8, 0x3c,0x5c,0x7e,0x34,0x0, 0x3e,0x74,0xff,0x12,0x29,0x72,0x7e,
+0x8, 0x3c,0x9a,0x7e,0x34,0x0, 0x3e,0x12,0x29,0x72,0x7e,0x18,0x3c,0x5c,0x7a,0x1d,
+0x14,0x12,0x7c,0x84,0x2, 0x7c,0x77,0x75,0x1a,0x0, 0x75,0x1b,0x0, 0x7e,0xb3,0x3f,
+0x21,0xf5,0x91,0x22,0x2, 0x7c,0x87,0x90,0x60,0x0, 0xe4,0x93,0x54,0xfe,0x75,0x91,
+0x0, 0xc2,0x90,0xc2,0x91,0xc2,0xc9,0x54,0xfe,0xf5,0x92,0xd2,0xe8,0xc2,0xc0,0xd2,
+0xad,0x22,0x7f,0x20,0xb, 0x2a,0x10,0xb, 0x1a,0x0, 0x1b,0x2a,0x0, 0x1b,0x1a,0x10,
+0x22,0xca,0x3b,0x6c,0xff,0x7e,0xe3,0x24,0x3b,0x7e,0xb3,0x24,0x3c,0xf5,0x29,0x6c,
+0xdd,0x7e,0xb3,0x1f,0x5d,0xbe,0xb0,0x1, 0x68,0xf, 0x60,0x2, 0xa1,0xc7,0x7e,0xb3,
+0x21,0xf5,0xb4,0x1, 0x2, 0x80,0x2, 0xa1,0xc7,0x6c,0xcc,0xa1,0xb9,0x7e,0x70,0x2,
+0xac,0x7c,0x9, 0xa3,0x20,0x6b,0x7a,0xa1,0x27,0x9, 0xb3,0x20,0x6c,0xf5,0x28,0x75,
+0x25,0x2, 0x75,0x26,0x2, 0x4c,0xaa,0x68,0x7, 0xa, 0x2e,0x12,0x7d,0xd5,0x48,0x3,
+0x75,0x25,0x1, 0xe5,0x28,0x60,0x7, 0xe5,0x29,0x12,0x7e,0x8c,0x48,0x3, 0x75,0x26,
+0x1, 0x75,0x24,0x0, 0x80,0x34,0xe5,0x24,0xbc,0xbc,0x68,0x2c,0x7e,0x71,0x24,0x12,
+0x7e,0x81,0x9, 0x33,0x20,0x6c,0xa, 0x2a,0xe5,0x27,0x12,0x7d,0xca,0xbe,0x34,0x0,
+0x3, 0x18,0x15,0xa, 0x23,0xe5,0x28,0x12,0x7d,0xca,0xbe,0x34,0x0, 0x3, 0x18,0x8,
+0x75,0x25,0x1, 0x75,0x26,0x1, 0x80,0xb, 0x5, 0x24,0x7e,0x23,0x21,0xf5,0xbe,0x21,
+0x24,0x38,0xc3,0x12,0x7e,0x5e,0x50,0x31,0x12,0x7e,0x79,0x78,0x5, 0x12,0x7e,0x71,
+0x68,0xa, 0x12,0x7e,0x69,0x78,0x22,0x12,0x7e,0x61,0x78,0x1d,0x75,0x25,0x4, 0x75,
+0x26,0x4, 0xe5,0x27,0x60,0x7, 0xa, 0x2e,0x12,0x7d,0xd5,0x48,0xc, 0x7e,0x73,0x21,
+0xf5,0xbe,0x70,0x3, 0x50,0x3, 0x75,0x25,0x1, 0xe5,0x25,0x7e,0x71,0x26,0x7c,0x6c,
+0x7c,0x5f,0x7c,0x4d,0x12,0x6c,0x55,0x90,0x61,0x46,0xe4,0x93,0xb4,0x1, 0x16,0x7e,
+0x70,0x9, 0xac,0x7c,0x7d,0x13,0x2e,0x14,0x20,0xe7,0x6d,0x0, 0x2e,0x34,0x20,0xe9,
+0x6d,0x22,0x12,0x7c,0xa2,0xb, 0xf0,0xb, 0xc0,0x7e,0x73,0x21,0xf5,0xbc,0x7c,0x28,
+0x2, 0x81,0xdd,0x7a,0xf3,0x21,0xf5,0xda,0x3b,0x22,0xa, 0x3b,0x9d,0x32,0x2, 0x29,
+0xb4,0xe5,0x47,0xa, 0x2b,0x1b,0x24,0xe5,0x27,0xa, 0x3b,0xbd,0x32,0x22,0x7e,0x30,
+0x64,0x7e,0x20,0x64,0x6c,0x11,0x80,0x4a,0xa, 0x31,0xb, 0x34,0x7c,0x7, 0x80,0x38,
+0x7e,0x70,0x2, 0xac,0x70,0x9, 0xb3,0x20,0x6b,0x12,0x7e,0x53,0x9, 0xb3,0x20,0x6b,
+0x12,0x7d,0xca,0x7c,0x97,0x7e,0x70,0x2, 0xac,0x70,0x9, 0xb3,0x20,0x6c,0x12,0x7e,
+0x53,0x9, 0xb3,0x20,0x6c,0x12,0x7d,0xca,0x7c,0x87,0xbc,0x39,0x28,0x2, 0x7c,0x39,
+0xbc,0x28,0x28,0x2, 0x7c,0x28,0xb, 0x0, 0x7e,0xb3,0x21,0xf5,0xbc,0xb0,0x38,0xc0,
+0xb, 0x10,0x7e,0xb3,0x21,0xf5,0xbc,0xb1,0x38,0xae,0xa5,0xbb,0x64,0x2, 0x6c,0x33,
+0xa5,0xba,0x64,0x2, 0x6c,0x22,0xbc,0x23,0x28,0x4, 0x7c,0xa2,0x80,0x2, 0x7c,0xa3,
+0x7c,0xba,0x22,0xa, 0x2b,0x7e,0x70,0x2, 0xac,0x71,0x22,0x2, 0x7c,0xb1,0xa2,0x11,
+0x22,0x7e,0x73,0x3d,0x3c,0xbe,0x71,0x28,0x22,0x7e,0x73,0x3d,0x3a,0xbe,0x71,0x27,
+0x22,0x7e,0x73,0x3d,0x3b,0xbe,0x71,0x28,0x22,0x7e,0x73,0x3d,0x39,0xbe,0x71,0x27,
+0x22,0x74,0x2, 0xac,0x7b,0x9, 0xa3,0x20,0x6b,0x22,0xe5,0x48,0xa, 0x2b,0x1b,0x24,
+0xe5,0x28,0xa, 0x3b,0xbd,0x32,0x22,0x7c,0x9b,0x7f,0x71,0x7e,0x7b,0x80,0x4c,0x88,
+0x78,0x7, 0x7e,0xb, 0x90,0x7a,0x7b,0x90,0x22,0xa, 0x28,0x7e,0xb, 0x80,0xa, 0x38,
+0x9d,0x32,0x12,0x29,0xb4,0xe5,0x29,0xa, 0x2b,0xbd,0x32,0x8, 0x15,0x7e,0x7b,0xa0,
+0x7e,0xb, 0xb0,0xbc,0xba,0x7c,0xba,0x28,0x4, 0x2c,0xb9,0x80,0x2, 0x9c,0xb9,0x7a,
+0x7b,0xb0,0x7e,0x7b,0x70,0x7a,0xb, 0x70,0x22,0xca,0x3b,0x75,0x24,0x0, 0x6c,0xff,
+0x75,0x25,0x0, 0x75,0x26,0x0, 0x75,0x28,0x3, 0x6c,0xee,0x7e,0x48,0x23,0x2d,0x7e,
+0xb3,0x23,0x90,0x70,0xf, 0x7e,0xb3,0x23,0x8c,0x70,0x9, 0x7e,0xb3,0x23,0x8d,0x70,
+0x3, 0x2, 0x80,0xec,0x30,0xe, 0x6, 0x7e,0x68,0x3c,0x9a,0x80,0x4, 0x7e,0x68,0x3c,
+0x5c,0x7f,0x6, 0x7e,0x34,0x0, 0x3e,0x74,0xff,0x12,0x29,0x72,0x7e,0x73,0x23,0x89,
+0x7a,0x6b,0x70,0x6c,0xdd,0x2, 0x80,0x9f,0x74,0x9, 0xac,0xbd,0x9, 0xc5,0x22,0x7d,
+0x7c,0xbc,0x54,0xf, 0xa, 0x3b,0x12,0xd1,0x57,0xf5,0x28,0x7c,0xbc,0x54,0xf0,0xbe,
+0xb0,0x0, 0x28,0x3, 0x2, 0x80,0x9d,0xe5,0x28,0xbe,0xb0,0x3, 0x78,0x3, 0x2, 0x80,
+0x9d,0x7e,0x8, 0x0, 0x28,0x7c,0xbc,0x12,0x9b,0x1d,0x50,0x3, 0x2, 0x80,0x9d,0x74,
+0x9, 0xac,0xbd,0x9, 0xb5,0x22,0x7e,0xf5,0x25,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x22,
+0x7f,0xf5,0x26,0xbe,0xb0,0xf, 0x28,0x3, 0x75,0x26,0xf, 0xe5,0x26,0xc4,0x54,0xf0,
+0xf5,0x26,0x7e,0x73,0x24,0x19,0xbc,0x7c,0x28,0x57,0x7e,0xb3,0x23,0x8e,0x70,0x2a,
+0x75,0x29,0xf, 0x7e,0x8, 0x0, 0x25,0xa, 0x3c,0x2e,0x34,0x3c,0x48,0x6d,0x22,0x74,
+0x1, 0x12,0x7e,0x97,0x75,0x29,0x20,0x7e,0x8, 0x0, 0x26,0xa, 0x3c,0x2e,0x34,0x3c,
+0x52,0x6d,0x22,0x74,0x10,0x12,0x7e,0x97,0x80,0xe, 0xa, 0x3c,0x9, 0xb3,0x3c,0x48,
+0xf5,0x25,0x9, 0xb3,0x3c,0x52,0xf5,0x26,0xa, 0x3c,0x12,0xd1,0x57,0xb4,0x1, 0x11,
+0xe4,0xa, 0x3c,0x19,0xb3,0x3c,0x48,0x19,0xb3,0x3c,0x52,0x75,0x25,0x0, 0x75,0x26,
+0x0, 0x7e,0xb3,0x24,0x30,0xb4,0xff,0x13,0x75,0x25,0x0, 0x74,0x9, 0xac,0xbd,0x9,
+0xb5,0x22,0x7d,0xbe,0xb0,0xff,0x68,0x3, 0x75,0x25,0x1, 0x7e,0x90,0x9, 0xac,0x9d,
+0x49,0xb4,0x22,0x79,0x49,0xa4,0x22,0x7b,0xe5,0x28,0xb4,0x1, 0x2c,0x75,0x27,0x0,
+0x80,0x1d,0x7e,0x71,0x27,0x74,0x9, 0xac,0x7b,0x9, 0xb3,0x3c,0xdc,0x54,0xf, 0xbc,
+0xbc,0x78,0xa, 0x49,0xb3,0x3c,0xd8,0x49,0xa3,0x3c,0xda,0x80,0xc, 0x5, 0x27,0x90,
+0x60,0xa1,0xe4,0x93,0xbe,0xb1,0x27,0x38,0xd9,0x5e,0xb4,0xf, 0xff,0x5e,0xa4,0xf,
+0xff,0x9, 0x74,0x22,0x7d,0xa, 0x57,0xc4,0x54,0xf0,0x7c,0xab,0xe4,0x2d,0xa5,0xbe,
+0x70,0xff,0x68,0x1a,0xe5,0x28,0xbe,0xb0,0x1, 0x68,0x2, 0x5, 0x24,0xb, 0xf0,0xe5,
+0x28,0xa, 0x5b,0x3, 0x3, 0x54,0xc0,0x7c,0xab,0xe4,0x2d,0xb5,0x80,0x4, 0x2e,0xb4,
+0xc0,0x0, 0x7e,0x70,0x6, 0xac,0x7e,0x7f,0x6, 0x2d,0x13,0x79,0xb0,0x0, 0x2, 0x7f,
+0x6, 0x2d,0x13,0x79,0xa0,0x0, 0x4, 0xe5,0x25,0x7f,0x6, 0x2d,0x13,0x39,0xb0,0x0,
+0x6, 0xe5,0x26,0x2d,0x3d,0x7d,0x2c,0x39,0xb1,0x0, 0x7, 0xb, 0xe0,0xb, 0xd0,0x7e,
+0x73,0x24,0x19,0xbc,0x7d,0x28,0x3, 0x2, 0x7f,0x28,0xe5,0x24,0x39,0xb6,0x0, 0x1,
+0x7e,0xb3,0x3, 0xee,0xb4,0x1, 0x9, 0x7e,0xb3,0x23,0x8d,0xb4,0x1, 0x14,0x80,0xd,
+0xbe,0xf0,0x0, 0x38,0x6, 0x7e,0xb3,0x23,0x8d,0x60,0x7, 0xb2,0xe, 0x74,0x1, 0x12,
+0x81,0x15,0x7e,0xb3,0x23,0x8c,0x60,0x5, 0x7f,0x4, 0x12,0x72,0x27,0xe4,0x7a,0xb3,
+0x23,0x90,0x7a,0xb3,0x23,0x8c,0x7a,0xb3,0x23,0x8d,0x80,0x4, 0xe4,0x12,0x81,0x15,
+0x12,0x81,0x1d,0xca,0x59,0x7e,0x18,0x22,0x79,0x7e,0x8, 0x3c,0xd8,0x12,0x29,0x4d,
+0x1b,0xfd,0x4c,0xff,0x78,0xc, 0x12,0x75,0x84,0x7e,0x8, 0x3c,0xd8,0x74,0xff,0x12,
+0x29,0x72,0xda,0x3b,0x22,0x70,0x3, 0xd2,0x86,0x22,0xc2,0x86,0x22,0x90,0x60,0xa1,
+0xe4,0x93,0x7c,0xab,0x74,0x9, 0xa4,0x22,0xca,0x69,0xca,0xf8,0x7e,0xa3,0x23,0x87,
+0x4c,0xaa,0x78,0x11,0x7e,0xb3,0x23,0x88,0xbe,0xb0,0x0, 0x28,0x13,0x74,0x1, 0x7a,
+0xb3,0x23,0x8c,0x80,0xb, 0xbe,0xa0,0x0, 0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x23,0x90,
+0x12,0x81,0x1d,0xca,0x59,0x7e,0x18,0x22,0x1f,0x7e,0x8, 0x22,0x79,0x12,0x29,0x4d,
+0x1b,0xfd,0x90,0x61,0x45,0xe4,0x93,0xbe,0xb0,0x0, 0x28,0x31,0x6c,0xff,0x80,0x28,
+0x74,0x9, 0xac,0xbf,0x49,0xa5,0x22,0x1f,0x49,0x95,0x22,0x21,0x7d,0x3a,0x12,0x82,
+0xb7,0x7d,0x83,0x7d,0x39,0x12,0x81,0xa2,0x7d,0x63,0x74,0x9, 0xac,0xbf,0x59,0x85,
+0x22,0x79,0x59,0x65,0x22,0x7b,0xb, 0xf0,0x12,0x87,0xea,0x38,0xd3,0xda,0xf8,0xda,
+0x69,0x22,0x7d,0xd3,0x9f,0x11,0x7e,0x14,0x61,0x53,0x12,0x84,0x7, 0x90,0x61,0x45,
+0xe4,0x93,0x70,0x3, 0x7d,0x3d,0x22,0x90,0x61,0x46,0xe4,0x93,0xb4,0x1, 0x6, 0x7e,
+0x33,0x24,0x3b,0x80,0x4, 0x7e,0x33,0x24,0x3c,0xa, 0x3, 0x7e,0x14,0x1, 0x0, 0xad,
+0x10,0x7d,0x41,0x1b,0x44,0xbe,0xd4,0x0, 0xff,0x38,0x25,0x7d,0x1d,0x12,0x83,0xfa,
+0x7e,0x14,0x61,0x57,0x12,0x82,0xad,0x74,0xa, 0x1e,0x34,0xe, 0x24,0x50,0x3, 0x4e,
+0x60,0x80,0x14,0x78,0xf4,0x12,0x83,0xd0,0x48,0x2, 0x7f,0x10,0x9f,0x1, 0x7f,0x10,
+0x7d,0xe4,0x9e,0xe4,0x0, 0xff,0xbd,0xed,0x38,0x34,0x7d,0x14,0x9e,0x14,0x1, 0x0,
+0x6d,0x0, 0x7d,0x3d,0x6d,0x22,0x9f,0x10,0x7e,0x14,0x61,0x59,0x12,0x82,0xad,0x74,
+0xa, 0x1e,0x34,0xe, 0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x90,0x61,0x56,
+0x12,0x83,0xd3,0x48,0x4, 0x7f,0x10,0x1b,0x1c,0x12,0x83,0xe8,0x2f,0x10,0xbe,0xd4,
+0x0, 0xff,0x28,0x68,0xbd,0xed,0x28,0x64,0x7d,0x54,0xb, 0x54,0x1e,0x54,0x7d,0xe5,
+0x1b,0xe4,0xbd,0xed,0x40,0xc, 0x7d,0x3e,0x9d,0x3d,0x6d,0x22,0x7e,0x14,0x61,0x5b,
+0x80,0xa, 0x7d,0x3d,0x9d,0x35,0x6d,0x22,0x7e,0x14,0x61,0x5d,0x12,0x82,0xad,0x74,
+0xa, 0x1e,0x34,0xe, 0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0xbd,0xed,0x7d,
+0x1f,0x40,0xc, 0x1e,0x14,0x1b,0x14,0x6d,0x0, 0x9f,0x1, 0x7f,0x10,0x80,0x6, 0x1e,
+0x14,0x6d,0x0, 0x2f,0x10,0x12,0x83,0xd0,0x58,0x4, 0x7f,0x10,0x80,0xe, 0x90,0x61,
+0x56,0xe4,0x93,0x12,0x83,0xe8,0xbf,0x10,0x8, 0x2, 0x7f,0x10,0x22,0x7e,0x4, 0x0,
+0xff,0xb, 0xa, 0x10,0x2, 0x27,0xa, 0x7d,0xb3,0x7e,0x34,0x61,0x47,0x7e,0x24,0x0,
+0xff,0xb, 0x1a,0xd0,0x90,0x61,0x45,0xe4,0x93,0x70,0x3, 0x7d,0x3b,0x22,0x90,0x61,
+0x46,0xe4,0x93,0xb4,0x1, 0x6, 0x7e,0x73,0x24,0x3c,0x80,0x4, 0x7e,0x73,0x24,0x3b,
+0xa, 0x27,0x7e,0x34,0x1, 0x0, 0xad,0x32,0x7d,0x43,0x1b,0x44,0xbe,0xb4,0x0, 0xff,
+0x38,0x2a,0x7d,0x1b,0x12,0x83,0xfa,0x7e,0x14,0x61,0x4b,0x12,0x82,0xad,0x7f,0x71,
+0x74,0xa, 0x1e,0xf4,0x1e,0xe4,0x50,0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3,0x12,
+0x83,0xdc,0x40,0x2, 0x7f,0x71,0x9f,0x17,0x7f,0x71,0x61,0xcd,0x7d,0x14,0x9e,0x14,
+0x0, 0xff,0xbd,0x1b,0x38,0x33,0x6d,0x0, 0x7d,0x3b,0x6d,0x22,0x9f,0x10,0x7e,0x14,
+0x61,0x4d,0x12,0x82,0xad,0x7f,0x71,0x74,0xa, 0x1e,0xf4,0x1e,0xe4,0x50,0x4, 0x4e,
+0xf4,0x80,0x0, 0x14,0x78,0xf3,0x90,0x61,0x4a,0x12,0x83,0xdf,0x40,0x4, 0x7f,0x71,
+0x1b,0x7c,0x12,0x83,0xf1,0x2f,0x71,0x80,0x74,0x7d,0x54,0xb, 0x54,0x1e,0x54,0x7d,
+0xc5,0x1b,0xc4,0xbd,0xcb,0x40,0x10,0x7d,0xfc,0x6d,0xee,0x7d,0x3b,0x6d,0x22,0x9f,
+0x71,0x7e,0x34,0x61,0x4f,0x80,0xe, 0x7d,0x35,0x6d,0x22,0x7d,0xfb,0x6d,0xee,0x9f,
+0x71,0x7e,0x34,0x61,0x51,0x12,0xd1,0x47,0x7f,0x17,0x12,0x27,0xa, 0x7f,0x71,0x74,
+0xa, 0x1e,0xf4,0x1e,0xe4,0x50,0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3,0xbd,0xcb,
+0x7d,0x3d,0x40,0xc, 0x1e,0x34,0x1b,0x34,0x6d,0x22,0x9f,0x17,0x7f,0x71,0x80,0x6,
+0x1e,0x34,0x6d,0x22,0x2f,0x71,0x12,0x83,0xdc,0x50,0x4, 0x7f,0x71,0x80,0xe, 0x90,
+0x61,0x4a,0xe4,0x93,0x12,0x83,0xf1,0xbf,0x71,0x28,0x2, 0x7f,0x71,0x7d,0x3f,0x22,
+0x90,0x61,0x55,0xe4,0x93,0xa, 0x1b,0x6d,0x0, 0xbf,0x10,0x22,0x90,0x61,0x49,0xe4,
+0x93,0xa, 0x3b,0x6d,0x22,0xbf,0x71,0x22,0xa, 0xb, 0x7d,0x1f,0x9d,0x10,0x6d,0x0,
+0x22,0xa, 0x2b,0x7d,0x3d,0x9d,0x32,0x6d,0x22,0x22,0x6d,0x0, 0x7e,0x18,0x0, 0xff,
+0x9f,0x10,0x22,0x7e,0x14,0x62,0xa8,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0xf0,0x22,0xca,
+0xf8,0x6c,0xff,0x7e,0xb7,0x3b,0x40,0x7e,0xc7,0x3b,0x42,0x7e,0x97,0x3b,0x28,0x7e,
+0xd7,0x3b,0x2a,0x7e,0xa7,0x3b,0x3c,0x7e,0xe7,0x3b,0x3e,0xe4,0x7e,0x73,0x3b,0x4c,
+0x1b,0x70,0x7d,0x2b,0x7d,0x1c,0x12,0x85,0x57,0x70,0x2, 0xa1,0x4a,0x7e,0x73,0x3b,
+0x4c,0xbe,0x70,0xa, 0x28,0x13,0xe4,0x7e,0x70,0x9, 0x7e,0x27,0x3b,0x44,0x7e,0x17,
+0x3b,0x46,0x12,0x85,0x57,0x70,0x2, 0xa1,0x4a,0x7e,0x73,0x3b,0x4c,0xbe,0x70,0x14,
+0x28,0x13,0xe4,0x7e,0x70,0x13,0x7e,0x27,0x3b,0x48,0x7e,0x17,0x3b,0x4a,0x12,0x85,
+0x57,0x70,0x2, 0xa1,0x4a,0x7e,0x34,0x62,0x88,0x12,0x85,0x4f,0xbd,0xfc,0x28,0x50,
+0x7e,0x34,0x62,0x86,0x12,0x85,0x4f,0xbd,0xfb,0x50,0x45,0x7e,0xb3,0x3b,0x25,0x70,
+0x3f,0x7e,0x34,0x62,0x8c,0x12,0x2d,0x68,0x12,0x84,0x3, 0x7d,0x8f,0x9d,0x83,0xbe,
+0x87,0x3b,0x26,0x50,0x2b,0x7e,0x34,0x62,0x8a,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x80,
+0x9d,0xf8,0xbe,0xf7,0x3b,0x26,0x28,0x18,0x7d,0xfc,0x3e,0xf4,0xbd,0xfb,0x40,0x2,
+0xa1,0x4a,0xbd,0xa9,0x50,0x5, 0x7e,0xf0,0x20,0x80,0x7f,0x7e,0xf0,0x21,0x80,0x7a,
+0x7e,0x34,0x62,0x90,0x12,0x85,0x4f,0xbd,0xfb,0x28,0x6f,0x7e,0x34,0x62,0x8e,0x12,
+0x85,0x4f,0xbd,0xfc,0x50,0x64,0x7e,0xb3,0x3b,0x25,0x70,0x5e,0x7e,0x34,0x62,0x94,
+0x12,0x2d,0x68,0x12,0x84,0x3, 0x7d,0xaf,0x9d,0xa3,0xbe,0xa7,0x3b,0x26,0x50,0x4a,
+0x7e,0x34,0x62,0x92,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xa0,0x9d,0xfa,0xbe,0xf7,0x3b,
+0x26,0x28,0x37,0x7d,0xfb,0x3e,0xf4,0xbd,0xfc,0x50,0x2f,0xbd,0xed,0x50,0x5, 0x7e,
+0xf0,0x22,0x80,0x26,0x12,0x87,0xf2,0x49,0x35,0x37,0x5f,0x49,0x15,0x37,0x61,0x49,
+0x25,0x37,0x4f,0x49,0x5, 0x37,0x51,0x9d,0x10,0xbe,0x14,0x0, 0x20,0x18,0x8, 0x9d,
+0x32,0xbe,0x34,0x0, 0x10,0x58,0x3, 0x7e,0xf0,0x23,0x7c,0xbf,0xda,0xf8,0x22,0x7e,
+0x24,0x0, 0xff,0xb, 0x1a,0xf0,0x22,0x7d,0x41,0x7d,0x2, 0x7c,0x37,0x7c,0x2b,0x74,
+0x4, 0xac,0xb2,0x49,0x35,0x37,0x63,0x49,0xf5,0x37,0x65,0x74,0x4, 0xac,0xb3,0x49,
+0x25,0x37,0x63,0x49,0x55,0x37,0x65,0x12,0x77,0xf3,0x7d,0x3f,0x9d,0x35,0x12,0x29,
+0xb4,0x9d,0x34,0x12,0x29,0xb4,0x7e,0x54,0x62,0x80,0x7e,0x44,0x0, 0xff,0xb, 0x2a,
+0x20,0xbd,0x32,0x50,0x11,0x12,0x87,0xe3,0x7e,0x14,0x62,0x80,0x12,0x6f,0xe6,0xbd,
+0x32,0x50,0x3, 0x74,0x1, 0x22,0xe4,0x22,0x12,0x87,0x2f,0x7a,0x37,0x3b,0x40,0x12,
+0x86,0xba,0x7a,0x37,0x3b,0x42,0x12,0x84,0xf, 0x60,0x1, 0x22,0x7e,0x73,0x3b,0x4c,
+0xa, 0x37,0x7a,0x35,0x24,0x7e,0x8, 0x37,0x63,0x7e,0x18,0x3b,0x24,0x2, 0x85,0xd0,
+0xca,0xf8,0x7e,0x45,0x24,0x7c,0xb9,0x7a,0xb3,0x3f,0x78,0x74,0xff,0x7a,0xb3,0x3f,
+0x77,0x6d,0x55,0x80,0x19,0x7d,0xf5,0x3e,0xf4,0x12,0xab,0xb2,0x7d,0xe5,0x3e,0xe4,
+0x59,0xfe,0x31,0xbb,0x69,0xf6,0x0, 0x2, 0x59,0xfe,0x33,0x9b,0xb, 0x54,0xbd,0x45,
+0x38,0xe3,0x7e,0x33,0x3f,0x78,0xbe,0x30,0x4, 0x38,0x2, 0xc1,0x92,0x69,0xf1,0x0,
+0x1c,0x69,0x11,0x0, 0x1e,0xbd,0x1f,0x18,0x19,0x4d,0x11,0x78,0x4, 0x7e,0x14,0x0,
+0x1, 0x7d,0x3f,0x7d,0x21,0x12,0x26,0xc7,0x7c,0xf7,0x74,0x40,0x7a,0xb3,0x3f,0x7b,
+0x80,0x43,0x4d,0xff,0x78,0x4, 0x7e,0xf4,0x0, 0x1, 0x7d,0x31,0x7d,0x2f,0x12,0x26,
+0xc7,0x7c,0xf7,0x74,0x80,0x7a,0xb3,0x3f,0x7b,0x7d,0xf, 0x2d,0xf, 0xbd,0x1, 0x8,
+0x24,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x3f,0x7b,0xa, 0x37,0x6d,0x22,0x12,0x26,0xf9,
+0x7d,0x5f,0x1a,0x4a,0x1a,0x48,0x7d,0x1f,0x1a,0x2, 0x1a,0x0, 0x2f,0x2, 0x12,0x27,
+0x15,0x7a,0x73,0x3f,0x7b,0xbe,0xf0,0x5, 0x58,0x14,0x12,0x86,0xb1,0x12,0xce,0x92,
+0x12,0x86,0xb1,0x12,0xce,0xe1,0x12,0x86,0xb1,0x12,0xcd,0xd6,0x80,0xa, 0x74,0x7d,
+0x80,0x2, 0x74,0x7f,0x7a,0xb3,0x3f,0x77,0xe4,0x7a,0xb3,0x3f,0x78,0x7e,0x73,0x40,
+0x29,0xbe,0x73,0x3f,0x77,0x48,0x6, 0x7e,0xb3,0x3f,0x79,0x80,0x1, 0xe4,0xda,0xf8,
+0x22,0x7e,0x8, 0x31,0xbb,0x7e,0x18,0x33,0x9b,0x22,0x7e,0x37,0x3b,0x3a,0x9e,0x37,
+0x3b,0x32,0x22,0x7e,0x17,0x3b,0x34,0xbd,0x13,0x28,0xa, 0x7a,0x37,0x3b,0x34,0x7a,
+0x27,0x3b,0x36,0x80,0x10,0x7e,0x17,0x3b,0x2c,0xbd,0x13,0x50,0x8, 0x7a,0x37,0x3b,
+0x2c,0x7a,0x27,0x3b,0x2e,0x7e,0x17,0x3b,0x32,0xbd,0x12,0x28,0xa, 0x7a,0x27,0x3b,
+0x32,0x7a,0x37,0x3b,0x30,0x80,0x10,0x7e,0x17,0x3b,0x3a,0xbd,0x12,0x50,0x8, 0x7a,
+0x27,0x3b,0x3a,0x7a,0x37,0x3b,0x38,0x7e,0xb3,0x3b,0x4c,0xb4,0xa, 0xf, 0x12,0x87,
+0x2f,0x7a,0x37,0x3b,0x44,0x12,0x86,0xba,0x7a,0x37,0x3b,0x46,0x22,0xb4,0x14,0xe,
+0x12,0x87,0x2f,0x7a,0x37,0x3b,0x48,0x12,0x86,0xba,0x7a,0x37,0x3b,0x4a,0x22,0x7e,
+0x37,0x3b,0x2c,0x9e,0x37,0x3b,0x34,0x22,0x7d,0x3c,0x7d,0x2d,0x7d,0x42,0x7d,0x13,
+0x7d,0x24,0x12,0xc9,0x51,0x7d,0x31,0x12,0x86,0xc3,0x2, 0x87,0x4d,0x7e,0x3, 0x3b,
+0x4c,0xbe,0x0, 0xf0,0x50,0x2, 0xe1,0xe2,0x80,0x7d,0x6c,0x99,0x7e,0xb3,0x3b,0x23,
+0xbe,0xb0,0x20,0x50,0x5, 0x4, 0x7a,0xb3,0x3b,0x23,0x7e,0x1f,0x37,0x63,0x7a,0x1f,
+0x31,0xbb,0x7e,0x80,0x1, 0x80,0x45,0x74,0x4, 0xac,0xb8,0x49,0x35,0x37,0x63,0x49,
+0x25,0x37,0x65,0x7e,0x17,0x31,0xbb,0x7e,0x7, 0x31,0xbd,0x12,0xc9,0x72,0x7c,0x1b,
+0x7e,0x3, 0x3b,0x23,0xbc,0x1, 0x38,0x22,0xb, 0x90,0x7e,0x70,0x4, 0xac,0x78,0x2e,
+0x34,0x37,0x63,0x7e,0x14,0x31,0xbb,0x74,0x4, 0x12,0x99,0xb2,0x7e,0x30,0x4, 0xac,
+0x39,0x2e,0x14,0x37,0x63,0x74,0x4, 0x12,0x27,0x9a,0xb, 0x80,0x7e,0x3, 0x3b,0x4c,
+0xbc,0x8, 0x38,0xb3,0xa, 0x59,0xb, 0x54,0x7c,0xb, 0x7a,0x3, 0x3b,0x4c,0x7e,0x3,
+0x3b,0x23,0xbe,0x0, 0x20,0x50,0xb, 0x7e,0x3, 0x3b,0x4c,0xbe,0x0, 0xec,0x40,0x2,
+0xe1,0x5a,0x22,0x7d,0x31,0x9d,0x30,0x2, 0x29,0xb4,0x90,0x60,0xa1,0xe4,0x93,0xbc,
+0xbf,0x22,0x7e,0xa3,0x3b,0x4c,0x74,0x4, 0xa4,0x22,0x7d,0x13,0x7d,0x32,0x6d,0x22,
+0x74,0x6, 0x2f,0x11,0x14,0x78,0xfb,0xb, 0x14,0x12,0x27,0x13,0x7d,0x53,0xbe,0x54,
+0x0, 0xff,0x28,0x4, 0x7e,0x54,0x0, 0x40,0x22,0xc2,0xf, 0x22,0x12,0xa8,0x72,0x12,
+0x88,0x25,0x2, 0x88,0x19,0x7e,0x8, 0x31,0xbb,0x12,0xd0,0xf8,0x12,0xa7,0x59,0x7e,
+0x73,0x24,0x39,0x7a,0x73,0x31,0xbb,0xa9,0xd1,0xcb,0x12,0xd1,0x4f,0x7a,0x37,0x31,
+0xbf,0x7e,0x1f,0x3f,0xdf,0x7a,0x37,0x31,0xc1,0x7e,0x1f,0x1b,0xd2,0x7a,0x37,0x31,
+0xc3,0x6d,0x33,0x12,0xa7,0x36,0x2, 0x18,0x0, 0x12,0x6a,0xf7,0x12,0x88,0xad,0x12,
+0x8a,0x46,0x7e,0xb3,0x3, 0xc3,0xb4,0x1, 0x1e,0x7e,0x34,0x61,0xd6,0x12,0xd1,0x47,
+0x7e,0x24,0x0, 0x5, 0xad,0x12,0x7a,0x17,0x22,0x12,0x7e,0x14,0x61,0xd8,0x12,0x8b,
+0x50,0xad,0x32,0x7a,0x37,0x22,0x14,0x7e,0xb3,0x40,0x43,0x60,0x7, 0x14,0x7a,0xb3,
+0x40,0x43,0x80,0x6, 0x7e,0xb3,0x22,0x1d,0x60,0x6, 0x12,0x88,0x1c,0x12,0x8c,0xae,
+0x7e,0xb3,0x22,0x1e,0x60,0x6, 0x12,0xc7,0x1, 0x2, 0x8f,0x42,0x22,0x7e,0x90,0x1,
+0x7e,0x94,0x61,0xd6,0x7e,0x84,0x0, 0xff,0xb, 0x4a,0x30,0x7a,0x37,0x22,0x12,0x7e,
+0xb4,0x61,0xd8,0x7e,0xa4,0x0, 0xff,0xb, 0x5a,0x30,0x7a,0x37,0x22,0x14,0x7e,0x34,
+0x61,0x65,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x20,0x7e,0x14,0x61,0x5f,0x7e,0x4, 0x0,
+0xff,0xb, 0xa, 0xd0,0xe4,0x7a,0xb3,0x22,0x1d,0x12,0x8a,0x26,0x7e,0x34,0xff,0xfa,
+0xad,0x32,0x12,0x8c,0xa7,0x7d,0xc3,0xe, 0x34,0x7e,0x27,0xa, 0x56,0xbd,0x2c,0x58,
+0x1c,0x7e,0xc7,0xa, 0x54,0xbd,0xc3,0x58,0x14,0x6d,0xcc,0x9e,0xc7,0x24,0x26,0xbe,
+0xc7,0x21,0xff,0x8, 0x8, 0x12,0x8f,0xf0,0x60,0x3, 0x12,0xa8,0xb1,0x12,0xa8,0xc0,
+0x40,0x5, 0xe4,0x7a,0xb3,0x22,0x19,0x12,0x6f,0xf6,0x68,0x6, 0x7e,0xb3,0x40,0x2d,
+0x60,0xd, 0x7e,0xb3,0x40,0x2f,0x70,0x7, 0xe4,0x7a,0xb3,0x22,0x1e,0x80,0x6f,0x12,
+0x8a,0x2d,0x28,0x5, 0xe4,0x7a,0xb3,0x22,0x1e,0x30,0x10,0x5, 0xe4,0x7a,0xb3,0x22,
+0x1e,0x12,0xa8,0xf6,0x50,0xa, 0x12,0x8a,0x26,0x12,0x45,0xaa,0x7c,0x9b,0x80,0x17,
+0x7e,0xb3,0x1f,0xf5,0x70,0x11,0x7e,0xb3,0x1f,0xf6,0x70,0xb, 0x12,0x8a,0x2d,0x28,
+0x6, 0x7e,0x90,0x3, 0x12,0x8a,0x26,0x7e,0xc7,0xa, 0x52,0xbe,0xc4,0x5, 0xdc,0x8,
+0x17,0x12,0x8a,0x2d,0x28,0x12,0x6d,0xcc,0x9d,0xcd,0xbe,0xc7,0x21,0xff,0x58,0x8,
+0x12,0x8a,0x38,0xe4,0x7a,0xb3,0x22,0x1e,0xa, 0x29,0xb, 0x4a,0x30,0xad,0x32,0x7a,
+0x37,0x22,0x12,0xa, 0x29,0xb, 0x5a,0x30,0xad,0x32,0x7a,0x37,0x22,0x14,0x12,0x8a,
+0x35,0x50,0x11,0xe4,0x7a,0xb3,0x22,0x1e,0x7e,0x73,0x21,0xf5,0xbe,0x70,0x0, 0x28,
+0x3, 0x12,0x8a,0x38,0x7e,0xc7,0x21,0xfb,0xbd,0xcd,0x8, 0x1f,0x7e,0x24,0x0, 0x2,
+0x7d,0x3d,0x12,0x26,0xc7,0x6e,0x34,0xff,0xff,0xb, 0x34,0xbe,0x37,0x21,0xff,0x58,
+0xa, 0x12,0x8a,0x35,0x50,0x5, 0xe4,0x7a,0xb3,0x22,0x1e,0x12,0x8a,0x63,0xb4,0x1,
+0x5, 0xe4,0x7a,0xb3,0x22,0x1e,0x12,0x8f,0x96,0x7e,0xb3,0x0, 0x65,0xbe,0xb0,0x0,
+0x28,0x23,0x14,0x7a,0xb3,0x0, 0x65,0x70,0x1c,0xe4,0x7a,0xb3,0x22,0x1e,0x74,0x1,
+0x7a,0xb3,0x22,0x1d,0xe4,0x7a,0xb3,0x1f,0x5d,0x7a,0xb3,0x1f,0x5c,0x7a,0xb3,0x21,
+0xf5,0x7a,0xb3,0x1f,0xf4,0x22,0x74,0x1, 0x7a,0xb3,0x22,0x1e,0x22,0x7e,0x83,0x21,
+0xf5,0xbe,0x80,0x0, 0x22,0xa2,0x13,0x22,0xe4,0x7a,0xb3,0x0, 0x65,0x7a,0xb3,0x22,
+0x1d,0x74,0x2, 0x2, 0x3f,0xe8,0x12,0xad,0x57,0x60,0x17,0x12,0x8a,0x26,0x7e,0x37,
+0x22,0x12,0x3e,0x34,0x7a,0x37,0x22,0x12,0x7e,0x37,0x22,0x14,0x3e,0x34,0x7a,0x37,
+0x22,0x14,0x22,0xca,0x3b,0x12,0x8f,0x3a,0x38,0x2, 0x61,0x26,0x7e,0xc3,0x0, 0x68,
+0x4c,0xcc,0x78,0x3d,0x7a,0xb3,0x0, 0x68,0xe4,0x7a,0xb3,0x0, 0x6a,0x6c,0xaa,0x80,
+0x26,0x12,0x8b,0x31,0x7e,0x70,0x2, 0xac,0x7a,0x9, 0xd3,0x20,0x6b,0x9, 0xe3,0x20,
+0x6c,0x7a,0x49,0xd0,0x19,0xe4,0x0, 0x1, 0x74,0x1, 0x19,0xb4,0x0, 0x8, 0x12,0x8b,
+0x3b,0x59,0x34,0x0, 0x2, 0xb, 0xa0,0x7e,0xb3,0x21,0xf5,0xbc,0xba,0x38,0xd2,0x80,
+0x7b,0x7c,0xfc,0x6c,0xaa,0x80,0x31,0x12,0x8b,0x31,0x7e,0x49,0xd0,0x9, 0xe4,0x0,
+0x1, 0x9, 0xb4,0x0, 0x8, 0x70,0x4, 0x1b,0xf0,0x80,0x1b,0x12,0x8b,0x3b,0x7d,0x23,
+0x49,0x34,0x0, 0x2, 0x12,0x97,0x80,0xbe,0xf4,0x0, 0x23,0x8, 0x9, 0x74,0x5, 0x19,
+0xb4,0x0, 0x8, 0x75,0x1e,0x1, 0xb, 0xa0,0xbc,0xfa,0x38,0xcb,0x4c,0xff,0x78,0x2,
+0x80,0x26,0x7e,0x73,0x0, 0x6a,0xbe,0x70,0x4, 0x40,0x22,0x6c,0xaa,0x80,0xe, 0x12,
+0x8b,0x31,0x9, 0xb4,0x0, 0x8, 0xbe,0xb0,0x5, 0x68,0x6, 0xb, 0xa0,0xbc,0xfa,0x38,
+0xee,0xbc,0xfa,0x78,0x3, 0x75,0x1e,0x0, 0x12,0x8b,0x42,0x80,0xf, 0x7c,0xb7,0x4,
+0x7a,0xb3,0x0, 0x6a,0x80,0x6, 0x12,0x8b,0x42,0x75,0x1e,0x0, 0xe5,0x1e,0xda,0x3b,
+0x22,0x7e,0x90,0x9, 0xac,0x9a,0x2e,0x44,0x0, 0x6b,0x22,0x7c,0xbd,0x7c,0x7e,0x2,
+0x4f,0x6f,0xe4,0x7a,0xb3,0x0, 0x69,0x7a,0xb3,0x0, 0x68,0x7a,0xb3,0x0, 0x6a,0x22,
+0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x22,0x7d,0x13,0x7e,0x54,0x62,0x6e,0x12,0x8b,
+0x8b,0xbd,0x31,0x50,0x23,0x7e,0x54,0x62,0x70,0x12,0x8b,0x8b,0xbd,0x31,0x28,0x18,
+0x7e,0x14,0x62,0x72,0x12,0x8b,0x50,0xbd,0x32,0x50,0xd, 0x7e,0x14,0x62,0x74,0x12,
+0x8b,0x50,0xbd,0x32,0x28,0x2, 0xe4,0x22,0x74,0x1, 0x22,0x7e,0x44,0x0, 0xff,0xb,
+0x2a,0x30,0x22,0xca,0xf8,0x7e,0xa3,0x23,0x87,0x7e,0xb3,0x23,0x88,0xbe,0xa0,0x1,
+0x38,0x21,0xbe,0xb0,0x1, 0x38,0x1c,0x7e,0x47,0x21,0xf7,0xbe,0x44,0x0, 0x1e,0x28,
+0x2, 0x80,0x10,0x7e,0xf3,0x3b,0x24,0x4c,0xff,0x68,0x17,0x7e,0x47,0x37,0x5b,0x4d,
+0x44,0x78,0xf, 0x12,0x4b,0xb, 0x74,0x1, 0x7a,0xb3,0x40,0x38,0x7a,0xb3,0x3, 0xc3,
+0x80,0x35,0x4c,0xaa,0x78,0x36,0xb4,0x1, 0x33,0x7e,0x37,0x37,0x5b,0x7a,0x37,0x3b,
+0x26,0x7e,0xb3,0x3b,0x24,0xb4,0x3, 0x1f,0x7e,0x37,0x37,0x5b,0xbe,0x34,0x0, 0x0,
+0x28,0x15,0x74,0x4, 0x7a,0xb3,0x3b,0x24,0x7e,0x37,0x3b,0x3c,0x7e,0x27,0x3b,0x3e,
+0x12,0x87,0x3c,0x81,0x9d,0x80,0x0, 0x12,0xc9,0xef,0x81,0x9d,0x7e,0xc7,0x22,0x79,
+0x7e,0xd7,0x22,0x7b,0x4c,0xff,0x78,0x19,0x70,0x57,0xbe,0xa0,0x1, 0x78,0x52,0x7d,
+0x3c,0x7d,0x2d,0x12,0xc9,0x8a,0x12,0x87,0x38,0x74,0x1, 0x7a,0xb3,0x3b,0x24,0x80,
+0x40,0xbe,0xf0,0x1, 0x78,0x2e,0x7e,0x27,0x3b,0x2c,0x9e,0x27,0x3b,0x34,0x7e,0x14,
+0x62,0xa4,0x12,0x8b,0x50,0xbd,0x23,0x38,0x13,0x7e,0x27,0x3b,0x3a,0x9e,0x27,0x3b,
+0x32,0x7e,0x14,0x62,0xa6,0x12,0x8b,0x50,0xbd,0x23,0x28,0x15,0x74,0x3, 0x7a,0xb3,
+0x3b,0x24,0x80,0x5, 0xbe,0xf0,0x3, 0x78,0x8, 0x7a,0xc7,0x3b,0x3c,0x7a,0xd7,0x3b,
+0x3e,0x7e,0xb3,0x3b,0x24,0x60,0x26,0x7d,0x3c,0x7d,0x2d,0x7e,0x17,0x37,0x5f,0x7e,
+0x7, 0x37,0x61,0x12,0xc9,0x72,0xa, 0x2b,0x7e,0x73,0x3b,0x23,0xa, 0x37,0xbd,0x32,
+0x58,0xb, 0x12,0x87,0x38,0x7a,0xc7,0x37,0x5f,0x7a,0xd7,0x37,0x61,0xda,0xf8,0x22,
+0x2d,0xb3,0xb, 0x5a,0x30,0x2d,0x32,0x7e,0x24,0x0, 0x2, 0x2, 0x26,0xc7,0x6c,0xaa,
+0x80,0x1c,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x1c,0x22,0x49,0x32,0x1b,0xda,0xbd,
+0x31,0x28,0x9, 0x2e,0x24,0x1b,0xda,0x9d,0x31,0x1b,0x28,0x30,0xb, 0xa0,0x12,0x8c,
+0xd4,0x38,0xdf,0x22,0x7e,0xb3,0x24,0x3a,0xbc,0xba,0x22,0xca,0x79,0x7e,0x8, 0x31,
+0xbb,0x12,0xd0,0xf0,0x6d,0x77,0x12,0xa7,0x16,0x6c,0xaa,0x80,0x20,0x7e,0x50,0x2,
+0xac,0x5a,0x49,0x12,0x6, 0x18,0x3e,0x14,0x3e,0x14,0x1e,0x14,0x7e,0x7f,0x40,0xc,
+0x2d,0xf2,0xb, 0x7a,0x30,0x9d,0x31,0x59,0x32,0x31,0xbb,0xb, 0xa0,0x12,0x8c,0xd4,
+0x38,0xdb,0xa9,0xc1,0xcb,0x7e,0x34,0x61,0x6b,0x12,0x2d,0x68,0x7a,0x35,0x2a,0x7e,
+0x18,0x31,0xbb,0x7f,0x1, 0x12,0x9f,0xd4,0x6c,0xaa,0x80,0xe, 0x12,0x8d,0x53,0xbd,
+0x37,0x28,0x5, 0x12,0x8d,0x53,0x7d,0x73,0xb, 0xa0,0x12,0x8c,0xd4,0x38,0xed,0xa9,
+0xc1,0xcb,0x7e,0x37,0x24,0xe3,0xbd,0x37,0x50,0x6, 0x74,0x2, 0x7a,0xb3,0x40,0xb,
+0xda,0x79,0x22,0x7e,0x70,0x2, 0xac,0x7a,0x49,0x33,0x31,0xbb,0x2, 0x29,0xb4,0x7e,
+0xb3,0x3, 0xee,0x70,0x6, 0x12,0x8d,0x98,0x2, 0x8f,0xf3,0x12,0x8b,0x93,0x12,0xc9,
+0x46,0x50,0xa, 0x12,0x85,0xa8,0x7c,0x3b,0x12,0x8d,0x98,0x80,0x5, 0x12,0x8d,0x9e,
+0x7c,0x3b,0x4c,0x33,0x68,0x11,0x7c,0xb3,0x12,0xc8,0xca,0x60,0xa, 0x7a,0x33,0x3,
+0xf1,0x74,0x1, 0x7a,0xb3,0x23,0x8d,0x22,0xe4,0x7a,0xb3,0x3b,0x24,0x22,0xca,0xd8,
+0xca,0x79,0x6c,0xff,0x6d,0xdd,0x7d,0xed,0x7d,0xfd,0x7e,0xd3,0x23,0x87,0x7e,0xe3,
+0x23,0x88,0x7e,0xb3,0x40,0x18,0x60,0x11,0x7e,0xc7,0x40,0x21,0x4d,0xcc,0x78,0x2,
+0xc1,0x92,0xbe,0xd0,0x1, 0x28,0x2, 0xc1,0x92,0xbe,0xd0,0x1, 0x78,0x1d,0xbe,0xb0,
+0x4, 0x78,0x2, 0xc1,0x92,0x7e,0xe7,0x22,0x79,0x7e,0xf7,0x22,0x7b,0x7d,0x3e,0x7d,
+0x2f,0x12,0x8b,0x58,0xbe,0xb0,0x1, 0x78,0x2, 0xc1,0x92,0x7e,0xa3,0x40,0x18,0x7c,
+0xba,0x14,0x68,0x29,0x14,0x68,0x54,0x14,0x68,0x23,0x14,0x78,0x2, 0xc1,0x8f,0xb,
+0xb2,0x68,0x2, 0xc1,0x92,0xbe,0xd0,0x1, 0x68,0x2, 0xc1,0xa1,0x4c,0xee,0x68,0x2,
+0xc1,0xa1,0x74,0x1, 0x7a,0xb3,0x40,0x18,0x12,0x8e,0xa8,0x80,0x65,0x4c,0xdd,0x78,
+0x1d,0xbe,0xa0,0x1, 0x78,0xc, 0x74,0x2, 0x7a,0xb3,0x40,0x18,0x7e,0x34,0x62,0x7a,
+0x80,0x54,0x74,0x4, 0x7a,0xb3,0x40,0x18,0x7e,0x34,0x62,0x7e,0x80,0x48,0x12,0x8e,
+0xb1,0x90,0x62,0x6d,0x12,0x8e,0xba,0x68,0x49,0x80,0x56,0xbe,0xd0,0x1, 0x78,0x51,
+0x4c,0xee,0x78,0x4d,0x12,0x8e,0xb1,0x7e,0x34,0x62,0x76,0x12,0x2d,0x68,0x7e,0x14,
+0x62,0x7a,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0xc0,0x9d,0xc3,0xbe,0xc7,0x40,0x21,0x40,
+0x21,0x90,0x62,0x6c,0x12,0x8e,0xba,0x68,0x19,0x12,0x8e,0xa8,0x74,0x3, 0x7a,0xb3,
+0x40,0x18,0x7e,0x34,0x62,0x7a,0x12,0x2d,0x68,0x7a,0x37,0x40,0x21,0x80,0x12,0x7e,
+0xf0,0x24,0xe4,0x7a,0xb3,0x40,0x18,0x6d,0x33,0x7a,0x37,0x40,0x21,0x7c,0xbf,0x80,
+0x2, 0x7c,0xbf,0xda,0x79,0xda,0xd8,0x22,0x7a,0xe7,0x40,0x19,0x7a,0xf7,0x40,0x1b,
+0x22,0x7a,0xe7,0x40,0x1d,0x7a,0xf7,0x40,0x1f,0x22,0xe4,0x93,0xa, 0x3b,0x12,0x8e,
+0xc6,0xa, 0xdb,0x4d,0xdd,0x22,0x7d,0x13,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x7e,0x37,
+0x40,0x1d,0x9e,0x37,0x40,0x19,0x12,0x29,0xb4,0xbd,0x31,0x38,0x12,0x7e,0x37,0x40,
+0x1f,0x9e,0x37,0x40,0x1b,0x12,0x29,0xb4,0xbd,0x31,0x38,0x3, 0x74,0x1, 0x22,0xe4,
+0x22,0x7e,0xa0,0x1, 0x7e,0x37,0x24,0x1b,0x12,0x8f,0x3a,0x28,0x35,0x6d,0x22,0x9d,
+0x23,0xbe,0x27,0xa, 0x50,0x58,0x2b,0x12,0x8c,0xa7,0xbe,0x37,0xa, 0x52,0x8, 0x22,
+0xe4,0x7a,0xb3,0x21,0xf5,0x7e,0xb3,0x23,0x88,0x70,0x17,0x7e,0xb3,0x3, 0xc5,0xb4,
+0x1, 0x10,0x6c,0xaa,0x5, 0x1d,0xe5,0x1d,0xbe,0xb0,0x10,0x28,0x5, 0xd2,0x12,0x75,
+0x1d,0x0, 0x4c,0xaa,0x68,0x3, 0x75,0x1d,0x0, 0x22,0x7e,0xb3,0x21,0xf5,0xbe,0xb0,
+0x0, 0x22,0x7e,0xa3,0x24,0x3a,0x7e,0x53,0x24,0x39,0x7c,0x95,0xac,0x9a,0x7e,0x37,
+0x22,0x12,0x12,0xa7,0xdc,0x6d,0x11,0x80,0x10,0x7d,0x1, 0x12,0xa7,0x49,0x6e,0x4,
+0xff,0xff,0xb, 0x4, 0x1b,0x7a,0x0, 0xb, 0x14,0xbd,0x41,0x38,0xec,0x7e,0xf, 0x3f,
+0xdf,0x7a,0x17,0x31,0xbf,0x7e,0x14,0xa, 0x62,0x7a,0x17,0x31,0xc1,0x7e,0x14,0xa,
+0x62,0x7a,0x17,0x31,0xc3,0x7a,0x53,0x31,0xbb,0x7a,0xa3,0x31,0xbc,0x7e,0x8, 0x31,
+0xbb,0x7c,0xb7,0x2, 0x16,0xe2,0x7e,0x60,0x4, 0x7e,0x27,0x40,0x32,0xbe,0x24,0x3,
+0xe8,0x28,0x3, 0x7e,0x60,0x8, 0x7e,0xb3,0x22,0x1d,0xb4,0x1, 0x1a,0x7e,0x73,0x0,
+0x66,0xbc,0x76,0x50,0xf, 0xe4,0x7a,0xb3,0x22,0x1e,0x12,0x8a,0x38,0x7e,0xb3,0x0,
+0x66,0x4, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0x7a,0xb3,0x0, 0x66,0x7e,0xb3,0x22,0x1e,
+0xb4,0x1, 0x17,0x7e,0xa3,0x0, 0x67,0xbe,0xa0,0x5, 0x50,0xa, 0xe4,0x7a,0xb3,0x22,
+0x1e,0x7c,0xba,0x4, 0x80,0x5, 0x74,0x5, 0x80,0x1, 0xe4,0x7a,0xb3,0x0, 0x67,0x22,
+0x74,0x1, 0x22,0xe4,0x7a,0xb3,0x40,0x18,0x22,0x74,0xc8,0x7a,0xb3,0x40,0x34,0xc2,
+0x17,0x80,0xa, 0x12,0x90,0x13,0x30,0x17,0x4, 0x75,0xe9,0xff,0x22,0x12,0x90,0x92,
+0x68,0xf1,0x22,0x80,0x1d,0x12,0x90,0x44,0x12,0x90,0x92,0x68,0x5, 0xc2,0x4, 0x12,
+0x3f,0x15,0x7e,0xb3,0x3f,0xe5,0xbe,0xb0,0x2, 0x68,0x18,0x20,0x17,0x15,0xe4,0x12,
+0x90,0x4b,0x20,0x93,0xe0,0x12,0x90,0x44,0xa9,0xd1,0xcd,0xa9,0xc5,0xea,0x74,0x2,
+0x2, 0x90,0x4b,0x22,0x74,0x81,0x7a,0xb3,0x40,0x30,0x22,0x7c,0xab,0x7e,0xb3,0x40,
+0x30,0xb4,0x81,0x38,0x4c,0xaa,0x78,0x5, 0xa9,0xd0,0x87,0x80,0x29,0xbe,0xa0,0x1,
+0x78,0xf, 0xc2,0xaf,0xa9,0xd0,0xce,0xa9,0xc7,0xc9,0xa9,0xd1,0x87,0xd2,0xaf,0x80,
+0x15,0xbe,0xa0,0x2, 0x78,0x16,0xc2,0xaf,0x20,0x93,0x9, 0xa9,0xd0,0xce,0xa9,0xd7,
+0xc9,0xa9,0xd1,0x87,0xd2,0xaf,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4,0x7a,0xb3,0x40,
+0x30,0x22,0x7e,0xb3,0x3f,0xe5,0xbe,0xb0,0x1, 0x22,0xd2,0x3, 0x80,0x12,0x30,0x3,
+0xc, 0x12,0x90,0x92,0x68,0x7, 0xc2,0x3, 0xc2,0x4, 0x12,0x3f,0x15,0x12,0x90,0x13,
+0x30,0x17,0xeb,0x22,0x74,0x1, 0x12,0x90,0xd3,0x20,0x17,0x6, 0x12,0x90,0x9a,0x12,
+0x0, 0x6e,0x7e,0xb3,0x3f,0xe5,0xb4,0x1, 0x6, 0x12,0x8f,0xf9,0x12,0x0, 0x6e,0xe4,
+0x2, 0x90,0xd3,0xbe,0xb0,0x8, 0x50,0x3, 0x12,0x91,0x25,0x22,0x30,0x17,0x3, 0x20,
+0x19,0x39,0x30,0x19,0x5, 0xc2,0x4, 0x12,0x3f,0x15,0xa9,0xd1,0xcd,0xa9,0xc5,0xea,
+0xa9,0xd3,0xcd,0xa9,0xd2,0xcd,0xa9,0xd0,0xce,0xa9,0xc4,0xc9,0x12,0x90,0x44,0x74,
+0x2, 0x12,0x90,0x4b,0xa9,0xd0,0xce,0xa9,0xd4,0xc9,0xa9,0xc1,0xcd,0xa9,0xc3,0xcd,
+0xa9,0xc2,0xcd,0x30,0x19,0x5, 0xc2,0x4, 0x2, 0x3f,0x15,0x22,0x12,0x90,0x92,0x68,
+0xfb,0x20,0x93,0xfd,0x22,0xa, 0x5b,0x2e,0x54,0x0, 0x8, 0xf5,0xcc,0x22,0xa9,0xc4,
+0xca,0xa9,0xc5,0xca,0xbe,0xb0,0x8, 0x50,0x3, 0x12,0x91,0x25,0xa9,0xd0,0xce,0xa9,
+0xc0,0xc9,0xd2,0x5, 0x12,0x3f,0xc, 0xa9,0xc2,0xea,0x75,0xc1,0x6, 0x75,0xc2,0xc,
+0xd2,0x3, 0x12,0x91,0x5f,0xa9,0xc1,0xc4,0xa9,0xd2,0xc4,0xa9,0xc2,0xe1,0x22,0xa2,
+0x3, 0xa9,0x97,0xc1,0xa2,0x3, 0xa9,0x95,0xc1,0xa2,0x3, 0xa9,0x97,0xc2,0xa2,0x3,
+0xa9,0x96,0xc2,0x22,0x12,0x48,0xc9,0x7e,0x73,0x3, 0x9d,0xbe,0x70,0xff,0x68,0x13,
+0xbe,0x73,0x3, 0xc3,0x68,0xd, 0x7a,0x73,0x3, 0xc3,0x74,0xff,0x7a,0xb3,0x3, 0x9d,
+0x2, 0x48,0xc9,0x22,0x7e,0x34,0x61,0x67,0x2, 0x2d,0x68,0x7e,0xb3,0x3, 0xc3,0x70,
+0x2e,0x7e,0x73,0x3, 0xa6,0xbe,0x70,0x10,0x40,0x2, 0x6c,0x77,0x7e,0xb3,0x3, 0xee,
+0xb4,0x1, 0x3, 0x7e,0x70,0x6, 0xa, 0x37,0x2e,0x34,0x29,0x84,0x12,0x57,0xbb,0x7c,
+0xab,0xe5,0x64,0xa, 0x3b,0x2e,0x37,0x40,0x36,0x7a,0x37,0x40,0x36,0x80,0xc, 0x7e,
+0xa3,0x3, 0xa7,0xbe,0xa0,0x7f,0x28,0x3, 0x7e,0xa0,0x7f,0x7c,0xba,0x2, 0x91,0xe0,
+0x75,0x64,0x0, 0x7a,0xb3,0x40,0x34,0xc2,0x17,0x22,0xca,0x3b,0x7c,0x7b,0x6c,0xff,
+0x7e,0x7, 0x21,0xfb,0x7e,0x14,0x0, 0x5, 0xad,0x10,0x7d,0xc1,0xe, 0xc4,0xe, 0xc4,
+0xe, 0xc4,0x74,0x2, 0xac,0xb7,0x9, 0x65,0x20,0x6b,0x9, 0xe5,0x20,0x6c,0x7a,0xe1,
+0x24,0x7e,0x8, 0x0, 0x25,0x7a,0xd, 0x28,0x7c,0xbe,0x7c,0x76,0x7d,0x2c,0x7e,0x8,
+0x0, 0x26,0x12,0x92,0x52,0x7e,0xc1,0x26,0x7e,0xd1,0x25,0x1b,0xe0,0xbe,0xe0,0x0,
+0x48,0x5, 0x12,0x92,0xd7,0x38,0xf4,0x7e,0xe1,0x24,0x7a,0xc1,0x26,0x7a,0xd1,0x25,
+0xb, 0xe0,0xe5,0x27,0xbc,0xbe,0x8, 0x5, 0x12,0x92,0xd7,0x38,0xf3,0x7c,0xbf,0xda,
+0x3b,0x22,0xca,0x79,0x7f,0x70,0x7d,0xd2,0x7c,0xe6,0x7c,0xf7,0x7c,0x8b,0x90,0x60,
+0x50,0xe4,0x93,0x7c,0x9b,0x7c,0xaf,0x80,0xb, 0x12,0x92,0xcd,0x48,0x4, 0x7c,0xfa,
+0x80,0x6, 0xb, 0xa0,0xbc,0xea,0x58,0xf1,0xa, 0x5f,0x1b,0x54,0x7c,0xab,0x80,0x7,
+0x12,0x92,0xcd,0x48,0x7, 0x1b,0xa0,0xbe,0xa0,0x0, 0x58,0xf4,0xbe,0xa0,0x0, 0x58,
+0x2, 0x6c,0xaa,0x7a,0x7b,0xa0,0xa, 0x5f,0xb, 0x54,0x7c,0xab,0x80,0x7, 0x12,0x92,
+0xcd,0x48,0x6, 0xb, 0xa0,0xbc,0x9a,0x18,0xf5,0xbc,0x9a,0x18,0x6, 0xa, 0x59,0x1b,
+0x54,0x7c,0xab,0x7e,0x1d,0x28,0x7a,0x1b,0xa0,0x7e,0x7b,0x70,0xa, 0x47,0x7e,0x1d,
+0x28,0x7e,0x1b,0x70,0xa, 0x57,0x9d,0x54,0xb, 0x54,0xda,0x79,0x22,0x7c,0xba,0x7c,
+0x78,0x12,0x4f,0x6f,0xbd,0x3d,0x22,0x7e,0x18,0x0, 0x25,0x7a,0x1d,0x28,0x7c,0xbe,
+0x7e,0x71,0x26,0x7e,0x61,0x25,0x7d,0x2c,0x7e,0x8, 0x0, 0x26,0x12,0x92,0x52,0x7c,
+0xab,0x2c,0xfa,0xbe,0xa0,0x3, 0x22,0x7c,0xab,0xbe,0xa0,0x32,0x38,0x19,0x7e,0xb3,
+0x3, 0xff,0x60,0x7, 0xbe,0xa0,0x23,0x28,0x2, 0x80,0xc, 0x4c,0xaa,0x78,0x3, 0xe4,
+0x80,0x7, 0x12,0x93,0x40,0x60,0x6, 0x74,0x14,0x7a,0xb3,0x3, 0xff,0x7e,0xb3,0x3,
+0xff,0xbe,0xb0,0x0, 0x28,0x17,0x7e,0x37,0x21,0xf9,0xbe,0x34,0x0, 0x14,0x50,0x5,
+0x14,0x7a,0xb3,0x3, 0xff,0xe4,0x7a,0xb3,0x21,0xf5,0xd2,0x10,0x22,0xc2,0x10,0x22,
+0x6c,0xaa,0x7e,0x63,0x24,0x3a,0x7e,0x73,0x24,0x39,0xac,0x76,0x7d,0x13,0x1e,0x14,
+0x7e,0x27,0x21,0xfb,0xbe,0x24,0x2, 0xbc,0x58,0xc, 0x3e,0x14,0x7e,0x4, 0x0, 0x3,
+0x8d,0x10,0x9e,0x14,0x0, 0xa, 0x7e,0x27,0x21,0xf9,0x2e,0x27,0x21,0xf7,0xbd,0x21,
+0x38,0xa, 0x1e,0x34,0x1e,0x34,0xbe,0x37,0x21,0xf7,0x50,0x29,0x90,0x60,0x51,0xe4,
+0x93,0x1e,0xb0,0xa, 0x2b,0x7e,0xb3,0x20,0x68,0xa, 0x3b,0xbd,0x32,0x8, 0x16,0x90,
+0x60,0x50,0xe4,0x93,0x1e,0xb0,0xa, 0x2b,0x7e,0xb3,0x20,0x67,0xa, 0x3b,0xbd,0x32,
+0x8, 0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0x7e,0xa3,0x23,0x88,0xbe,0xa0,0x0, 0x38,
+0x2f,0xbe,0xa3,0x23,0x87,0x50,0x19,0x7e,0xb3,0x23,0x91,0xbe,0xb3,0x3c,0x1f,0x28,
+0x14,0x7e,0xb3,0x3c,0x1f,0x4, 0x7a,0xb3,0x3c,0x1f,0x7a,0xa3,0x23,0x87,0x80,0x5,
+0xe4,0x7a,0xb3,0x3c,0x1f,0x7e,0xb3,0x23,0x87,0x70,0x5, 0xe4,0x7a,0xb3,0x23,0x90,
+0x22,0x12,0x93,0xe7,0x2, 0x93,0xa8,0x7e,0xb3,0x23,0x87,0x70,0x2d,0x7e,0x73,0x23,
+0x88,0xbe,0x70,0x0, 0x28,0x24,0x7e,0xb3,0x3b,0xa5,0x70,0x18,0x12,0x94,0x24,0x7e,
+0x73,0x23,0x88,0x7a,0x73,0x23,0x87,0x74,0x1, 0x7a,0xb3,0x23,0x8e,0x7e,0xb3,0x3b,
+0xa5,0x4, 0x80,0x1, 0xe4,0x7a,0xb3,0x3b,0xa5,0x22,0xe4,0x7a,0xb3,0x3b,0xa5,0x7a,
+0xb3,0x23,0x8e,0x22,0x7e,0x34,0x0, 0x3c,0xca,0x39,0x7e,0x18,0x3d,0x3d,0x7e,0x8,
+0x3d,0x79,0x12,0x29,0x4d,0x1b,0xfd,0x7e,0x73,0x22,0x5, 0x7a,0x73,0x3d,0x33,0x7a,
+0x73,0x22,0x4, 0x22,0xe4,0x7a,0xb3,0x3b,0xa4,0x7a,0xb3,0x3b,0x4e,0x7e,0x8, 0x3b,
+0x4f,0x74,0xa, 0x7e,0x34,0x0, 0xa, 0x12,0x29,0x72,0x7e,0x8, 0x3b,0x59,0x7e,0x34,
+0x0, 0xa, 0xe4,0x12,0x29,0x72,0x7e,0x8, 0x3b,0x79,0x7e,0x34,0x0, 0xa, 0x2, 0x29,
+0x72,0xca,0x3b,0x7e,0xa3,0x23,0x87,0x7e,0x8, 0x23,0x2d,0x7e,0x90,0xa, 0x7e,0x80,
+0x3, 0x4c,0xaa,0x78,0x5, 0x12,0x94,0x44,0xe1,0x2a,0x12,0x7e,0x5e,0x50,0x4f,0x7e,
+0x90,0x14,0x7e,0x80,0xd, 0x7e,0xb3,0x3d,0x34,0xb4,0x2, 0x2a,0x7e,0xb3,0x3d,0x3c,
+0xa, 0x2b,0x7e,0xb3,0x3d,0x3b,0x12,0x7d,0xca,0x7d,0xf3,0x7e,0xb3,0x3d,0x3a,0xa,
+0x2b,0x7e,0xb3,0x3d,0x39,0x12,0x7d,0xca,0x2d,0x3f,0xbe,0x34,0x0, 0xa, 0x58,0x6,
+0x7e,0x90,0x1e,0x7e,0x80,0x12,0x7e,0xb3,0x3, 0xa9,0xb4,0x1, 0x11,0x7e,0x90,0x1e,
+0x7e,0x80,0x17,0xbe,0xa0,0x3, 0x28,0x6, 0x7e,0x90,0x28,0x7e,0x80,0x21,0x6c,0xff,
+0xe1,0x23,0x7e,0x70,0x9, 0xac,0x7f,0x9, 0xe3,0x22,0x7d,0xa, 0x2e,0x7f,0x50,0x2d,
+0xb2,0x7e,0x5b,0x50,0xa5,0xbd,0x0, 0xb, 0xa, 0xfe,0x19,0x9f,0x3b,0x4f,0xe4,0x19,
+0xbf,0x3b,0x59,0xbe,0xe0,0xff,0x78,0x2, 0xe1,0x21,0xa, 0xfe,0x9, 0x4f,0x3b,0x4f,
+0x7a,0x43,0x3b,0x4d,0x9, 0x4f,0x3b,0x59,0x7a,0x43,0x3b,0x4e,0xa5,0xbd,0x2, 0x2,
+0x80,0x2, 0xc1,0xde,0x7e,0x50,0x4, 0xac,0x5e,0x49,0x22,0x3c,0x20,0x49,0x33,0x22,
+0x79,0x12,0x97,0x80,0x7e,0x70,0x4, 0xac,0x7e,0x49,0x23,0x3c,0x22,0x7e,0x70,0x9,
+0xac,0x7f,0x49,0x33,0x22,0x7b,0x9d,0x32,0x12,0x29,0xb4,0x7d,0xe3,0x7e,0x73,0x3b,
+0x4d,0xa, 0x27,0xbd,0x2f,0x28,0x63,0xbd,0x2e,0x28,0x5f,0x7e,0x50,0x4, 0xac,0x5e,
+0x49,0x22,0x3c,0x20,0x7e,0xd0,0x9, 0xac,0xdf,0x59,0x26,0x22,0x79,0x7e,0x50,0x4,
+0xac,0x5e,0x49,0x22,0x3c,0x22,0x7e,0xd0,0x9, 0xac,0xdf,0x59,0x26,0x22,0x7b,0x7e,
+0x63,0x3b,0x4d,0xbe,0x60,0x1, 0x28,0x7, 0xe4,0xa, 0x2f,0x19,0xb2,0x3b,0x79,0xbe,
+0xa0,0x0, 0x28,0x2, 0x1b,0xa0,0x7e,0xb3,0x3b,0x4e,0x4, 0x7a,0xb3,0x3b,0x4e,0xbe,
+0xb0,0x32,0x50,0x2, 0xc1,0xce,0xe4,0x7a,0xb3,0x3b,0x4e,0xbc,0x68,0x40,0x2, 0xc1,
+0xce,0x7c,0xb6,0x4, 0x7a,0xb3,0x3b,0x4d,0xc1,0xce,0xbe,0x70,0x1, 0x50,0x2, 0xc1,
+0x9b,0x7e,0x70,0x4, 0xac,0x7e,0x49,0x23,0x3c,0x20,0x7e,0xd0,0x9, 0xac,0xdf,0x49,
+0xd6,0x22,0x79,0x9d,0xd2,0x49,0x33,0x3c,0x22,0x49,0xc6,0x22,0x7b,0x9d,0xc3,0x7e,
+0xb3,0x23,0x87,0xbe,0xb0,0x1, 0x50,0x2, 0xc1,0x9b,0x12,0x97,0x2d,0xbe,0xb0,0x10,
+0x50,0xa, 0xa, 0x3f,0x2e,0x34,0x3b,0x79,0x4, 0x7a,0x39,0xb0,0xbe,0xf4,0x1, 0x2c,
+0x38,0x6, 0xbe,0xe4,0x1, 0x2c,0x28,0x5a,0x7e,0xb3,0x3b,0xa4,0xbe,0xb0,0x64,0x50,
+0x5, 0x4, 0x7a,0xb3,0x3b,0xa4,0x12,0x97,0x2d,0xbe,0xb0,0x10,0x50,0x7, 0xa, 0x3b,
+0xb, 0x34,0x12,0x97,0x36,0xbe,0xf4,0x2, 0xbc,0x38,0x6, 0xbe,0xe4,0x2, 0xbc,0x28,
+0xc, 0xa, 0x3f,0x9, 0x63,0x3b,0x79,0x7e,0x70,0x2, 0x12,0x97,0x34,0xbe,0xf4,0x4,
+0x4c,0x38,0x6, 0xbe,0xe4,0x4, 0x4c,0x28,0xc, 0xa, 0x3f,0x9, 0x63,0x3b,0x79,0x7e,
+0x70,0x4, 0x12,0x97,0x34,0x12,0x97,0x2d,0xbe,0xb0,0x10,0x28,0x5, 0x74,0x10,0x12,
+0x97,0x38,0x12,0x97,0x2d,0xa, 0x9b,0xad,0x9d,0x7d,0x39,0xe, 0x34,0xe, 0x34,0xe,
+0x34,0xe, 0x34,0x12,0x97,0x6f,0x59,0x32,0x22,0x79,0x12,0x97,0x2d,0xa, 0x3b,0xad,
+0x3c,0x7d,0x23,0xe, 0x24,0xe, 0x24,0xe, 0x24,0xe, 0x24,0x7e,0x70,0x4, 0xac,0x7e,
+0x49,0x33,0x3c,0x22,0x12,0x97,0x6f,0x59,0x32,0x22,0x7b,0x7e,0x70,0x9, 0xac,0x7f,
+0x49,0x93,0x22,0x79,0x7e,0x50,0x4, 0xac,0x5e,0x59,0x92,0x3c,0x20,0x12,0x97,0x77,
+0x7e,0x73,0x3b,0x4d,0xbe,0x70,0x1, 0x28,0x4, 0x74,0x1, 0x80,0x8, 0xbe,0x70,0x1,
+0x28,0x7, 0x7c,0xb7,0x14,0x7a,0xb3,0x3b,0x4d,0xe4,0x7a,0xb3,0x3b,0x4e,0x7e,0xb3,
+0x3b,0x4d,0xa, 0x3e,0x19,0xb3,0x3b,0x4f,0x7e,0xb3,0x3b,0x4e,0x80,0x3d,0x7e,0x5b,
+0xb0,0x70,0x1c,0x7e,0x70,0x9, 0xac,0x7f,0x49,0x33,0x22,0x79,0x7e,0x50,0x4, 0xac,
+0x5e,0x59,0x32,0x3c,0x20,0x7e,0x70,0x9, 0xac,0x7f,0x12,0x97,0x77,0x80,0x22,0xa,
+0x3e,0x2d,0x31,0x7d,0x20,0x7e,0x1b,0xb0,0xb4,0x1, 0x16,0x7e,0xb3,0x23,0x87,0xbe,
+0xb0,0x0, 0x28,0xd, 0xa, 0x3e,0x19,0x93,0x3b,0x4f,0xe4,0xa, 0x3e,0x19,0xb3,0x3b,
+0x59,0xb, 0xf0,0x12,0x87,0xea,0x28,0x2, 0x81,0xe2,0xda,0x3b,0x22,0xa, 0x3f,0x9,
+0xb3,0x3b,0x79,0x22,0xac,0x67,0x7c,0xb7,0xa, 0x3f,0x19,0xb3,0x3b,0x79,0x22,0x12,
+0x94,0x71,0x2, 0x97,0x45,0x7e,0xb3,0x23,0x8e,0x70,0x23,0x7e,0xb3,0x3b,0x83,0xb4,
+0x2, 0x9, 0x12,0x97,0x88,0x28,0x4, 0x74,0x3, 0x80,0x1, 0xe4,0x7a,0xb3,0x3b,0x8e,
+0x7e,0x73,0x3b,0x8f,0xbe,0x73,0x3b,0x8e,0x28,0x4, 0x7a,0x73,0x3b,0x8e,0x22,0x2d,
+0x32,0x7e,0x50,0x9, 0xac,0x5f,0x22,0x49,0x33,0x22,0x7b,0x59,0x32,0x3c,0x22,0x22,
+0x9d,0x32,0x12,0x29,0xb4,0x7d,0xf3,0x22,0x7e,0x73,0x23,0x87,0xbe,0x70,0x1, 0x22,
+0x7e,0x73,0x23,0x88,0xbe,0x73,0x23,0x87,0x78,0x13,0x12,0x97,0x88,0x40,0xe, 0x7e,
+0x37,0x3b,0x77,0xbe,0x34,0x0, 0x14,0x38,0xe, 0xb, 0x34,0x80,0x6, 0x7e,0x37,0x3b,
+0x77,0x1e,0x34,0x7a,0x37,0x3b,0x77,0x7e,0xb3,0x23,0x87,0x70,0x6, 0x6d,0x33,0x7a,
+0x37,0x3b,0x77,0x7e,0x37,0x3b,0x77,0x22,0xca,0x3b,0x6d,0x11,0x7e,0xe3,0x23,0x87,
+0x4c,0xee,0x78,0x23,0x6c,0xff,0x80,0x1a,0x74,0x2, 0xac,0xbf,0x12,0x99,0xaa,0x7e,
+0x70,0x9, 0xac,0x7f,0x19,0xa3,0x3b,0xaa,0x74,0x2, 0xa, 0x3f,0x19,0xb3,0x3c,0x14,
+0xb, 0xf0,0x12,0x87,0xea,0x38,0xe1,0x12,0x97,0x90,0x7e,0xf4,0x0, 0x50,0xad,0xf3,
+0x2e,0xf4,0xc, 0x80,0x6c,0xff,0x21,0x83,0x74,0x9, 0xac,0xbf,0x9, 0xd5,0x22,0x23,
+0x5e,0xd0,0xf, 0x12,0x77,0x1f,0x38,0x2, 0x21,0x81,0xa, 0x1d,0x9, 0xb1,0x23,0x2d,
+0xbe,0xb0,0x1, 0x78,0x2, 0x21,0x67,0x75,0x24,0x0, 0x21,0x5e,0x7e,0xa1,0x24,0x74,
+0x9, 0xa4,0x9, 0xc5,0x3b,0xaa,0xbc,0xcd,0x68,0x2, 0x21,0x5c,0x49,0x25,0x3b,0xa8,
+0x74,0x9, 0xac,0xbf,0x49,0x35,0x22,0x21,0x9d,0x32,0x12,0x29,0xb4,0x7d,0x3, 0x7e,
+0xa1,0x24,0x74,0x9, 0xa4,0x49,0x25,0x3b,0xa6,0x74,0x9, 0xac,0xbf,0x49,0x35,0x22,
+0x1f,0x9d,0x32,0x12,0x29,0xb4,0x2d,0x3, 0xbe,0x4, 0x9, 0x60,0x38,0x66,0xa, 0x1c,
+0x9, 0xa1,0x3c,0x14,0xbe,0xa0,0x0, 0x28,0x17,0x7e,0x30,0x2, 0xac,0x3c,0x59,0x1,
+0x3c,0x0, 0xa, 0x1c,0x2e,0x14,0x3c,0x14,0x7c,0xba,0x14,0x7a,0x19,0xb0,0x21,0x81,
+0x74,0x2, 0xac,0xbc,0x49,0x15,0x3c,0x0, 0xbe,0x14,0x0, 0xc8,0x28,0x8, 0x7d,0xe1,
+0x2d,0xef,0xbd,0xe0,0x40,0x2e,0x7e,0xe7,0x3b,0x77,0xbe,0xe4,0x0, 0x14,0x40,0x6,
+0x7e,0x44,0x0, 0x96,0x80,0x4, 0x7e,0x44,0x1, 0x2c,0xbd,0x14,0x28,0x6, 0xbd,0x40,
+0x50,0x2, 0x21,0x56,0x7d,0xe1,0x2e,0xe4,0x0, 0xc8,0xbd,0xe0,0x50,0x6, 0xbd,0x14,
+0x28,0x2, 0x21,0x56,0xbe,0x4, 0x3, 0x20,0x28,0x78,0xa, 0x1d,0x9, 0xb1,0x23,0x2d,
+0x70,0x4, 0x74,0x3, 0x80,0x2, 0x74,0x1, 0xa, 0x1d,0x19,0xb1,0x23,0x2d,0x74,0x3,
+0xa, 0x1c,0x19,0xb1,0x23,0x37,0xbe,0xe0,0x0, 0x38,0x2, 0x21,0x81,0x1b,0xe0,0x7e,
+0x70,0x9, 0xac,0x7f,0x2e,0x34,0x22,0x1f,0x7e,0x14,0x31,0xbb,0x74,0x9, 0x12,0x27,
+0x9a,0x7e,0x70,0x9, 0xac,0x7e,0x12,0x99,0xba,0xac,0x3f,0x2e,0x14,0x22,0x1f,0x74,
+0x9, 0x12,0x99,0xb2,0x7e,0x30,0x9, 0xac,0x3e,0x2e,0x14,0x22,0x1f,0x74,0x9, 0x12,
+0x27,0x9a,0x7a,0xe3,0x40,0x42,0x7e,0x14,0x7f,0xff,0x74,0x2, 0xac,0xbd,0x59,0x15,
+0x23,0x41,0x74,0x2, 0xac,0xbd,0x59,0x15,0x23,0x55,0x1b,0xf0,0x74,0x2, 0xac,0xbc,
+0x80,0x4, 0x74,0x2, 0xac,0xbc,0x59,0x5, 0x3c,0x0, 0x80,0x25,0x5, 0x24,0x12,0x74,
+0xfc,0x28,0x2, 0x1, 0x2c,0x80,0x1a,0x6d,0x11,0x74,0x2, 0xac,0xbd,0x12,0x99,0xaa,
+0x7e,0x30,0x9, 0xac,0x3d,0x19,0xa1,0x3b,0xaa,0x74,0x2, 0xa, 0x1d,0x19,0xb1,0x3c,
+0x14,0xb, 0xf0,0xbc,0xef,0x28,0x2, 0x1, 0x8, 0xe4,0x7a,0xb3,0x1f,0x5e,0x90,0x60,
+0xa1,0x12,0x81,0x21,0xca,0x59,0x7e,0x18,0x22,0x1f,0x7e,0x8, 0x3b,0xa6,0x12,0x29,
+0x4d,0x1b,0xfd,0x7a,0xe3,0x23,0x87,0xda,0x3b,0x22,0x59,0x15,0x3c,0x0, 0x7e,0xa0,
+0xff,0x22,0x12,0x27,0x9a,0x7e,0x34,0x31,0xbb,0x22,0x2e,0x34,0x22,0x1f,0x7e,0x30,
+0x9, 0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x90,0x60,0xa1,0xe4,0x93,0x7c,0xfb,0x6c,
+0x11,0x80,0x21,0x7e,0x0, 0xff,0x74,0x9, 0xac,0xb1,0x19,0x5, 0x31,0xbf,0x7e,0x34,
+0x7f,0xff,0x74,0x9, 0xac,0xb1,0x59,0x35,0x31,0xbb,0x74,0x9, 0xac,0xb1,0x59,0x35,
+0x31,0xbd,0xb, 0x10,0xbc,0xf1,0x38,0xdb,0xe4,0x6c,0x77,0x7c,0x6d,0x12,0x9a,0x64,
+0x7c,0x1b,0x7c,0x7d,0x7c,0x6f,0x12,0x9a,0x64,0x7c,0x1b,0x6c,0x0, 0x80,0x39,0x6c,
+0xee,0x80,0x16,0x74,0x9, 0xac,0xbe,0x9, 0x65,0x31,0xbf,0x74,0x9, 0xac,0xb0,0x9,
+0x75,0x22,0x23,0xbc,0x76,0x68,0x6, 0xb, 0xe0,0xbc,0x1e,0x38,0xe6,0xbc,0x1e,0x78,
+0x15,0x7e,0x70,0x9, 0xac,0x70,0x12,0x99,0xba,0xac,0x31,0x2e,0x14,0x31,0xbb,0x74,
+0x9, 0x12,0x27,0x9a,0xb, 0x10,0xb, 0x0, 0xbc,0xf0,0x38,0xc3,0x74,0x9, 0xac,0xbf,
+0xca,0x59,0x7e,0x18,0x31,0xbb,0x7e,0x8, 0x22,0xd3,0x12,0x29,0x4d,0x1b,0xfd,0xda,
+0x79,0xda,0xd8,0x22,0x7e,0x8, 0x31,0xbb,0xca,0x3b,0x7c,0x46,0x7c,0xab,0x6c,0x66,
+0x61,0x3, 0x7c,0x57,0x41,0xfb,0x7e,0xf0,0x9, 0xac,0xf6,0x9, 0x87,0x22,0xd7,0x7c,
+0x98,0x7e,0xd0,0x9, 0xac,0xd5,0x9, 0xb6,0x22,0x23,0xbc,0xb9,0x78,0x6b,0xbe,0x90,
+0xff,0x68,0x66,0x12,0x9b,0x13,0x39,0x87,0x0, 0x4, 0xa, 0xf9,0x9, 0xbf,0x23,0x2d,
+0x7e,0xf0,0x9, 0x70,0xc, 0xac,0xf5,0x7d,0x97,0x2e,0x94,0x22,0x1f,0x6d,0x88,0x80,
+0xa, 0xac,0xf6,0x7d,0x97,0x2e,0x94,0x22,0xd3,0x6d,0x88,0xb, 0x4a,0xd0,0x12,0x9b,
+0x13,0x1b,0x7a,0xd0,0x69,0xf4,0x0, 0x2, 0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x60,0x2d,
+0xd7,0x79,0xf6,0x0, 0x2, 0x7e,0xf0,0x9, 0xac,0xf5,0x9, 0x87,0x22,0x24,0x12,0x9b,
+0x13,0x39,0x87,0x0, 0x5, 0x7e,0xf0,0x9, 0xac,0xf5,0x9, 0x87,0x22,0x25,0x12,0x9b,
+0x13,0x39,0x87,0x0, 0x6, 0xb, 0xa0,0x80,0x8, 0xb, 0x50,0xbc,0x45,0x28,0x2, 0x41,
+0x76,0xb, 0x60,0x90,0x60,0xa1,0xe4,0x93,0xbc,0xb6,0x28,0x2, 0x41,0x72,0x7c,0xba,
+0xda,0x3b,0x22,0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x70,0x2d,0xf7,0x22,0x7c,0xab,0x7e,
+0xb, 0xb0,0x60,0x3, 0xb4,0x2, 0x31,0xa, 0x4a,0x9, 0x74,0x3b,0x84,0xbe,0x73,0x3b,
+0x8e,0x50,0xe, 0x7d,0x24,0x2e,0x24,0x3b,0x84,0x7c,0xb7,0x4, 0x7a,0x29,0xb0,0xd3,
+0x22,0xbe,0x73,0x3b,0x8e,0x40,0x9, 0xbe,0x70,0xff,0x68,0x4, 0xe4,0x7a,0xb, 0xb0,
+0x74,0xff,0x19,0xb4,0x3b,0x84,0x80,0x17,0xa, 0x3a,0x9, 0xb3,0x3b,0x84,0xbe,0xb0,
+0xff,0x68,0x7, 0xe4,0x19,0xb3,0x3b,0x84,0xd3,0x22,0xe4,0x19,0xb3,0x3b,0x84,0xc3,
+0x22,0xca,0xf8,0x7c,0xfb,0x7d,0xf3,0x7e,0x17,0x24,0x2e,0xbd,0x13,0x38,0x6, 0x7e,
+0x34,0x1, 0x0, 0x80,0x15,0x6d,0x22,0x7c,0x56,0x7c,0x67,0x6c,0x77,0x12,0x27,0x13,
+0xbe,0x34,0x0, 0x10,0x50,0x4, 0x7e,0x34,0x0, 0x10,0x74,0x2, 0xac,0xbf,0x49,0x25,
+0x3b,0x90,0xbd,0x2f,0x28,0x6, 0x49,0x35,0x3b,0x63,0x80,0x4, 0x59,0x35,0x3b,0x63,
+0x59,0xf5,0x3b,0x90,0xbe,0x34,0x1, 0x0, 0x28,0x4, 0x7e,0x34,0x1, 0x0, 0xda,0xf8,
+0x22,0x7e,0x8, 0x3b,0x83,0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x29,0x72,0x7e,0x73,0x21,
+0xf5,0xbe,0x70,0x2, 0x50,0x3, 0x6d,0x33,0x22,0x7e,0x37,0x21,0xfb,0x12,0x8c,0xa7,
+0x7e,0x17,0x24,0x26,0x7e,0x4, 0x0, 0x3, 0x8d,0x10,0x7d,0x21,0x3e,0x24,0x2e,0x27,
+0x24,0x26,0xbd,0x23,0x50,0x2, 0x7d,0x32,0x22,0xca,0x3b,0x6d,0x44,0x7e,0xf3,0x21,
+0xf5,0x6c,0xee,0x80,0x24,0x7c,0xbe,0x12,0x55,0x62,0x60,0x1b,0x74,0x2, 0xac,0xbe,
+0x9, 0xd5,0x20,0x6b,0x9, 0xc5,0x20,0x6c,0x7c,0xbd,0x7c,0x7c,0x12,0x4f,0x6f,0x7d,
+0xf3,0xbd,0x4f,0x58,0x2, 0x7d,0x4f,0xb, 0xe0,0xbc,0xfe,0x38,0xd8,0x7d,0x34,0xda,
+0x3b,0x22,0x7e,0xd7,0x24,0x28,0x12,0x9b,0xf9,0x7d,0xc3,0x3e,0x34,0x3e,0x34,0x7e,
+0xe4,0x0, 0xa, 0x12,0x9c,0xbc,0x7e,0xb3,0x22,0x19,0x60,0xf, 0x7e,0x37,0x3e,0x31,
+0xbd,0x3c,0x48,0x7, 0x3e,0x34,0x3e,0x34,0x12,0x9c,0xbc,0xbe,0xc4,0x4, 0x4c,0x8,
+0xf, 0x12,0x9c,0xc4,0x50,0x6, 0x7e,0xb3,0x22,0x19,0x60,0x4, 0x74,0xa, 0x80,0x13,
+0x7e,0xb3,0x22,0x19,0x60,0xc, 0x7e,0xb3,0x3e,0x2f,0xbe,0xb0,0x0, 0x28,0x8, 0x14,
+0x80,0x1, 0xe4,0x7a,0xb3,0x3e,0x2f,0x7e,0xe7,0x24,0x28,0x7d,0x3e,0x12,0x3e,0x7f,
+0x7e,0x53,0x3e,0x2f,0xbe,0x50,0x0, 0x28,0x12,0xbd,0x3f,0x58,0x4, 0x7d,0xf3,0x80,
+0x6, 0xbd,0xef,0x8, 0x2, 0x7d,0xfe,0x7a,0xf7,0x24,0x28,0x12,0x63,0x1d,0x28,0x3,
+0x12,0x6e,0xb1,0x7a,0xc7,0x3e,0x31,0x7a,0xd7,0x24,0x28,0x22,0x7d,0x2e,0x12,0x26,
+0xc7,0x7d,0xf3,0x22,0x6c,0x99,0x6c,0x88,0x80,0xf, 0x7c,0xb8,0x12,0x68,0x6b,0xbe,
+0x34,0x1, 0xf4,0x8, 0x2, 0xb, 0x90,0xb, 0x80,0x7e,0x73,0x21,0xf5,0xbc,0x78,0x38,
+0xe9,0xbe,0x90,0x1, 0x38,0x2, 0xc3,0x22,0xd3,0x22,0xca,0xd8,0xca,0x79,0x7e,0x34,
+0x62,0x3d,0x12,0x9d,0x9d,0x12,0x9c,0xc4,0x50,0x2, 0xa1,0x98,0x7e,0x34,0x62,0x41,
+0x12,0x2d,0x68,0x7a,0x35,0x2a,0x90,0x62,0x3c,0xe4,0x93,0x70,0x2, 0xa1,0x98,0x7e,
+0xb3,0x22,0x19,0xb4,0x1, 0x7, 0x7e,0x34,0x62,0x3f,0x12,0x9d,0x9d,0x7e,0x37,0x21,
+0xfb,0xbe,0x34,0x4, 0x4c,0x8, 0x71,0x6c,0xdd,0x80,0x65,0xc2,0x3, 0x7c,0xbd,0x12,
+0x68,0x6b,0x7a,0x35,0x26,0x7c,0xbd,0x7e,0x70,0x1, 0x7e,0x60,0x1, 0x12,0x9d,0xa5,
+0x7a,0x35,0x24,0x9e,0x35,0x26,0x7a,0x35,0x24,0x7e,0x35,0x26,0x3e,0x34,0x3e,0x34,
+0x12,0x8c,0xa7,0x7a,0x35,0x28,0xbe,0x75,0x28,0x58,0x3, 0x7a,0x75,0x28,0x7e,0x35,
+0x28,0xbe,0x35,0x24,0x8, 0xa, 0x7e,0x35,0x2a,0xbe,0x35,0x26,0x8, 0x2, 0xd2,0x3,
+0x7c,0xbd,0x12,0x9e,0xcc,0x50,0x2, 0xc2,0x3, 0x30,0x3, 0x12,0x7c,0xbd,0x6c,0x77,
+0x12,0x65,0xe0,0x7e,0x70,0x2, 0xac,0x7d,0x12,0x9e,0xa8,0x12,0x9e,0xb1,0xb, 0xd0,
+0x7e,0x73,0x21,0xf5,0xbc,0x7d,0x38,0x93,0xda,0x79,0xda,0xd8,0x22,0x7e,0x24,0x0,
+0xff,0xb, 0x1a,0x70,0x22,0xca,0x79,0x7c,0xa6,0x7c,0x97,0x7c,0x8b,0x7e,0xb3,0x24,
+0x3b,0x7a,0xb3,0x31,0xbc,0x7e,0xb3,0x24,0x3c,0x7a,0xb3,0x31,0xbd,0x7e,0x70,0x2,
+0xac,0x78,0x9, 0xb3,0x20,0x6b,0x7a,0xb3,0x31,0xbb,0x9, 0x83,0x20,0x6c,0x9f,0x77,
+0x1a,0x39,0x1a,0x7b,0x9d,0x73,0xc1,0x81,0x7a,0xf1,0x2d,0xbe,0xf0,0x0, 0x58,0x12,
+0x1a,0x1f,0x7e,0xb3,0x31,0xbb,0x1a,0x2b,0x7d,0x32,0x9d,0x31,0x2d,0x32,0x7c,0xb7,
+0xf5,0x2d,0x7e,0xb3,0x31,0xbc,0xbc,0xbf,0x18,0x10,0x7e,0xb3,0x31,0xbb,0x1a,0x3b,
+0x1a,0x2f,0x9d,0x23,0x9d,0x32,0x7c,0xb7,0xf5,0x2d,0x1a,0x29,0x1a,0x38,0x9d,0x32,
+0x7c,0xb7,0xf5,0x2c,0x80,0x5b,0x85,0x2c,0x2e,0xe5,0x2c,0xbe,0xb0,0x0, 0x58,0x10,
+0xe5,0x2c,0x1a,0x3b,0x1a,0x28,0x9d,0x23,0x1a,0x38,0x2d,0x32,0x7c,0xb7,0xf5,0x2e,
+0x7e,0xb3,0x31,0xbd,0xbe,0xb1,0x2c,0x18,0x10,0x1a,0x38,0xe5,0x2c,0x1a,0x2b,0x9d,
+0x23,0x1a,0x38,0x9d,0x32,0x7c,0xb7,0xf5,0x2e,0x4c,0xaa,0x68,0x7, 0xe5,0x2d,0x7e,
+0x71,0x2e,0x80,0x16,0xe5,0x2d,0x7e,0x71,0x2e,0x12,0x9e,0xa0,0xe5,0x2d,0x7e,0x71,
+0x2e,0x58,0x7, 0x12,0x9e,0x98,0x9f,0x71,0x80,0x5, 0x12,0x9e,0x98,0x2f,0x71,0x5,
+0x2c,0x1a,0x39,0x1a,0x28,0x2d,0x23,0xe5,0x2c,0x1a,0x3b,0xbd,0x32,0x8, 0x97,0xb,
+0xf0,0x1a,0x39,0x7e,0xb3,0x31,0xbb,0x1a,0x2b,0x2d,0x23,0x1a,0x3f,0xbd,0x32,0x18,
+0x2, 0xa1,0xd8,0x7f,0x17,0xda,0x79,0x22,0x12,0x4f,0x6f,0x1a,0x26,0x1a,0x24,0x22,
+0x12,0x4f,0x6f,0xbe,0x34,0x0, 0x0, 0x22,0x9, 0xb3,0x20,0x6b,0x9, 0x73,0x20,0x6c,
+0x22,0x7c,0x6b,0x7e,0xa3,0x3d,0xb5,0x7e,0x50,0x2, 0xac,0x5a,0x19,0x62,0x3d,0xf2,
+0x19,0x72,0x3d,0xf3,0x7c,0xba,0x4, 0x7a,0xb3,0x3d,0xb5,0x22,0x7c,0x4b,0x74,0x2,
+0xac,0xb4,0x9, 0x55,0x20,0x6b,0x9, 0x65,0x20,0x6c,0x7e,0x73,0x21,0xfd,0xbc,0x75,
+0x78,0xa, 0x7e,0x73,0x21,0xfe,0xbc,0x76,0x78,0x2, 0xd3,0x22,0xc3,0x22,0xca,0x79,
+0x7c,0xa4,0x7c,0x25,0x7c,0x36,0x7c,0x17,0x7c,0x9b,0x7e,0x3, 0x23,0x88,0xbe,0x0,
+0x1, 0x38,0x2, 0xe1,0xb8,0xa, 0x21,0xa, 0x39,0x7d,0xf3,0x9d,0xf2,0xbe,0xf4,0x0,
+0x2, 0x48,0x60,0x2d,0x32,0x7e,0xe4,0x0, 0x2, 0x12,0x9c,0xbc,0x3e,0xf4,0x7e,0x3,
+0x24,0x3a,0x7e,0xf0,0x2, 0xac,0xf0,0x2d,0xf7,0x7e,0x6f,0x7, 0x28,0x7f,0x16,0x2d,
+0x3f,0xb, 0x1a,0xf0,0x7e,0x34,0x0, 0x3, 0xad,0x3f,0x7d,0x2e,0x12,0x26,0xc7,0x7e,
+0x50,0x2, 0xac,0x51,0x2d,0x27,0x2d,0xd2,0xb, 0x6a,0x20,0xbd,0x32,0x58,0x24,0x7e,
+0x34,0x0, 0x3, 0xad,0x3f,0x12,0x8c,0xa7,0x7e,0x10,0x2, 0xac,0x1, 0x7e,0x50,0x2,
+0xac,0x59,0x2d,0x20,0x7e,0x7f,0x7, 0x28,0x2d,0xf2,0xb, 0x7a,0x20,0xbd,0x32,0x58,
+0x2, 0x6c,0xaa,0xa, 0x22,0xa, 0x33,0x7d,0x3, 0x9d,0x2, 0xbe,0x4, 0x0, 0x2, 0x48,
+0x37,0x12,0x8c,0xa5,0x7d,0x3, 0x3e,0x4, 0x7e,0x7f,0x7, 0x28,0x7f,0x17,0x2d,0x30,
+0xb, 0x1a,0x40,0x7e,0x10,0x2, 0xac,0x12,0x2d,0xf0,0xb, 0x7a,0x0, 0xbd,0x40,0x58,
+0x17,0xb, 0x1a,0x20,0x7e,0x70,0x2, 0xac,0x73,0x7e,0xf, 0x7, 0x28,0x2d,0x13,0xb,
+0xa, 0x30,0xbd,0x23,0x58,0x2, 0x6c,0xaa,0x7c,0xba,0xda,0x79,0x22,0xe4,0x7a,0xb3,
+0x3d,0xb5,0x7e,0xb3,0x21,0xf5,0x60,0x6, 0x7e,0xb3,0x3e,0x2e,0x60,0x5, 0xe4,0x7a,
+0xb3,0x3e,0x30,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x24,0x3a,0xa, 0x37,
+0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x29,0x4d,0x1b,0xfd,0x6c,0xdd,0x12,
+0xa5,0x91,0x7a,0xb3,0x32,0x3, 0x6c,0xcc,0x80,0x45,0x12,0xa0,0x79,0x78,0x3e,0x12,
+0xa5,0x99,0xb, 0x1a,0xe0,0x7d,0x3f,0x12,0x29,0xb4,0x7d,0x13,0x7d,0x3e,0x12,0x29,
+0xb4,0xbd,0x31,0x58,0x2, 0x7d,0xfe,0xbe,0xe5,0x2a,0x8, 0x5, 0x7e,0xe5,0x2a,0x80,
+0xb, 0x6d,0x33,0x9e,0x35,0x2a,0xbd,0x3e,0x8, 0x2, 0x7d,0xe3,0x7d,0x3e,0x1a,0x26,
+0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x32,0x3, 0x4, 0x7a,0xb3,0x32,0x3, 0xb, 0xc0,0x7e,
+0x73,0x24,0x3c,0xbc,0x7c,0x38,0xb3,0x7e,0x73,0x32,0x3, 0x4c,0x77,0x68,0x1d,0x12,
+0xa1,0x92,0x8, 0x2, 0x7d,0x7f,0x6c,0xcc,0x80,0xa, 0x12,0xa0,0x79,0x78,0x3, 0x12,
+0xa0,0x8c,0xb, 0xc0,0x7e,0x73,0x24,0x3c,0xbc,0x7c,0x38,0xee,0xb, 0xd0,0xbe,0xd0,
+0x3, 0x50,0x3, 0x2, 0x9f,0xef,0xda,0x3b,0x22,0xa, 0xec,0x9, 0x7e,0x24,0xb0,0xa,
+0x37,0x7e,0x24,0x0, 0x3, 0x8d,0x32,0xa, 0xed,0xbd,0x2e,0x22,0x74,0x2, 0xac,0xbc,
+0x7f,0x16,0x2d,0x35,0xb, 0x1a,0xe0,0x9d,0xe7,0x7f,0x15,0x2d,0x35,0x1b,0x1a,0xe0,
+0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x14,0x2c,0x31,0x7e,0x4, 0x0, 0xff,0x69,
+0x30,0x0, 0x2, 0xb, 0xa, 0x20,0x7a,0x1d,0x2c,0x7e,0x73,0x24,0x39,0xa, 0x37,0x3e,
+0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x29,0x4d,0x1b,0xfd,0x6c,0xdd,0x12,0xa5,
+0x91,0x7a,0xb3,0x31,0xbb,0x6c,0xcc,0x80,0x4c,0x12,0xa1,0x82,0x40,0x45,0x12,0xa1,
+0x7a,0xbc,0xab,0x50,0x3e,0x12,0xa5,0x99,0xb, 0x1a,0x10,0x7d,0x3f,0x12,0x29,0xb4,
+0x7d,0x3, 0x7d,0x31,0x12,0x29,0xb4,0xbd,0x30,0x58,0x2, 0x7d,0xf1,0xbe,0x15,0x2a,
+0x8, 0x5, 0x7e,0x15,0x2a,0x80,0xb, 0x6d,0x0, 0x9e,0x5, 0x2a,0xbd,0x1, 0x8, 0x2,
+0x7d,0x10,0x7d,0x31,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x31,0xbb,0x4, 0x7a,
+0xb3,0x31,0xbb,0xb, 0xc0,0x7e,0x73,0x24,0x3b,0xbc,0x7c,0x38,0xac,0x7e,0x73,0x31,
+0xbb,0x4c,0x77,0x68,0x39,0x12,0xa1,0x92,0x8, 0x2, 0x7d,0x7f,0xbe,0x75,0x2a,0x8,
+0x5, 0x7e,0x75,0x2a,0x80,0xb, 0x6d,0xee,0x9e,0xe5,0x2a,0xbd,0xe7,0x8, 0x2, 0x7d,
+0x7e,0x6c,0xcc,0x80,0x11,0x12,0xa1,0x82,0x40,0xa, 0x12,0xa1,0x7a,0xbc,0xab,0x50,
+0x3, 0x12,0xa0,0x8c,0xb, 0xc0,0x7e,0x73,0x24,0x3b,0xbc,0x7c,0x38,0xe7,0xb, 0xd0,
+0xbe,0xd0,0x3, 0x50,0x2, 0x1, 0xce,0xda,0x3b,0x22,0x7c,0x1d,0x2e,0x10,0x2d,0xa5,
+0xe7,0x22,0xa, 0xec,0x9, 0xae,0x24,0x8d,0x7c,0x1d,0x2e,0x10,0x2c,0xa5,0xe7,0xbc,
+0xab,0x22,0xa, 0x17,0x6d,0x0, 0x7f,0x14,0x12,0x27,0x66,0x7d,0x73,0x12,0x29,0xb4,
+0x7d,0xe3,0x7d,0x3f,0x12,0x29,0xb4,0xbd,0x3e,0x22,0xca,0x3b,0x7f,0x31,0x7a,0xd,
+0x24,0x7e,0x35,0x28,0x7a,0x35,0x2a,0x7e,0xd, 0x24,0x7f,0x13,0x12,0x9f,0xd4,0x30,
+0x3, 0x15,0x7e,0x35,0x28,0x7a,0x35,0x2a,0x12,0xa5,0x89,0x7e,0xd, 0x24,0x2d,0x15,
+0x7f,0x13,0x2d,0x35,0x12,0xa0,0xa1,0xda,0x3b,0x22,0x7e,0x37,0x24,0x1b,0x1e,0x34,
+0x7a,0x35,0x28,0xd2,0x3, 0x7e,0x8, 0x5, 0xc, 0x7e,0x18,0x4, 0x0, 0x12,0xa1,0xaa,
+0x7e,0x37,0x22,0xa, 0xe, 0x34,0x7a,0x35,0x28,0xc2,0x3, 0x7e,0x8, 0x5, 0x92,0x7e,
+0x18,0x4, 0x86,0x12,0xa1,0xaa,0x12,0xa2,0x1d,0x2, 0xa2,0xc, 0xe4,0x7a,0xb3,0x40,
+0x40,0x7e,0xb3,0x22,0x19,0x60,0x5, 0xe4,0x7a,0xb3,0x40,0x40,0x22,0xca,0x3b,0x7e,
+0xf3,0x24,0x3a,0x7e,0xe3,0x24,0x3b,0x7e,0xd3,0x24,0x3c,0x6c,0xcc,0x80,0x13,0x7c,
+0x7c,0xac,0x7f,0x3e,0x34,0x7e,0xf, 0x1b,0xd6,0x2d,0x13,0x7c,0xbd,0x12,0xa2,0x49,
+0xb, 0xc0,0xbc,0xec,0x38,0xe9,0xda,0x3b,0x22,0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f,
+0x70,0xc2,0x3, 0x6c,0xdd,0x6d,0xdd,0x7e,0x34,0x2c,0x35,0x7e,0x24,0x0, 0xff,0x7e,
+0x14,0x31,0xbb,0x74,0xc, 0x12,0x27,0xbb,0x6d,0x11,0x7e,0x4, 0x7f,0xff,0x6c,0xee,
+0x80,0x16,0x12,0xa3,0x57,0x12,0xa3,0x6b,0x7d,0xc3,0xbd,0xdc,0x50,0x2, 0x7d,0xdc,
+0xbd,0xc, 0x28,0x2, 0x7d,0xc, 0xb, 0xe0,0xbc,0xfe,0x38,0xe6,0xbe,0xd4,0x0, 0x1e,
+0x58,0xa, 0x7e,0xb3,0x22,0x5, 0x70,0x4, 0x6d,0x33,0x61,0x52,0xbe,0xd4,0x4, 0xb0,
+0x8, 0x2, 0xd2,0x3, 0x6c,0xee,0x74,0x4, 0xac,0xbe,0x49,0x45,0x31,0xbb,0xbd,0x4d,
+0x58,0x6, 0x49,0xd5,0x31,0xbd,0x80,0x7, 0xb, 0xe0,0xbe,0xe0,0x3, 0x40,0xe7,0xbe,
+0xe0,0x3, 0x78,0x4, 0x6d,0x33,0x61,0x52,0xbd,0xd, 0x8, 0x5, 0x30,0x3, 0x2, 0x7d,
+0xd0,0x9f,0x55,0x6c,0xee,0x80,0xe, 0x12,0xa3,0x57,0x12,0xa3,0x6b,0x1a,0x26,0x1a,
+0x24,0x2f,0x51,0xb, 0xe0,0xbc,0xfe,0x38,0xee,0xa, 0x1f,0x12,0xa3,0x5e,0x7d,0x13,
+0x9f,0x55,0x6c,0xee,0x80,0x1f,0x12,0xa3,0x57,0x2d,0x35,0xb, 0x1a,0x90,0x7d,0x39,
+0x12,0x29,0xb4,0x7d,0xc3,0xbd,0x1c,0x28,0xa, 0x7d,0x39,0x1a,0x26,0x1a,0x24,0x2f,
+0x51,0xb, 0xd0,0xb, 0xe0,0xbc,0xfe,0x38,0xdd,0x6d,0x11,0xbe,0xd0,0x0, 0x28,0x7,
+0xa, 0x1d,0x12,0xa3,0x5e,0x7d,0x13,0xbd,0x1d,0x8, 0x4, 0x7d,0x1d,0x80,0xa, 0x6d,
+0x0, 0x9d,0xd, 0xbd,0x1, 0x8, 0x2, 0x7d,0x10,0x6c,0xee,0x80,0xf, 0x12,0xa3,0x57,
+0x2d,0x35,0xb, 0x1a,0x0, 0x9d,0x1, 0x1b,0x1a,0x0, 0xb, 0xe0,0xbc,0xfe,0x38,0xed,
+0x7d,0x31,0xda,0x79,0xda,0xd8,0x22,0x74,0x2, 0xac,0xbe,0x7f,0x17,0x22,0x6d,0x0,
+0x7f,0x15,0x2, 0x27,0x66,0x74,0x2, 0xac,0xbe,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0x30,
+0x2, 0x29,0xb4,0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f,0x60,0x6c,0xdd,0x6d,0xff,0x7d,
+0xef,0x9f,0x44,0x7f,0x14,0x6c,0xee,0x80,0xe, 0x12,0xa3,0xfe,0xb, 0xa, 0x10,0x1a,
+0x2, 0x1a,0x0, 0x2f,0x10,0xb, 0xe0,0xbc,0xfe,0x38,0xee,0xa, 0x1f,0x12,0xa4,0x7,
+0x7f,0x14,0x6c,0xee,0x80,0x16,0x12,0xa3,0xfe,0xb, 0xa, 0xb0,0xbd,0xeb,0x8, 0xa,
+0x7d,0x1b,0x1a,0x2, 0x1a,0x0, 0x2f,0x10,0xb, 0xd0,0xb, 0xe0,0xbc,0xfe,0x38,0xe6,
+0x6d,0xee,0xbe,0xd0,0x0, 0x28,0x5, 0xa, 0x1d,0x12,0xa4,0x7, 0x6c,0xee,0x80,0xd,
+0x12,0xa3,0xfe,0xb, 0xa, 0x30,0x9d,0x3e,0x1b,0xa, 0x30,0xb, 0xe0,0xbc,0xfe,0x38,
+0xef,0x6c,0xee,0x80,0xe, 0x12,0xa3,0x65,0xbd,0x3f,0x8, 0x5, 0x12,0xa3,0x65,0x7d,
+0xf3,0xb, 0xe0,0xbc,0xfe,0x38,0xee,0x7d,0x3f,0xda,0x79,0xda,0xd8,0x22,0x74,0x2,
+0xac,0xbe,0x7f,0x6, 0x2d,0x15,0x22,0x6d,0x0, 0x12,0x27,0x66,0x7d,0xe3,0x22,0xca,
+0xf8,0x7f,0x71,0x6d,0xdd,0x6c,0xaa,0x7e,0xf0,0x7f,0x6d,0x44,0x80,0x1e,0x7d,0xc4,
+0x3e,0xc4,0x7f,0x17,0x2d,0x3c,0x12,0xa3,0x6d,0xbd,0x3d,0x48,0xd, 0x7d,0x34,0x3e,
+0x34,0x2d,0x3f,0x7d,0x2e,0x12,0xa3,0x6d,0x7d,0xd3,0xb, 0x44,0x7e,0xc5,0x33,0xbd,
+0xc4,0x38,0xdb,0x80,0x7, 0xb, 0xa0,0xbe,0xa0,0x8, 0x50,0x11,0x7c,0xba,0x7d,0x3d,
+0x60,0x5, 0xe, 0x34,0x14,0x78,0xfb,0xa, 0xcf,0xbd,0x3c,0x18,0xe8,0x7f,0x10,0x2e,
+0x35,0x33,0x7a,0x1b,0xa0,0x6d,0x44,0x80,0x21,0x7d,0x54,0x3e,0x54,0x7f,0x17,0x2d,
+0x35,0xb, 0x1a,0x30,0x7f,0x60,0x2e,0xd5,0x33,0x7e,0x6b,0xb0,0x60,0x5, 0xe, 0x34,
+0x14,0x78,0xfb,0x7c,0xb7,0x12,0xa7,0x41,0xb, 0x44,0x7e,0x55,0x33,0xbd,0x54,0x38,
+0xd8,0xda,0xf8,0x22,0x90,0x60,0x9b,0xe4,0x93,0xa, 0xb, 0x7e,0x73,0x24,0x3d,0xa,
+0x17,0x2d,0x10,0x7e,0xa3,0x24,0x3a,0xa, 0x3a,0xad,0x13,0x7d,0x21,0x6c,0x33,0x80,
+0x18,0xa, 0x3, 0x2d,0x2, 0x12,0xa7,0x49,0x7e,0x90,0x2, 0xac,0x93,0x49,0xf4,0x1b,
+0xda,0x9d,0xf, 0x59,0x4, 0x31,0xbb,0xb, 0x30,0xbc,0xa3,0x38,0xe4,0x7a,0x35,0x33,
+0x7e,0xf, 0x3e,0xae,0x7e,0x18,0x31,0xbb,0x2, 0xa4,0xf, 0xca,0x79,0x7e,0xe3,0x24,
+0x3a,0x7e,0x73,0x3e,0x42,0x4c,0x77,0x78,0x2, 0xa1,0x86,0x7e,0xa4,0x31,0xc9,0x1e,
+0xa4,0x3e,0xa4,0x12,0xa7,0x55,0x7d,0xba,0x7a,0xb7,0x31,0xc3,0x12,0xa5,0xa2,0x90,
+0x60,0x99,0x93,0xa, 0x3b,0x7e,0x53,0x24,0x39,0xa, 0x25,0x2d,0x23,0xa, 0x3e,0xad,
+0x32,0x7d,0xb3,0x3e,0xb4,0x7e,0x1f,0x3f,0xdf,0x2d,0x3b,0x7d,0xb3,0x7a,0xb7,0x31,
+0xbf,0x7e,0xb4,0x0, 0x20,0x7a,0xb7,0x31,0xc5,0x7e,0x8, 0x31,0xbb,0x12,0x18,0x0,
+0x6c,0xff,0x80,0x19,0x7c,0x3f,0xac,0x3e,0x3e,0x14,0x2d,0x1a,0x6d,0x0, 0x7c,0xbe,
+0x12,0xa3,0x73,0x74,0x2, 0xac,0xbf,0x59,0x35,0x32,0xa1,0xb, 0xf0,0x7e,0x73,0x3e,
+0x42,0xbc,0x7f,0x38,0xdf,0x6c,0xff,0x80,0x25,0x90,0x61,0xdb,0xe4,0x93,0xbc,0xbf,
+0x28,0x24,0xa, 0x3f,0x9, 0xa3,0x3e,0x45,0xbc,0xab,0x50,0x10,0x7e,0x70,0x2, 0xac,
+0x7f,0x49,0x33,0x32,0xa1,0x74,0xc, 0xa4,0x59,0x35,0x3e,0x51,0xb, 0xf0,0x7e,0x73,
+0x3e,0x42,0xbc,0x7f,0x38,0xd3,0xda,0x79,0x22,0x7e,0xa3,0x24,0x40,0x74,0x2, 0xa4,
+0x22,0x7e,0xf4,0x7f,0xff,0x9f,0x44,0xe4,0x22,0x74,0x2, 0xac,0xbc,0x7f,0x16,0x2d,
+0x35,0x22,0xe4,0x7a,0xb3,0x31,0xbd,0x7a,0xb3,0x31,0xbe,0x22,0x7a,0xb3,0x31,0xbb,
+0x7e,0x53,0x24,0x3a,0x7a,0x53,0x31,0xbc,0x7a,0x37,0x31,0xc3,0x12,0xa5,0xa2,0x7e,
+0x34,0x80,0x0, 0x7a,0x37,0x31,0xbf,0x7e,0x34,0x0, 0x20,0x12,0xa7,0x36,0x2, 0x18,
+0x0, 0x12,0xa7,0x16,0x7e,0x34,0x13,0x1a,0x7e,0xb3,0x24,0x39,0x12,0xa5,0xac,0x12,
+0xa5,0xed,0x7a,0x37,0x3f,0xdb,0x74,0x1, 0x7a,0xb3,0x1f,0x5d,0x22,0x6d,0x33,0x90,
+0x60,0x99,0xe4,0x93,0xbe,0xb0,0x0, 0x28,0x5, 0x12,0xa6,0x7f,0x80,0xd, 0x90,0x60,
+0x9a,0xe4,0x93,0xbe,0xb0,0x0, 0x28,0x3, 0x12,0xc6,0x10,0x6d,0x22,0x7e,0x33,0x24,
+0xfd,0x12,0xa6,0x23,0x74,0x6, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,
+0x78,0xf4,0x22,0xa, 0x13,0x6d,0x0, 0x2, 0x26,0xf9,0x7f,0x71,0x7f,0x60,0x7e,0x35,
+0x2f,0xbe,0x34,0x0, 0x0, 0x38,0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x2f,0x7e,0x35,
+0x31,0xbe,0x34,0x0, 0x0, 0x38,0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x31,0xb, 0x6a,
+0x30,0x9e,0x35,0x33,0x6d,0x22,0x7e,0x33,0x3f,0x7a,0x12,0xa6,0x23,0x7e,0x15,0x2f,
+0x12,0x27,0x13,0x1b,0x6a,0x30,0xb, 0x7a,0x30,0x9e,0x35,0x35,0x6d,0x22,0x7e,0x33,
+0x3f,0x7b,0x12,0xa6,0x23,0x7e,0x15,0x31,0x12,0x27,0x13,0x1b,0x7a,0x30,0x22,0xca,
+0xf8,0x6d,0x44,0x7e,0xf3,0x24,0x3a,0x90,0x60,0x9b,0xe4,0x93,0xa, 0xfb,0x7e,0xb3,
+0x24,0x39,0xa, 0xeb,0x2d,0xef,0xa, 0xff,0xad,0xfe,0xa, 0xef,0x2d,0xef,0x90,0x60,
+0x9c,0xe4,0x93,0xb4,0xff,0x31,0x7e,0x8, 0x1b,0xda,0x6c,0xaa,0x80,0x23,0xa, 0xda,
+0x2d,0xdf,0x3e,0xd4,0x7e,0x1f,0x3f,0xdf,0x2d,0x3d,0xb, 0x1a,0xd0,0x7e,0x50,0x2,
+0xac,0x5a,0x7f,0x50,0x2d,0xb2,0xb, 0x5a,0x30,0x9d,0x3d,0x59,0x32,0x1c,0x22,0xb,
+0xa0,0xbc,0xfa,0x38,0xd9,0x80,0xa, 0x7d,0x5e,0x3e,0x54,0x7e,0xf, 0x3f,0xdf,0x2d,
+0x15,0x6c,0xaa,0x80,0x28,0xa, 0xea,0x2d,0xef,0x3e,0xe4,0x7e,0x1f,0x3f,0xdf,0x2d,
+0x3e,0xb, 0x1a,0xe0,0x7e,0x70,0x2, 0xac,0x7a,0x2d,0x31,0x7d,0x20,0xb, 0x1a,0xd0,
+0x12,0xa7,0x2f,0x7d,0xc3,0xbd,0x4c,0x58,0x2, 0x7d,0x4c,0xb, 0xa0,0xbc,0xfa,0x38,
+0xd4,0x7d,0x34,0xda,0xf8,0x22,0xa9,0xd1,0xcb,0x74,0x1, 0x2, 0x0, 0xe, 0x7c,0xab,
+0x12,0xa7,0x16,0xd2,0x16,0x7c,0xba,0x12,0xab,0xfc,0xc2,0x16,0x22,0x7d,0x43,0x7d,
+0x3e,0x9d,0x3d,0x2, 0x29,0xb4,0x7a,0x37,0x31,0xc5,0x7e,0x8, 0x31,0xbb,0x22,0xa,
+0x4a,0x7f,0x10,0x2d,0x34,0x7a,0x1b,0xb0,0x22,0x3e,0x4, 0x7e,0x7f,0x3f,0xdf,0x2d,
+0xf0,0xb, 0x7a,0x0, 0x22,0x7a,0x73,0x31,0xbb,0x7e,0x73,0x24,0x3a,0x7a,0x73,0x31,
+0xbc,0x22,0xd2,0xc9,0x75,0xf2,0x30,0x75,0xf3,0x80,0x75,0xf4,0xc, 0x75,0xf5,0x1,
+0x6c,0xaa,0xe5,0xf5,0x54,0x80,0xb4,0x80,0xf9,0xe5,0xf6,0x12,0xa7,0x3f,0xb, 0xa0,
+0xbe,0xa0,0xd, 0x40,0xed,0xc2,0xc9,0x22,0x7e,0xb3,0x24,0xfb,0xb4,0x1, 0x43,0x12,
+0xa7,0xdc,0x7e,0x1f,0x3f,0xdf,0x7a,0x37,0x31,0xc3,0x7e,0x34,0x13,0x1a,0x7a,0x37,
+0x31,0xbf,0x7e,0x73,0x24,0x39,0x12,0xa7,0x55,0xe4,0x7a,0xb3,0x31,0xbe,0x7e,0x34,
+0x0, 0x20,0x7a,0x37,0x31,0xc5,0x12,0xa7,0xd3,0x12,0x18,0x0, 0x7e,0x34,0x13,0x1a,
+0x7a,0x37,0x31,0xc3,0x74,0x6, 0x12,0xa7,0xd3,0x7e,0x73,0x3f,0x3f,0xa, 0x37,0x2,
+0x18,0xcb,0x22,0x7a,0xb3,0x31,0xbd,0x7e,0x8, 0x31,0xbb,0x22,0xa9,0xd1,0xcb,0xe4,
+0x2, 0x0, 0xe, 0x12,0xa7,0xf7,0x7e,0x14,0x62,0x1d,0x12,0x6f,0xe6,0xbd,0x32,0x28,
+0x3, 0xd2,0x13,0x22,0xc2,0x13,0x22,0x6d,0x11,0x7e,0x73,0x24,0x40,0xa, 0x7, 0x7e,
+0x73,0x24,0x3f,0xa, 0x57,0x2d,0x50,0x7c,0xab,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x10,
+0x2, 0xac,0x1a,0x2e,0x4, 0x7, 0x2c,0x7e,0x90,0x4, 0xac,0x9a,0x2e,0x44,0x7, 0x2c,
+0x6c,0xaa,0x80,0x3b,0x12,0xa8,0x6a,0x2d,0x24,0xb, 0x28,0x20,0x2d,0x30,0xb, 0x38,
+0x30,0x12,0x97,0x80,0xbd,0x1f,0x50,0x2, 0x7d,0x1f,0x12,0xa8,0x6a,0x2d,0x20,0xb,
+0x28,0x20,0xbe,0x24,0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0x7d,0xe3,0x2d,0xe4,
+0xb, 0xe8,0xe0,0xbe,0xe4,0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0xb, 0xa0,0x7e,
+0xb3,0x24,0x40,0xbc,0xba,0x38,0xbd,0x7d,0x31,0x22,0x7e,0x70,0x2, 0xac,0x7a,0x7d,
+0x23,0x22,0x6c,0xaa,0x80,0x26,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x6, 0x18,0x49,
+0x32,0x4, 0x0, 0x2d,0x31,0x59,0x32,0x6, 0x18,0x30,0x1, 0xe, 0x49,0x12,0x4, 0x86,
+0x49,0x32,0x6, 0x9e,0x2d,0x31,0x59,0x32,0x6, 0x9e,0xb, 0xa0,0x7e,0xb3,0x24,0x40,
+0xa, 0x3b,0x7e,0xb3,0x24,0x3f,0xa, 0x2b,0x2d,0x23,0xa, 0x3a,0xbd,0x32,0x48,0xc6,
+0x22,0x74,0x2, 0x7a,0xb3,0x0, 0x65,0x74,0x1, 0x7a,0xb3,0x22,0x1d,0x2, 0x3f,0xe7,
+0xd2,0x3, 0x6c,0xaa,0x6c,0x77,0x80,0x15,0x7c,0x67,0x7e,0x50,0x2, 0xac,0x56,0x49,
+0x22,0x5, 0x92,0xbe,0x24,0xfe,0x70,0x58,0x2, 0xb, 0xa0,0xb, 0x70,0x7e,0xb3,0x24,
+0x3a,0xbc,0xb7,0x38,0xe3,0xa, 0x2b,0x1e,0x24,0x1e,0x24,0xa, 0x3a,0xbd,0x32,0x8,
+0x2, 0xc2,0x3, 0xa2,0x3, 0x22,0x7e,0x63,0x24,0x3b,0x7e,0xa3,0x24,0x3c,0x7e,0x70,
+0x1, 0x80,0x29,0xa, 0x17,0x7e,0xb3,0x24,0x3a,0xa, 0x2b,0x2d,0x21,0x3e,0x24,0x49,
+0x12,0x5, 0xc, 0x7e,0xf4,0x61,0x69,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x20,0x6e,0x24,
+0xff,0xff,0xb, 0x24,0xbd,0x12,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x16,0x1b,0x14,
+0xa, 0x27,0xbd,0x21,0x48,0xcd,0x7e,0x70,0x2, 0x80,0x20,0x7e,0x50,0x2, 0xac,0x57,
+0x49,0x12,0x5, 0xc, 0x7e,0xf4,0x61,0x6b,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x0, 0x6d,
+0x22,0x9d,0x20,0xbd,0x12,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x1a,0x1b,0x15,0xa,
+0x27,0xbd,0x21,0x48,0xd6,0xc3,0x22,0x7e,0xb3,0x3e,0x44,0xb4,0x1, 0x7, 0x74,0x2,
+0x7a,0xb3,0x3e,0x38,0x22,0x7e,0xb3,0x3e,0xaa,0x4, 0x7a,0xb3,0x3e,0xaa,0x7e,0xb3,
+0x3e,0x38,0xb4,0x2, 0x2f,0x7e,0xb3,0x3e,0xa9,0x4, 0x7a,0xb3,0x3e,0xa9,0x7e,0x34,
+0x61,0xe8,0x12,0x2d,0x68,0xbe,0x37,0x3f,0xdb,0x50,0x9, 0x7e,0xb3,0x3e,0xa9,0x4,
+0x7a,0xb3,0x3e,0xa9,0x7e,0xb3,0x3e,0xa9,0xb4,0x1, 0x6, 0x74,0x1, 0x7a,0xb3,0x3e,
+0xaa,0x12,0x46,0xa3,0x7e,0x73,0x3e,0xa9,0xbe,0x70,0x3, 0x40,0x12,0x74,0x1, 0x7a,
+0xb3,0x3e,0x44,0x74,0x2, 0x7a,0xb3,0x3e,0x38,0x12,0xa9,0xe6,0x12,0xa9,0xdc,0x7e,
+0x73,0x3e,0xaa,0xbe,0x70,0xa, 0x28,0x3, 0x2, 0xa9,0xdc,0x22,0xe4,0x7a,0xb3,0x3e,
+0xaa,0x7a,0xb3,0x3e,0xa9,0x22,0xe4,0x7a,0xb3,0x3e,0x36,0x6c,0xaa,0x80,0xd, 0x6d,
+0x44,0x7e,0x70,0xc, 0xac,0x7a,0x59,0x43,0x3e,0x4d,0xb, 0xa0,0x12,0xaa,0x7, 0x38,
+0xee,0xe4,0x7a,0xb3,0x3e,0x37,0x22,0x90,0x61,0xdb,0xe4,0x93,0xbc,0xba,0x22,0x7d,
+0x23,0x7e,0x14,0x61,0xde,0x12,0x8b,0x50,0x7e,0x14,0x0, 0x5, 0xad,0x13,0x1e,0x14,
+0xbd,0x12,0x50,0xd, 0x7e,0x33,0x3e,0xab,0xbe,0x30,0x8, 0x50,0x45,0x74,0x8, 0x80,
+0x3d,0x7d,0x13,0x3e,0x14,0xbd,0x12,0x50,0xd, 0x7e,0x33,0x3e,0xab,0xbe,0x30,0x6,
+0x50,0x30,0x74,0x6, 0x80,0x28,0x7e,0x14,0x0, 0x3, 0xad,0x13,0x1e,0x14,0xbd,0x12,
+0x50,0xd, 0x7e,0x33,0x3e,0xab,0xbe,0x30,0x4, 0x50,0x17,0x74,0x4, 0x80,0xf, 0xbd,
+0x32,0x50,0xf, 0x7e,0x73,0x3e,0xab,0xbe,0x70,0x2, 0x50,0x6, 0x74,0x2, 0x7a,0xb3,
+0x3e,0xab,0x7e,0xb3,0x3e,0xab,0xbe,0xb0,0x0, 0x28,0x1b,0x14,0x7a,0xb3,0x3e,0xab,
+0x74,0x1, 0x7a,0xb3,0x1f,0x5e,0x90,0x62,0x13,0xe4,0x93,0xbe,0xb3,0x3e,0xab,0x50,
+0x5, 0xe4,0x7a,0xb3,0x1f,0x5d,0x22,0x7c,0x6b,0x7e,0x44,0xff,0xff,0x6c,0x55,0x80,
+0x1c,0x12,0xab,0x0, 0x68,0x15,0x7e,0x10,0xc, 0xac,0x15,0x49,0x10,0x3e,0x51,0x49,
+0xf0,0x3e,0x4d,0xbd,0xf1,0x50,0x4, 0x59,0x10,0x3e,0x4d,0xb, 0x50,0xbc,0x65,0x50,
+0xe0,0x6c,0xaa,0x6c,0x55,0x80,0x2c,0x12,0xab,0x0, 0x78,0x14,0xa, 0x15,0xb, 0x14,
+0x7c,0x73,0xbc,0x67,0x50,0x1b,0xa, 0x16,0xb, 0x14,0x7c,0x43,0x9c,0x74,0x80,0x11,
+0x7e,0x10,0xc, 0xac,0x15,0x49,0x10,0x3e,0x4d,0xbd,0x14,0x50,0x4, 0x7d,0x41,0x7c,
+0xa5,0xb, 0x50,0xbc,0x65,0x50,0xd0,0x4d,0x44,0x78,0x2, 0x7c,0xa7,0x7c,0xba,0x22,
+0x7e,0x30,0x5, 0xac,0x35,0x9, 0x41,0x1f,0xa4,0xbe,0x43,0x24,0xed,0x22,0x7e,0x8,
+0x3e,0x49,0x7e,0x34,0x0, 0x60,0xe4,0x12,0x29,0x72,0x6c,0xaa,0x7e,0x44,0xff,0xff,
+0x7e,0x70,0xc, 0xac,0x7a,0x59,0x43,0x3e,0x4b,0x59,0x43,0x3e,0x53,0xb, 0xa0,0xbe,
+0xa0,0x8, 0x40,0xe8,0x7e,0x8, 0x3e,0x37,0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x29,0x72,
+0x12,0xab,0xe, 0x74,0x1, 0x7a,0xb3,0x3e,0x35,0x22,0x7e,0xa3,0x25,0x48,0xbc,0xab,
+0x68,0x6, 0x7a,0xb3,0x25,0x48,0xd2,0xc, 0x30,0xc, 0x6, 0x12,0xab,0x62,0x2, 0x0,
+0xa, 0x22,0xc2,0xc, 0x7e,0x8, 0x24,0x39,0x12,0x11,0x1d,0x7e,0x8, 0x24,0x39,0xe4,
+0x22,0x7c,0xab,0x6d,0x44,0x80,0x33,0x4c,0xaa,0x68,0x16,0x12,0xab,0xbc,0x7e,0x6b,
+0xb0,0x60,0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x7d,0xf4,0x12,0xab,0xb2,0x2d,0xfe,0x80,
+0x14,0x12,0xab,0xbc,0x7e,0x6b,0xb0,0x60,0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x7d,0xf4,
+0x12,0xab,0xb2,0x9d,0xfe,0x1b,0x6a,0xf0,0xb, 0x44,0x7e,0xf5,0x29,0xbd,0xf4,0x38,
+0xc6,0x22,0x3e,0xf4,0x7f,0x60,0x2d,0xdf,0xb, 0x6a,0xf0,0x22,0x7f,0x71,0x2d,0xf4,
+0x7e,0x7b,0xb0,0x1a,0xeb,0x7f,0x61,0x2e,0xd5,0x29,0x22,0x7c,0x7b,0x90,0x60,0x9b,
+0xe4,0x93,0xa, 0x1b,0x7e,0x63,0x24,0x3d,0xa, 0x6, 0x2d,0x1, 0x7e,0x63,0x24,0x3a,
+0xa, 0x16,0xad,0x10,0x7d,0x21,0x12,0xac,0x7a,0xa, 0x26,0x7a,0x25,0x29,0x74,0x25,
+0xac,0x7b,0x2e,0x34,0x3e,0xb2,0x6d,0x22,0xe4,0x2, 0xab,0x71,0x7c,0x2b,0x7e,0xb3,
+0x2b,0xfd,0xbc,0x2b,0x68,0x55,0x12,0xac,0x5c,0x7c,0x3b,0x7c,0xb2,0x12,0xac,0x5c,
+0x7c,0xab,0xbe,0x30,0xff,0x68,0x44,0xbe,0xa0,0xff,0x68,0x3f,0x7e,0x70,0x4, 0xac,
+0x73,0xa, 0x2a,0x2d,0x32,0x2e,0x34,0x29,0xa4,0x12,0x57,0xbb,0xbe,0xb0,0x2, 0x38,
+0x2a,0xa, 0x2b,0x7e,0x34,0x2, 0x1, 0xad,0x32,0x2e,0x34,0x25,0xfa,0x6d,0x22,0x30,
+0x16,0x3, 0x2, 0xab,0xcb,0x7e,0xb3,0x24,0xfb,0xb4,0x1, 0xf, 0x12,0x5c,0x50,0x7a,
+0x55,0x29,0x7e,0x8, 0x13,0x1a,0x74,0x1, 0x2, 0xab,0x71,0x22,0x7c,0xab,0x6c,0x77,
+0x7e,0x50,0x5, 0xac,0x57,0x9, 0x62,0x1f,0xa4,0xbc,0x6a,0x78,0x3, 0x7c,0xb7,0x22,
+0xb, 0x70,0xbe,0x70,0x4, 0x40,0xe9,0x74,0xff,0x22,0x3e,0x24,0x7e,0xf, 0x3f,0xdf,
+0x2d,0x12,0x22,0x7e,0xa3,0x24,0x3a,0xa, 0x3a,0x3e,0x34,0x7e,0x8, 0x1b,0xda,0xe4,
+0x12,0x29,0x72,0x90,0x60,0x9b,0x93,0xa, 0x3b,0x7e,0xb3,0x24,0x3d,0xa, 0x2b,0x2d,
+0x23,0xa, 0x3a,0xad,0x32,0x7d,0x43,0x6c,0x77,0x80,0x1d,0xa, 0x27,0x2d,0x24,0x12,
+0xac,0x7a,0xb, 0xa, 0x0, 0x7e,0x30,0x2, 0xac,0x37,0x2e,0x14,0x1b,0xda,0xb, 0x18,
+0x20,0x2d,0x20,0x1b,0x18,0x20,0xb, 0x70,0xbc,0xa7,0x38,0xdf,0x22,0xca,0x3b,0x7e,
+0xb3,0x24,0xed,0x7a,0xb3,0x2b,0xfd,0x7e,0xf3,0x25,0x48,0x12,0xac,0x5c,0x7c,0xdb,
+0xbe,0xd0,0xff,0x68,0x6f,0x6c,0xcc,0x74,0x5, 0xac,0xbc,0x9, 0xb5,0x1f,0xa4,0xf5,
+0x29,0x7e,0x73,0x24,0xed,0xbe,0x71,0x29,0x68,0x3c,0x7e,0x70,0x4, 0xac,0x7d,0xa,
+0x2c,0x2d,0x32,0x2e,0x34,0x29,0xa4,0x12,0x57,0xbb,0x7c,0xeb,0xbe,0xe0,0x2, 0x38,
+0x43,0xa, 0xe, 0x7e,0x14,0x2, 0x1, 0xad,0x10,0x2e,0x14,0x25,0xfa,0x6d,0x0, 0x7a,
+0xd, 0x2a,0x7e,0x70,0x25,0xac,0x7e,0x2e,0x34,0x3e,0xb2,0x6d,0x22,0x7a,0x1f,0x3e,
+0xae,0x7c,0xbc,0x12,0x5b,0xd, 0xb, 0xc0,0xbe,0xc0,0x4, 0x40,0xaa,0x7e,0x73,0x25,
+0x48,0xbc,0x7f,0x68,0x6, 0x7a,0xf3,0x25,0x48,0xd2,0xc, 0xd2,0x3, 0x7e,0xb3,0x2b,
+0xfd,0x12,0x43,0x81,0xda,0x3b,0x22,0x6d,0x33,0x7d,0x23,0x7d,0x3, 0x6c,0x33,0x80,
+0x45,0x6c,0x22,0x80,0x37,0x7e,0xb3,0x24,0x3a,0xac,0xb3,0xa, 0x42,0x2d,0x54,0x7d,
+0x45,0x3e,0x44,0x7e,0x7f,0x1b,0xd6,0x2d,0xf4,0xb, 0x7a,0x40,0xbe,0x44,0x0, 0x32,
+0x8, 0x8, 0xbe,0x44,0x2, 0x58,0x58,0x2, 0xb, 0x24,0xbe,0x44,0xff,0xce,0x58,0x8,
+0xbe,0x44,0xfd,0xa8,0x8, 0x2, 0xb, 0x4, 0xb, 0x34,0xb, 0x21,0x7e,0x93,0x24,0x3a,
+0xbc,0x92,0x38,0xc1,0xb, 0x31,0x7e,0xb3,0x24,0x39,0xbc,0xb3,0x38,0xb3,0x7e,0x54,
+0x0, 0x6, 0xad,0x53,0x7d,0x15,0x1e,0x14,0x1e,0x14,0x1e,0x14,0x12,0xf, 0xf7,0xbd,
+0x12,0x50,0x22,0xbd,0x30,0x28,0x1e,0xe4,0x7a,0xb3,0x40,0x2a,0x7e,0xb3,0x40,0x2b,
+0xbe,0xb0,0x5, 0x50,0x7, 0x4, 0x7a,0xb3,0x40,0x2b,0x80,0x3c,0xe4,0x7a,0xb3,0x40,
+0x2b,0x74,0x1, 0x80,0x2f,0xbd,0x10,0x50,0x22,0xbd,0x32,0x28,0x1e,0xe4,0x7a,0xb3,
+0x40,0x2b,0x7e,0xb3,0x40,0x2a,0xbe,0xb0,0x5, 0x50,0x7, 0x4, 0x7a,0xb3,0x40,0x2a,
+0x80,0x16,0xe4,0x7a,0xb3,0x40,0x2a,0x74,0x2, 0x80,0x9, 0xe4,0x7a,0xb3,0x40,0x2a,
+0x7a,0xb3,0x40,0x2b,0x7a,0xb3,0x40,0x2c,0x7e,0xb3,0x40,0x2c,0x22,0xe4,0x7a,0xb3,
+0x22,0x19,0x7a,0xb3,0x40,0x2d,0x22,0xca,0xd8,0xca,0x79,0xc2,0x3, 0x6c,0xdd,0x7e,
+0x57,0x22,0xa, 0x7d,0xf5,0x7e,0xe7,0x22,0x8, 0x7e,0x37,0x3, 0xfd,0x4d,0x33,0x68,
+0x4, 0x7d,0xf5,0xe, 0xf4,0x6c,0xff,0x7e,0xa3,0x24,0x3a,0x7c,0x8a,0x7e,0xb3,0x22,
+0x16,0x14,0x68,0x21,0x14,0x68,0x14,0x24,0xc2,0x68,0x8, 0x24,0xfb,0x68,0x16,0x24,
+0x45,0x78,0x10,0x7c,0xfa,0x7e,0x83,0x24,0x39,0x80,0xa, 0x7e,0x73,0x24,0x39,0x2c,
+0x87,0x80,0x2, 0x6c,0x88,0x6c,0x99,0x80,0xf, 0x7c,0xb9,0x12,0x68,0x6b,0xbe,0x34,
+0x2, 0x58,0x8, 0x2, 0xb, 0xd0,0xb, 0x90,0x7e,0x33,0x21,0xf5,0xbc,0x39,0x38,0xe9,
+0xbe,0xd0,0x3, 0x40,0x2, 0xe1,0xec,0x7e,0xa3,0x21,0xf6,0xbe,0xa0,0x0, 0x38,0xb,
+0xbe,0x30,0x0, 0x28,0x37,0x7e,0xb3,0x1f,0xf4,0x70,0x31,0x6c,0x99,0x80,0x29,0xa,
+0x29,0xa, 0x3f,0x2d,0x32,0x3e,0x34,0x49,0x23,0x5, 0x92,0xbd,0x2f,0x8, 0x17,0x49,
+0x3, 0x5, 0xc, 0xbd,0xe, 0x58,0xf, 0x6d,0x33,0x9d,0x3e,0x12,0x8c,0xa7,0xbd,0x3,
+0x8, 0x4, 0xd2,0x3, 0x80,0x6, 0xb, 0x90,0xbc,0x89,0x38,0xd3,0x6d,0xee,0x9e,0xe7,
+0x24,0x1b,0xbe,0xe7,0xa, 0x50,0x8, 0x2, 0xc2,0x3, 0x30,0x3, 0x20,0x7e,0xb3,0x40,
+0x2d,0x4, 0x7a,0xb3,0x40,0x2d,0x7e,0x23,0x40,0x2d,0xbe,0x20,0xa, 0x28,0x1d,0x74,
+0xa, 0x7a,0xb3,0x40,0x2d,0x74,0x1, 0x7a,0xb3,0x22,0x19,0x80,0xf, 0x7e,0x23,0x40,
+0x2d,0xbe,0x20,0x0, 0x28,0x6, 0x1e,0x20,0x7a,0x23,0x40,0x2d,0x6c,0xee,0xbe,0x30,
+0x0, 0x38,0x5, 0xbe,0xa0,0x0, 0x28,0x6d,0x7e,0xb3,0x22,0x18,0xb4,0x1, 0x9, 0x7e,
+0xb3,0x22,0x1b,0xbe,0xb0,0x1, 0x68,0x5d,0x7e,0xb3,0x22,0x19,0xb4,0x1, 0x56,0x6c,
+0x99,0x80,0x1d,0x7e,0x70,0x2, 0xac,0x79,0x9, 0xa3,0x20,0x6b,0x9, 0xd3,0x20,0x6c,
+0x7c,0xba,0x7c,0x7d,0x12,0xaf,0xf5,0x8, 0x5, 0x7e,0xe0,0x1, 0x80,0xa, 0xb, 0x90,
+0x7e,0xb3,0x21,0xf5,0xbc,0xb9,0x38,0xdb,0x6c,0x99,0x80,0x21,0x7e,0x70,0x2, 0xac,
+0x79,0x9, 0xa3,0x20,0xa7,0x9, 0xd3,0x20,0xa8,0x7c,0xba,0x7c,0x7d,0x12,0x4f,0x6f,
+0xbe,0x34,0xff,0x6a,0x58,0x5, 0x7e,0xe0,0x1, 0x80,0xa, 0xb, 0x90,0x7e,0xb3,0x21,
+0xf6,0xbc,0xb9,0x38,0xd7,0x6c,0x99,0x80,0x17,0xa, 0xe9,0xa, 0x5f,0x2d,0x5e,0x3e,
+0x54,0x49,0x55,0x5, 0x92,0xbd,0x5f,0x8, 0x5, 0x7e,0xe0,0x1, 0x80,0x6, 0xb, 0x90,
+0xbc,0x89,0x38,0xe5,0x4c,0xee,0x78,0x25,0x7e,0xb3,0x40,0x2e,0x4, 0x7a,0xb3,0x40,
+0x2e,0x7e,0x73,0x40,0x2e,0xbe,0x70,0x5, 0x28,0x22,0x74,0x5, 0x7a,0xb3,0x40,0x2e,
+0x7e,0xb3,0x22,0x19,0x60,0x2, 0xd2,0x15,0x12,0xae,0x1d,0x80,0xf, 0x7e,0x73,0x40,
+0x2e,0xbe,0x70,0x0, 0x28,0x6, 0x1e,0x70,0x7a,0x73,0x40,0x2e,0xda,0x79,0xda,0xd8,
+0x22,0x7c,0xba,0x7c,0x79,0x12,0x4f,0x6f,0xbe,0x34,0x0, 0x96,0x22,0xca,0x3b,0x7c,
+0xdb,0x75,0x41,0x0, 0x75,0x42,0x0, 0x7e,0xb3,0x24,0x3b,0xf5,0x47,0x7e,0xb3,0x24,
+0x3c,0xf5,0x48,0x75,0x49,0x28,0x75,0x52,0x6, 0x7e,0xb3,0x21,0xf5,0xf5,0x29,0xe4,
+0x7a,0xb3,0x2, 0x8b,0x7a,0xb3,0x2, 0x87,0x7a,0xb3,0x2, 0x88,0x7e,0x8, 0x2, 0x8d,
+0x90,0x60,0xa2,0x93,0xa, 0x3b,0xe4,0x12,0x29,0x72,0x12,0xb7,0x4f,0x7e,0x8, 0x2,
+0xad,0xe4,0x12,0x29,0x72,0x75,0x40,0x0, 0xe5,0x29,0xbe,0xb0,0x3, 0x28,0x21,0x7e,
+0x37,0x21,0xf9,0xbe,0x34,0x0, 0x1e,0x28,0x17,0x7e,0x73,0x23,0x88,0xbe,0x70,0x3,
+0x28,0xe, 0x7e,0xb3,0x3, 0xa9,0xb4,0x1, 0x5, 0x75,0x52,0x5, 0x80,0x42,0x80,0x3d,
+0x7e,0xb3,0x1f,0xf6,0xb4,0x1, 0x39,0x7e,0x73,0x1f,0xf5,0xbe,0x70,0x3, 0x40,0x30,
+0x7e,0x73,0x1f,0xcd,0x12,0x57,0x6e,0xbe,0x34,0x0, 0x3, 0x48,0x23,0x7e,0x73,0x1f,
+0xce,0xa, 0x27,0x7e,0x73,0x1f,0xcd,0x12,0x57,0x74,0xbe,0x34,0x0, 0x3, 0x48,0x10,
+0x7e,0x73,0x1f,0xce,0x12,0x57,0x6e,0xbe,0x34,0x0, 0x3, 0x48,0x3, 0x75,0x52,0x4,
+0x30,0x11,0xd, 0x7e,0x34,0x0, 0xfa,0x7a,0x35,0x3c,0x7e,0x34,0x1, 0x5e,0x80,0x7,
+0x7e,0x34,0x1, 0x5e,0x7a,0x35,0x3c,0x7a,0x35,0x3e,0x7e,0x37,0xa, 0x5a,0xbe,0x35,
+0x3e,0x48,0x9, 0x7e,0x37,0xa, 0x58,0xbe,0x35,0x3c,0x58,0x3, 0x75,0x40,0x1, 0xe5,
+0x29,0xbe,0xb0,0x2, 0x50,0x2, 0xc1,0x85,0x12,0xb7,0x63,0x6c,0xcc,0xc1,0x7d,0x74,
+0x2, 0xac,0xbc,0x9, 0x75,0x20,0x6b,0x7a,0x73,0x31,0xf7,0x9, 0xb5,0x20,0x6c,0xf5,
+0x24,0x4c,0xcc,0x68,0x8, 0xa, 0x3c,0x9, 0xb3,0x2, 0x8d,0x70,0xa, 0xa, 0x3c,0xb,
+0x34,0xa, 0x2c,0x19,0x72,0x2, 0x8d,0xe5,0x29,0x14,0xbc,0xbc,0x78,0x2, 0xc1,0x85,
+0xa, 0x5c,0xb, 0x54,0xf5,0x2a,0xc1,0x72,0x75,0x57,0x0, 0x7e,0x71,0x2a,0x12,0x7e,
+0x81,0x7a,0xa3,0x31,0xf8,0x9, 0xb3,0x20,0x6c,0xf5,0x25,0xa, 0x2a,0x7e,0x73,0x31,
+0xf7,0x12,0x57,0x74,0x7a,0x73,0x31,0xf9,0xe5,0x25,0xa, 0x2b,0xe5,0x24,0x12,0x7d,
+0xca,0x7c,0xb7,0xf5,0x26,0x7e,0x73,0x31,0xf9,0xbe,0x71,0x52,0x40,0x2, 0xc1,0x70,
+0xe5,0x52,0xbe,0xb1,0x26,0x38,0x2, 0xc1,0x70,0x12,0xb6,0xad,0x7e,0x63,0x31,0xf8,
+0x7e,0x51,0x25,0x12,0x66,0xbd,0x7a,0xb3,0x2, 0x8a,0x85,0x24,0x5f,0x7e,0xb3,0x31,
+0xf8,0xf5,0x60,0x85,0x25,0x61,0x7e,0x8, 0x0, 0x30,0x7e,0x18,0x0, 0x32,0x7e,0xb3,
+0x31,0xf7,0x12,0xb6,0xc9,0x75,0x41,0x0, 0x75,0x42,0x0, 0x75,0x2f,0x0, 0x12,0xb6,
+0xad,0x12,0x4f,0x6f,0x7a,0x35,0x34,0x7e,0xb3,0x31,0xf8,0x7e,0x71,0x25,0x12,0x4f,
+0x6f,0x7a,0x35,0x36,0x7e,0x35,0x34,0xbe,0x35,0x36,0x8, 0x5, 0x7e,0x35,0x36,0x80,
+0x3, 0x7e,0x35,0x34,0x7a,0x35,0x3a,0xe, 0x34,0x7a,0x35,0x38,0x7e,0xa3,0x31,0xf9,
+0xbe,0xa0,0x1, 0x38,0x11,0xe5,0x26,0xbe,0xb0,0x1, 0x38,0xa, 0x7c,0xbd,0x30,0xe1,
+0x5, 0x75,0x2f,0x1, 0xa1,0xe2,0xbe,0xa0,0x1, 0x38,0x9, 0xe5,0x26,0xbe,0xb0,0x1,
+0x38,0x2, 0xa1,0xe2,0xbe,0xa1,0x52,0x40,0x2, 0xa1,0xe2,0xe5,0x52,0xbe,0xb1,0x26,
+0x38,0x2, 0xa1,0xe2,0x7c,0xbd,0x20,0xe0,0x2, 0xa1,0xe2,0x6d,0x33,0x7a,0x35,0x58,
+0x75,0x5a,0x0, 0x7a,0x35,0x5b,0x75,0x5d,0x0, 0xc2,0x4, 0xc2,0x5, 0x7e,0x73,0x31,
+0xf8,0xbe,0x73,0x31,0xf7,0x28,0x8, 0x7e,0x63,0x31,0xf7,0x7c,0xe6,0x80,0x4, 0x7e,
+0xe3,0x31,0xf8,0xbe,0x73,0x31,0xf7,0x50,0x6, 0x7e,0xb3,0x31,0xf7,0x80,0x4, 0x7e,
+0xb3,0x31,0xf8,0xf5,0x27,0xe5,0x25,0xbe,0xb1,0x24,0x28,0x6, 0xe5,0x24,0x7c,0xfb,
+0x80,0x3, 0x7e,0xf1,0x25,0xe5,0x25,0xbe,0xb1,0x24,0x50,0x4, 0xe5,0x24,0x80,0x2,
+0xe5,0x25,0xf5,0x28,0x12,0x7d,0xd1,0xe5,0x27,0x58,0x6, 0xa, 0x5b,0xb, 0x54,0x80,
+0x0, 0xf5,0x53,0xbe,0xe0,0x0, 0x28,0x6, 0xa, 0x5e,0x1b,0x54,0x80,0x2, 0x7c,0xbe,
+0xf5,0x54,0x12,0x7e,0x8a,0xe5,0x28,0x58,0x6, 0xa, 0x5b,0xb, 0x54,0x80,0x0, 0xf5,
+0x55,0xbe,0xf0,0x0, 0x28,0x6, 0xa, 0x5f,0x1b,0x54,0x80,0x2, 0x7c,0xbf,0xf5,0x56,
+0x75,0x2b,0x0, 0x80,0x75,0xbe,0xc1,0x2b,0x68,0x6e,0xe5,0x2a,0xbe,0xb1,0x2b,0x68,
+0x67,0x7e,0x91,0x2b,0x74,0x2, 0xac,0x9b,0x9, 0xa4,0x20,0x6b,0xbe,0xa1,0x53,0x78,
+0x13,0xe5,0x27,0xa, 0x2b,0xb, 0x24,0xe5,0x53,0xa, 0x3b,0xbd,0x32,0x78,0x5, 0x85,
+0x27,0x53,0x80,0x14,0xbe,0xa1,0x54,0x78,0xf, 0xe5,0x54,0xa, 0x3b,0xb, 0x34,0xa,
+0x5e,0xbd,0x35,0x78,0x3, 0x7a,0xe1,0x54,0x9, 0xa4,0x20,0x6c,0xbe,0xa1,0x55,0x78,
+0x13,0xe5,0x28,0xa, 0x2b,0xb, 0x24,0xe5,0x55,0xa, 0x3b,0xbd,0x32,0x78,0x5, 0x85,
+0x28,0x55,0x80,0x14,0xbe,0xa1,0x56,0x78,0xf, 0xe5,0x56,0xa, 0x2b,0xb, 0x24,0xa,
+0x3f,0xbd,0x23,0x78,0x3, 0x7a,0xf1,0x56,0x5, 0x2b,0xe5,0x29,0xbe,0xb1,0x2b,0x38,
+0x84,0xe5,0x27,0xbc,0xbe,0x78,0x1d,0xd2,0x4, 0x4c,0xee,0x68,0x7, 0xe5,0x47,0x14,
+0xbc,0xbe,0x78,0x2, 0xd2,0x5, 0xbe,0xe0,0x0, 0x28,0x2, 0x1b,0xe0,0x12,0x7d,0xd1,
+0x58,0x2, 0x5, 0x27,0xe5,0x28,0xbc,0xbf,0x78,0x1d,0xd2,0x4, 0x4c,0xff,0x68,0x7,
+0xe5,0x48,0x14,0xbc,0xbf,0x78,0x2, 0xd2,0x5, 0xbe,0xf0,0x0, 0x28,0x2, 0x1b,0xf0,
+0x12,0x7e,0x8a,0x58,0x2, 0x5, 0x28,0x75,0x2d,0x0, 0x75,0x2e,0x0, 0x75,0x2c,0x0,
+0x80,0x16,0xe5,0x2c,0xa, 0x2b,0x9, 0x72,0x1f,0xcc,0xbe,0x71,0x53,0x38,0x7, 0xbe,
+0x71,0x54,0x40,0x2, 0x5, 0x2d,0x5, 0x2c,0x7e,0x73,0x1f,0xf5,0xbe,0x71,0x2c,0x38,
+0xe1,0x75,0x2c,0x0, 0x80,0x16,0xe5,0x2c,0xa, 0x2b,0x9, 0x72,0x1f,0xe0,0xbe,0x71,
+0x55,0x38,0x7, 0xbe,0x71,0x56,0x40,0x2, 0x5, 0x2e,0x5, 0x2c,0x7e,0x73,0x1f,0xf6,
+0xbe,0x71,0x2c,0x38,0xe1,0x7a,0xe1,0x43,0x80,0x57,0x7a,0xf1,0x44,0x80,0x49,0xe5,
+0x43,0x7e,0x71,0x44,0x12,0x4f,0x6f,0x7a,0x35,0x45,0xbe,0xe1,0x43,0x68,0x13,0xe5,
+0x27,0xbe,0xb1,0x43,0x68,0xc, 0xbe,0xf1,0x44,0x68,0x7, 0xe5,0x28,0xbe,0xb1,0x44,
+0x78,0xd, 0x7e,0x35,0x45,0x2e,0x35,0x58,0x7a,0x35,0x58,0x5, 0x5a,0x80,0x17,0x5,
+0x5d,0x7e,0x35,0x45,0x2e,0x35,0x5b,0x7a,0x35,0x5b,0x7e,0x35,0x32,0xbe,0x35,0x45,
+0x58,0x2, 0x5, 0x41,0x5, 0x42,0x5, 0x44,0xe5,0x28,0xbe,0xb1,0x44,0x50,0xb0,0x5,
+0x43,0xe5,0x27,0xbe,0xb1,0x43,0x50,0xa2,0xe5,0x27,0x7c,0x7f,0x12,0x4f,0x6f,0x7e,
+0x45,0x58,0x9d,0x43,0x7c,0xbe,0x7e,0x71,0x28,0x12,0x4f,0x6f,0x9d,0x43,0x7c,0x7f,
+0x12,0x4f,0x6f,0x9d,0x43,0xe5,0x27,0x7e,0x71,0x28,0x12,0x4f,0x6f,0x7d,0x23,0x7d,
+0x34,0x9d,0x32,0x7a,0x35,0x58,0x7e,0x35,0x36,0x2e,0x35,0x34,0x7a,0x35,0x38,0xe5,
+0x5a,0xbe,0xb0,0x4, 0x28,0x6, 0xe5,0x5a,0x24,0xfc,0xf5,0x5a,0x7e,0x35,0x58,0xbe,
+0x34,0x0, 0x0, 0x58,0x5, 0x6d,0x33,0x7a,0x35,0x58,0x75,0x49,0x22,0xe5,0x47,0x14,
+0xbe,0xb3,0x31,0xf7,0x68,0x12,0xbe,0xb3,0x31,0xf8,0x68,0xc, 0x7e,0xb3,0x31,0xf7,
+0x60,0x6, 0x7e,0xb3,0x31,0xf8,0x70,0xa, 0x12,0xb6,0x95,0x28,0x5a,0x75,0x49,0x2c,
+0x80,0x55,0x30,0x11,0x36,0x12,0x7e,0x79,0x38,0xd, 0xbc,0x7e,0x40,0x9, 0x12,0x7e,
+0x71,0x38,0x4, 0xbc,0x7f,0x50,0x12,0x12,0x7e,0x69,0x38,0x3b,0xbc,0x7e,0x40,0x37,
+0x12,0x7e,0x61,0x38,0x32,0xbc,0x7f,0x40,0x2e,0xe5,0x49,0xa, 0x3b,0x12,0xb7,0x5c,
+0x7c,0xb7,0x25,0x49,0xf5,0x49,0x75,0x57,0x1, 0x80,0x1c,0x7e,0x15,0x5b,0x1a,0x2,
+0x1a,0x0, 0x7e,0x35,0x58,0x1a,0x26,0x1a,0x24,0x2f,0x10,0xe5,0x49,0xa, 0x1b,0x6d,
+0x0, 0x12,0x26,0xf9,0x7a,0x1d,0x4a,0x7e,0x15,0x38,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,
+0x30,0x1a,0x26,0x1a,0x24,0x12,0x26,0xf9,0xe5,0x5d,0xa, 0xfb,0x6d,0xee,0xe5,0x5a,
+0xa, 0x1b,0x6d,0x0, 0x2f,0x7, 0x12,0x26,0xf9,0x7f,0x1, 0x7a,0xd, 0x4e,0x7e,0x1d,
+0x4a,0xbf,0x10,0x8, 0x3, 0x75,0x2f,0x2, 0x12,0x8a,0x35,0x50,0x2, 0xa1,0xe2,0xe5,
+0x40,0x60,0x2, 0xa1,0xe2,0x12,0xb6,0xbe,0x78,0x22,0x12,0xb6,0x95,0x28,0x1d,0xa,
+0x2e,0xe5,0x27,0x12,0xb6,0xb5,0x58,0x14,0xa, 0x2f,0xe5,0x28,0x12,0xb6,0xb5,0x58,
+0xb, 0x12,0xb6,0x88,0x7e,0x31,0x57,0x12,0xbf,0x85,0xf5,0x2f,0x12,0xb6,0xbe,0x8,
+0x35,0xe5,0x2f,0xb4,0x2, 0x30,0x12,0xb6,0xa5,0x28,0x2b,0x7e,0xb3,0x2, 0x8c,0x70,
+0x25,0xbe,0xa0,0x2, 0x28,0x20,0xbe,0xa0,0x3, 0x28,0x18,0x12,0xb6,0x9d,0x50,0x7,
+0xe5,0x26,0xbe,0xb0,0x3, 0x40,0xf, 0xbe,0xa0,0x4, 0x50,0x7, 0xe5,0x26,0xbe,0xb0,
+0x3, 0x40,0x3, 0x75,0x2f,0x0, 0x7e,0xb3,0x2, 0x8c,0x70,0x8, 0x12,0xb6,0x88,0x12,
+0x9e,0xee,0xf5,0x2f,0x7e,0xb3,0x31,0xf7,0x7e,0x71,0x25,0x12,0x9e,0xa0,0x58,0x42,
+0x7e,0xb3,0x31,0xf8,0x12,0x4f,0x6c,0xbe,0x34,0x0, 0x0, 0x58,0x35,0x12,0xb6,0xa5,
+0x28,0x30,0xe5,0x2f,0xbe,0xb0,0x1, 0x28,0x29,0x7e,0xb3,0x2, 0x8a,0xbe,0xb0,0x2,
+0x50,0x20,0xbe,0xa0,0x3, 0x28,0x18,0x12,0xb6,0x9d,0x50,0x7, 0xe5,0x26,0xbe,0xb0,
+0x3, 0x40,0xf, 0xbe,0xa0,0x4, 0x50,0x7, 0xe5,0x26,0xbe,0xb0,0x3, 0x40,0x3, 0x75,
+0x2f,0x0, 0x4c,0xdd,0x68,0x1f,0x12,0x8a,0x35,0x40,0x1a,0xe5,0x40,0x70,0x16,0x12,
+0xb6,0x88,0x7e,0x33,0x31,0xf7,0x7e,0x21,0x24,0x7e,0x13,0x31,0xf8,0x7e,0x1, 0x25,
+0x12,0xbc,0x1d,0xf5,0x2f,0xe5,0x2f,0xbe,0xb0,0x0, 0x28,0x64,0xe5,0x2f,0xa, 0x3b,
+0x2e,0x34,0x2, 0x86,0x7e,0x39,0xb0,0x4, 0x7a,0x39,0xb0,0xe5,0x2a,0xa, 0x3b,0x9,
+0xa3,0x2, 0x8d,0x4c,0xaa,0x78,0xc, 0xa, 0x2c,0x9, 0xb2,0x2, 0x8d,0x19,0xb3,0x2,
+0x8d,0x80,0x3d,0xa, 0x2c,0x9, 0xb2,0x2, 0x8d,0xf5,0x5e,0xbc,0xba,0x28,0x3, 0x7a,
+0xa1,0x5e,0x75,0x2b,0x0, 0x80,0x22,0x9, 0x33,0x2, 0x8d,0xe5,0x2b,0xa, 0x2b,0x9,
+0x22,0x2, 0x8d,0xbc,0x23,0x68,0xa, 0xa, 0xc, 0x9, 0x30,0x2, 0x8d,0xbc,0x23,0x78,
+0x6, 0xe5,0x5e,0x19,0xb2,0x2, 0x8d,0x5, 0x2b,0xe5,0x29,0xbe,0xb1,0x2b,0x38,0xd7,
+0x5, 0x2a,0xe5,0x29,0xbe,0xb1,0x2a,0x28,0x2, 0x21,0x28,0xb, 0xc0,0xe5,0x29,0xbc,
+0xbc,0x28,0x2, 0x1, 0xef,0xda,0x3b,0x22,0xe5,0x27,0x7c,0x7e,0x7e,0x61,0x28,0x7c,
+0x5f,0x7e,0x41,0x2f,0x22,0x7e,0x73,0x2, 0x8a,0xbe,0x70,0x5, 0x22,0x7e,0xa3,0x31,
+0xf9,0xbe,0xa0,0x3, 0x22,0x7e,0xa3,0x23,0x88,0xbe,0xa0,0x1, 0x22,0x7e,0xb3,0x31,
+0xf7,0x7e,0x71,0x24,0x22,0xa, 0x3b,0x9d,0x32,0xbe,0x34,0x0, 0x5, 0x22,0x7e,0xa1,
+0x2e,0xe5,0x2d,0xa4,0xbe,0x54,0x0, 0x1, 0x22,0x7c,0x9b,0x7f,0x71,0x7f,0x60,0x7e,
+0x34,0x2c,0x7, 0x7e,0x24,0x0, 0xff,0x7e,0x14,0x31,0xfa,0x74,0x2a,0x12,0x27,0xbb,
+0x7e,0x58,0x31,0xfa,0x7c,0xb9,0x7e,0x71,0x5f,0x12,0x4f,0x6f,0x7d,0x43,0xe5,0x60,
+0x7e,0x71,0x61,0x12,0x4f,0x6f,0x2d,0x34,0xe, 0x34,0x7f,0x5, 0x7e,0x50,0x7, 0xb,
+0xa, 0x50,0xbd,0x53,0x58,0x10,0x69,0x30,0x0, 0x2, 0x1b,0x6a,0x30,0x69,0x30,0x0,
+0x4, 0x1b,0x7a,0x30,0x80,0x8, 0x2e,0x14,0x0, 0x6, 0x1b,0x50,0x78,0xe1,0x12,0xb6,
+0x95,0x28,0x2b,0xb, 0x6a,0x20,0x7e,0x34,0x0, 0xd, 0xad,0x32,0x7e,0x24,0x0, 0x10,
+0x12,0x26,0xc7,0x1b,0x6a,0x30,0xb, 0x7a,0x30,0x1a,0x26,0x1a,0x24,0x7e,0x14,0x0,
+0xd, 0x12,0x27,0xa, 0x7e,0x8, 0x0, 0x10,0x12,0x27,0x66,0x1b,0x7a,0x30,0x22,0x90,
+0x60,0xa2,0x93,0xa, 0x3b,0x3e,0x34,0x22,0x7c,0x8b,0xa, 0x38,0x7e,0x24,0x0, 0x3,
+0x2, 0x26,0xc7,0x7e,0x73,0x23,0x88,0xbe,0x70,0x2, 0x38,0xe, 0x6c,0x77,0x80,0x2,
+0xb, 0x70,0x7e,0x63,0x1f,0xf5,0xbc,0x67,0x38,0xf6,0x22,0xca,0x3b,0x7c,0xf7,0x7c,
+0xab,0x6c,0x99,0x80,0x29,0xa, 0xf9,0x12,0x57,0xad,0x12,0xb7,0x58,0x7c,0x65,0x7a,
+0x61,0x30,0xa, 0xf8,0x7e,0xe4,0x0, 0x3, 0x8d,0xfe,0x7d,0x2f,0x12,0xb7,0xec,0x60,
+0x5, 0x3e,0x24,0x14,0x78,0xfb,0x7e,0x70,0x2, 0xac,0x67,0x12,0xd0,0x79,0xbc,0xf9,
+0x38,0xd3,0x6c,0x99,0x80,0x2f,0xa, 0x39,0x12,0xb7,0xf5,0xa, 0x78,0x7e,0x64,0x0,
+0xc, 0x8d,0x76,0x2e,0x74,0x0, 0x3, 0x7a,0xf1,0x30,0xa, 0x38,0x7e,0x24,0x0, 0xc,
+0x12,0x26,0xc7,0x12,0xb7,0xec,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb,0x7e,0x70,0x2,
+0xac,0x7f,0x12,0xd0,0x79,0xbc,0xa9,0x38,0xcd,0xda,0x3b,0x22,0x7c,0xb5,0xf5,0x2f,
+0x7e,0x24,0x0, 0x1, 0x22,0x2d,0x31,0x7d,0x20,0x7e,0x1b,0x80,0x22,0x6c,0xaa,0x12,
+0xd0,0xd0,0x29,0x81,0x0, 0x5, 0x7c,0x98,0x5e,0x90,0x1, 0x3e,0x90,0x7f,0x1, 0x2e,
+0x14,0x0, 0x5, 0x7c,0xb8,0x54,0xfd,0x4c,0xb9,0x7a,0xb, 0xb0,0x29,0xb1,0x0, 0x5,
+0x30,0xe0,0x16,0x30,0xe2,0x13,0xc4,0x23,0x54,0x1f,0xb4,0x1, 0xc, 0x7f,0x1, 0xb,
+0x16,0x7e,0xb, 0xb0,0x1e,0xb0,0x7a,0xb, 0xb0,0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xbf,
+0x22,0xca,0x3b,0x7f,0x40,0x7e,0xe3,0x21,0xf5,0x6c,0xdd,0x7e,0xc0,0x1, 0x80,0x1a,
+0xa, 0x3d,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0x60,0xa, 0x2c,0x7f,0x4, 0x2d,0x12,0x7e,
+0xb, 0x70,0xbc,0x76,0x40,0x2, 0x7c,0xdc,0xb, 0xc0,0xbc,0xec,0x38,0xe2,0xa, 0x3d,
+0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xd0,0x6c,0xff,0x7e,0xc0,0x1, 0x21,0xff,0x75,0x2c,
+0x0, 0x6d,0x33,0x7a,0x35,0x2d,0x7a,0x35,0x2f,0x9f,0x11,0x7a,0x1f,0x31,0xf8,0x7a,
+0x1d,0x24,0x7e,0x18,0x31,0xfc,0x7a,0x1d,0x28,0x74,0xff,0x7e,0x34,0x31,0xfd,0x7e,
+0x24,0x0, 0x0, 0x7a,0x1b,0xb0,0x7e,0x1d,0x28,0x7a,0x1b,0xb0,0xe4,0x7e,0x1d,0x28,
+0x39,0xb1,0x0, 0x3, 0x7e,0x1d,0x28,0x39,0xb1,0x0, 0x2, 0x7e,0x1d,0x28,0x12,0xbc,
+0xa, 0x44,0x1, 0x7a,0x1b,0xb0,0xe4,0x21,0x5d,0x7e,0xa3,0x31,0xf7,0x7e,0x70,0x2,
+0xac,0x7a,0x9, 0x93,0x20,0x6b,0x9, 0x83,0x20,0x6c,0xa, 0x5a,0x7f,0x14,0x2d,0x35,
+0x7e,0x1b,0x70,0xbc,0x7c,0x78,0x71,0x5, 0x2c,0x12,0xba,0xd, 0x7d,0x53,0x2e,0x55,
+0x2d,0x7a,0x55,0x2d,0x12,0x6e,0xa3,0xa, 0x39,0x6d,0x22,0x12,0x26,0xf9,0x12,0xba,
+0x25,0x12,0x6e,0xa3,0xa, 0x38,0x6d,0x22,0x12,0x26,0xf9,0x7f,0x1, 0x12,0xba,0x1c,
+0x12,0xba,0xd, 0xbe,0x35,0x2f,0x8, 0x6, 0x12,0xba,0xd, 0x7a,0x35,0x2f,0x7e,0x1d,
+0x28,0x7e,0x1b,0x30,0xbc,0x39,0x28,0x3, 0x7a,0x1b,0x90,0x7e,0x1d,0x28,0x29,0x31,
+0x0, 0x2, 0xbc,0x39,0x50,0x4, 0x39,0x91,0x0, 0x2, 0x7e,0x1d,0x28,0x29,0x31,0x0,
+0x1, 0xbc,0x38,0x28,0x4, 0x39,0x81,0x0, 0x1, 0x7e,0x1d,0x28,0x29,0x31,0x0, 0x3,
+0xbc,0x38,0x50,0x4, 0x39,0x81,0x0, 0x3, 0x7e,0xb3,0x31,0xf7,0x4, 0x7a,0xb3,0x31,
+0xf7,0x7e,0x73,0x31,0xf7,0xbc,0x7e,0x50,0x2, 0x1, 0xc9,0xe5,0x2c,0xbe,0xb0,0x0,
+0x38,0x2, 0x21,0xfd,0x7e,0xd, 0x28,0x12,0xba,0x32,0x7e,0xf5,0x2d,0x12,0x6e,0x78,
+0x7e,0x8, 0x0, 0x2, 0x12,0x27,0x66,0x12,0xba,0x25,0x12,0xba,0x1c,0x7d,0x1f,0x1a,
+0x2, 0x1a,0x0, 0x7e,0x1f,0x31,0xf8,0x12,0x27,0x66,0x7a,0x1f,0x31,0xf8,0x7d,0x1f,
+0x1a,0x2, 0x1a,0x0, 0x7e,0x1d,0x24,0x12,0x27,0x66,0x7a,0x1d,0x24,0x7e,0x2f,0x31,
+0xf8,0x12,0xba,0x14,0x19,0xa3,0x2, 0xad,0x7e,0x2d,0x24,0x12,0xba,0x14,0x19,0xa3,
+0x2, 0xae,0x7e,0x37,0x21,0xfb,0xbe,0x35,0x2f,0x78,0xf, 0x7e,0x1f,0x31,0xf8,0x7a,
+0x73,0x21,0xfd,0x7e,0x1d,0x24,0x7a,0x73,0x21,0xfe,0x7e,0x37,0x2, 0xab,0x4d,0x33,
+0x68,0x19,0x7e,0x2f,0x31,0xf8,0x7e,0x1d,0x24,0x12,0x4f,0x6f,0x7e,0x25,0x2f,0x7e,
+0x70,0x2, 0xac,0x7f,0x2e,0x37,0x2, 0xab,0x1b,0x38,0x20,0xb, 0xf0,0xb, 0xc0,0xbc,
+0xdc,0x40,0x2, 0x1, 0x7e,0x12,0xb7,0xfd,0x7c,0xbf,0xda,0x3b,0x22,0x7c,0xb9,0x7c,
+0x78,0x2, 0x4f,0x6f,0x7c,0xab,0x7e,0x70,0x2, 0xac,0x7f,0x22,0x7e,0x1d,0x24,0x2f,
+0x10,0x7a,0x1d,0x24,0x22,0x7f,0x1, 0x7e,0x1f,0x31,0xf8,0x2f,0x10,0x7a,0x1f,0x31,
+0xf8,0x22,0xca,0x79,0x7f,0x70,0x7e,0xb4,0xff,0xff,0x6c,0xee,0xc2,0x4, 0xc2,0x5,
+0x29,0x67,0x0, 0x2, 0x7e,0x7b,0x70,0xbc,0x76,0x78,0xe, 0x29,0x67,0x0, 0x3, 0x29,
+0x77,0x0, 0x1, 0xbc,0x76,0x78,0x2, 0xd2,0x5, 0x6c,0xff,0x12,0xbc,0x12,0x6d,0xcc,
+0x6d,0xaa,0x29,0xb6,0x0, 0x5, 0x20,0xe1,0x2, 0x41,0xf4,0x7f,0x6, 0x7e,0x7b,0xb0,
+0x7e,0x70,0x1, 0x12,0x66,0x88,0x50,0x30,0x7f,0x6, 0x29,0xb7,0x0, 0x2, 0x7e,0x70,
+0x1, 0x12,0x66,0x88,0x50,0x22,0x7f,0x6, 0x29,0xb7,0x0, 0x1, 0x6c,0x77,0x12,0x66,
+0x88,0x50,0x15,0x7f,0x6, 0x29,0xb7,0x0, 0x3, 0x6c,0x77,0x12,0x66,0x88,0x50,0x8,
+0x7c,0xef,0xd2,0x4, 0x6d,0xbb,0x80,0x55,0x7e,0x6b,0x70,0xa, 0x27,0x7e,0x7b,0x70,
+0x12,0x57,0x74,0x2d,0xa3,0x29,0x76,0x0, 0x2, 0xa, 0x27,0x29,0x77,0x0, 0x2, 0x12,
+0x57,0x74,0x2d,0xa3,0x29,0x76,0x0, 0x1, 0xa, 0x27,0x29,0x77,0x0, 0x1, 0x12,0x57,
+0x74,0x2d,0xa3,0x29,0x76,0x0, 0x3, 0xa, 0x27,0x29,0x77,0x0, 0x3, 0x12,0x57,0x74,
+0x2d,0xa3,0xbd,0xab,0x50,0x4, 0x7d,0xba,0x7c,0xef,0xbe,0xa4,0x0, 0x4, 0x38,0x4,
+0xd2,0x4, 0x80,0x9, 0xb, 0xf0,0xbe,0xf0,0x1e,0x50,0x2, 0x41,0x5b,0x20,0x4, 0xb,
+0x20,0x5, 0x8, 0xbe,0xb4,0x0, 0x8, 0x50,0x2, 0xd2,0x4, 0x20,0x4, 0x2, 0x61,0xb7,
+0x74,0x6, 0xac,0xbe,0x12,0xbc,0x16,0x6d,0xcc,0x29,0x76,0x0, 0x5, 0x7c,0xb7,0xc4,
+0x23,0x54,0x1f,0xbe,0xb0,0x1f,0x50,0x16,0x7f,0x6, 0x2e,0x14,0x0, 0x5, 0x7c,0x67,
+0x2e,0x60,0x8, 0x5e,0x60,0xf8,0x5e,0x70,0x7, 0x4c,0x76,0x7a,0xb, 0x70,0x20,0x5,
+0x11,0x29,0xb6,0x0, 0x4, 0xbe,0xb0,0xfa,0x50,0x8, 0x7f,0x16,0xb, 0x36,0x4, 0x7a,
+0x1b,0xb0,0x29,0x67,0x0, 0x3, 0x29,0x76,0x0, 0x3, 0xbc,0x76,0x28,0x6, 0x29,0x76,
+0x0, 0x3, 0x80,0x4, 0x29,0x77,0x0, 0x3, 0x39,0x76,0x0, 0x3, 0x29,0x67,0x0, 0x2,
+0x29,0x76,0x0, 0x2, 0xbc,0x76,0x28,0x6, 0x29,0x76,0x0, 0x2, 0x80,0x4, 0x29,0x77,
+0x0, 0x2, 0x39,0x76,0x0, 0x2, 0x29,0x67,0x0, 0x1, 0x29,0x76,0x0, 0x1, 0xbc,0x76,
+0x50,0x6, 0x29,0x76,0x0, 0x1, 0x80,0x4, 0x29,0x77,0x0, 0x1, 0x39,0x76,0x0, 0x1,
+0x7e,0x7b,0x60,0x7e,0x6b,0x70,0xbc,0x76,0x50,0x5, 0x7e,0x6b,0x70,0x80,0x3, 0x7e,
+0x7b,0x70,0x7a,0x6b,0x70,0x80,0x33,0x6c,0xff,0x74,0x6, 0xac,0xbf,0x9, 0xb5,0x2,
+0xee,0x30,0xe1,0x7, 0xb, 0xf0,0xbe,0xf0,0x1e,0x40,0xee,0xbe,0xf0,0x1e,0x50,0x35,
+0x74,0x1, 0x39,0xb7,0x0, 0x4, 0x12,0xbc,0x12,0x6d,0xcc,0x7e,0x34,0x0, 0x6, 0xca,
+0x39,0x7f,0x17,0x7f,0x6, 0x12,0x29,0x4d,0x1b,0xfd,0x12,0xbc,0x8, 0x44,0x1, 0x7a,
+0x1b,0xb0,0x12,0xbc,0x8, 0x44,0x2, 0x7a,0x1b,0xb0,0x30,0x5, 0x8, 0x12,0xbc,0x8,
+0x44,0x4, 0x7a,0x1b,0xb0,0xda,0x79,0x22,0x7f,0x16,0x2e,0x34,0x0, 0x5, 0x7e,0x1b,
+0xb0,0x22,0x74,0x6, 0xac,0xbf,0x7d,0xd5,0x2e,0xd4,0x2, 0xe9,0x22,0xca,0x3b,0x7a,
+0x1, 0x63,0x7a,0x11,0x62,0x7a,0x21,0x61,0x7a,0x31,0x60,0x12,0xbf,0x1a,0xf5,0x5f,
+0x7e,0xb3,0x1f,0xf5,0xb4,0x2, 0x2, 0x80,0x2, 0xa1,0x47,0x7e,0xb3,0x1f,0xf6,0xb4,
+0x1, 0x2, 0x80,0x2, 0xa1,0x47,0x7e,0x23,0x24,0x3c,0xa, 0x32,0x1b,0x34,0x7e,0x23,
+0x1f,0xe0,0xa, 0xe2,0xbd,0xe3,0x48,0x2, 0xa1,0x47,0x7e,0x43,0x1f,0xcd,0xa, 0xd4,
+0x7e,0x63,0x1f,0xcc,0xa, 0xe6,0x7d,0xfe,0x2d,0xfd,0xe, 0xf4,0x7d,0x4f,0x7c,0x29,
+0x7e,0x73,0x24,0x3a,0x7e,0x90,0x2, 0xac,0x97,0x7e,0xf0,0x2, 0xac,0xf2,0x7d,0xf7,
+0x2d,0xf4,0x7e,0x5f,0x7, 0x28,0x7f,0x45,0x2d,0x9f,0xb, 0x4a,0xf0,0x7e,0x50,0x2,
+0xac,0x45,0x2d,0x24,0x12,0xbe,0xd2,0x7e,0x90,0x2, 0xac,0x97,0x7e,0x70,0x2, 0xac,
+0x67,0x2d,0x34,0x12,0x8c,0xa0,0x12,0xa7,0x2d,0xbe,0x34,0x0, 0x6, 0x58,0x51,0x7c,
+0x72,0x12,0xbe,0xf2,0x2d,0x27,0x7e,0x6f,0x7, 0x28,0x7f,0x56,0x2d,0xb2,0x1b,0xb5,
+0xb, 0x5a,0x20,0x12,0xbe,0xe3,0x7f,0x56,0x2d,0xbe,0xb, 0x5a,0xe0,0xbd,0xe2,0x8,
+0x8, 0xa, 0xe7,0x1b,0xe4,0x7d,0x2e,0x7c,0x25,0x12,0xbe,0xf2,0x7d,0xe2,0x2d,0xe7,
+0x7f,0x56,0x2d,0xbe,0x69,0x25,0x0, 0x2, 0x7e,0x63,0x24,0x3a,0x12,0xbe,0xe3,0x2d,
+0xde,0xb, 0x6a,0xe0,0xbd,0xe2,0x8, 0x8, 0xa, 0xe7,0xb, 0xe4,0x7d,0x3e,0x7c,0x27,
+0xe5,0x5f,0xbc,0xb2,0x28,0x4, 0xbc,0x2, 0x28,0xe, 0x4c,0xaa,0x78,0x39,0x12,0xbe,
+0xda,0x50,0x34,0x7e,0xa0,0x2, 0x80,0x2f,0xbc,0x2, 0x38,0x2b,0xe5,0x5f,0xbc,0xb2,
+0x28,0x25,0xbe,0xa0,0x1, 0x28,0x20,0x12,0xbf,0x1, 0x2e,0x34,0x0, 0x64,0xbd,0xe3,
+0x58,0x13,0x7e,0x23,0x1f,0xcd,0xa, 0x22,0x7e,0x23,0x1f,0xcc,0x12,0xbf,0x13,0xbe,
+0x34,0x0, 0x5, 0x48,0x2, 0x6c,0xaa,0x7e,0xb3,0x1f,0xf5,0xb4,0x1, 0x2, 0x80,0x2,
+0xc1,0x46,0x7e,0xb3,0x1f,0xf6,0xb4,0x2, 0x2, 0x80,0x2, 0xc1,0x46,0x7e,0x23,0x1f,
+0xcc,0xbe,0x20,0x1, 0x38,0x2, 0xc1,0x46,0x7e,0x3, 0x24,0x3b,0xa, 0x30,0x1b,0x34,
+0xa, 0xe2,0xbd,0xe3,0x48,0x2, 0xc1,0x46,0x7e,0x73,0x1f,0xe1,0xa, 0xd7,0x7e,0x63,
+0x1f,0xe0,0xa, 0xe6,0x7d,0x2e,0x2d,0x2d,0xe, 0x24,0x7c,0x25,0x7e,0x50,0x2, 0xac,
+0x52,0x7e,0x5f,0x7, 0x28,0x7f,0x45,0x2d,0x92,0xb, 0x4a,0xf0,0x7e,0x50,0x2, 0xac,
+0x57,0x12,0xbe,0xd2,0x7e,0x70,0x2, 0xac,0x67,0x12,0x8c,0xa0,0x12,0xa7,0x2d,0xbe,
+0x34,0x0, 0x6, 0x58,0x4f,0x7c,0x2, 0x7e,0x70,0x2, 0xac,0x70,0x7e,0x6f,0x7, 0x28,
+0x2d,0x3d,0x7d,0x2c,0x1b,0x35,0xb, 0x1a,0x30,0x7e,0x50,0x2, 0xac,0x52,0x7f,0x56,
+0x2d,0xb2,0xb, 0x5a,0xe0,0xbd,0xe3,0x8, 0x8, 0xa, 0xe0,0x1b,0xe4,0x7d,0x3e,0x7c,
+0x27,0x7e,0x70,0x2, 0xac,0x70,0x2d,0x3d,0x7d,0x2c,0x69,0x31,0x0, 0x2, 0x7e,0x50,
+0x2, 0xac,0x52,0x2d,0xd2,0xb, 0x6a,0xe0,0xbd,0xe3,0x8, 0x8, 0xa, 0xe0,0xb, 0xe4,
+0x7d,0x3e,0x7c,0x27,0xbc,0x32,0x28,0x4, 0xbc,0x12,0x28,0x11,0x4c,0xaa,0x78,0x36,
+0x12,0xbe,0xda,0x50,0x31,0x30,0x11,0x2e,0x7e,0xa0,0x2, 0x80,0x29,0xbc,0x12,0x38,
+0x25,0xbc,0x32,0x28,0x21,0xbe,0xa0,0x1, 0x28,0x1c,0x12,0xbf,0x1, 0xbd,0xe3,0x58,
+0x13,0x7e,0xb3,0x1f,0xe1,0xa, 0x2b,0x7e,0xb3,0x1f,0xe0,0x12,0x7d,0xca,0xbe,0x34,
+0x0, 0x5, 0x48,0x2, 0x6c,0xaa,0x7e,0xb3,0x21,0xf5,0xb4,0x2, 0x20,0x7e,0x73,0x2,
+0x8a,0xbe,0x70,0x2, 0x50,0x17,0x7e,0x73,0x23,0x88,0xbe,0x70,0x1, 0x28,0xe, 0xbe,
+0xb3,0x1f,0xf5,0x28,0x6, 0xbe,0xb3,0x1f,0xf6,0x38,0x2, 0x6c,0xaa,0x7e,0xb3,0x1f,
+0xf4,0xb4,0x1, 0x51,0x7e,0xf3,0x23,0x88,0xbe,0xf0,0x1, 0x28,0x40,0x7e,0xb3,0x2,
+0x8a,0x70,0x3a,0xe5,0x60,0x7e,0x71,0x63,0x12,0xbe,0xca,0x58,0xe, 0xe5,0x62,0x7e,
+0x71,0x61,0x12,0xbe,0xca,0x58,0x4, 0x6c,0xaa,0x80,0x2a,0x7e,0xb3,0x23,0x88,0xb4,
+0x2, 0x23,0x7e,0xb3,0x21,0xf5,0xbe,0xb0,0x5, 0x50,0x1a,0x7e,0xb3,0x21,0xf6,0xbe,
+0xb0,0x1, 0x50,0x11,0xbe,0xa0,0x1, 0x28,0xc, 0x6c,0xaa,0x80,0x8, 0xbe,0xf0,0x1,
+0x78,0x3, 0x7e,0xa0,0x2, 0x7c,0xba,0xda,0x3b,0x22,0x12,0x4f,0x6f,0xbe,0x34,0xff,
+0x38,0x22,0x7f,0x45,0x2d,0x92,0xb, 0x4a,0x20,0x22,0x7e,0xe7,0x21,0xf9,0xbe,0xe4,
+0x0, 0x1e,0x22,0x7e,0xd0,0x2, 0xac,0xd6,0x7e,0xf0,0x2, 0xac,0xf2,0x7d,0xe7,0x2d,
+0xe6,0x22,0x7e,0x63,0x24,0x3a,0x7e,0xf0,0x2, 0xac,0xf6,0x7e,0x50,0x2, 0xac,0x57,
+0x22,0x7d,0x34,0x9d,0x3f,0x12,0x29,0xb4,0x7d,0xe3,0x7e,0x24,0x0, 0x4, 0x7d,0x34,
+0x2, 0x26,0xc7,0xa, 0x32,0x9d,0x32,0x2, 0x29,0xb4,0x7c,0xa4,0x7c,0x15,0x7c,0x36,
+0x7c,0x7, 0x22,0x7c,0xa6,0x7c,0x37,0x7c,0x2b,0xe4,0x6c,0x11,0x80,0x42,0xbc,0xa1,
+0x68,0x3c,0x1a,0x41,0x3e,0x44,0x9, 0x4, 0x20,0x6c,0xa, 0x20,0xa, 0x33,0x9d,0x32,
+0x12,0x29,0xb4,0x7c,0x7, 0x1a,0x41,0x3e,0x44,0x9, 0x74,0x20,0x6b,0xa, 0x27,0x12,
+0xbf,0x13,0x7c,0x97,0xbe,0x90,0x1, 0x18,0x8, 0xbe,0x0, 0x1, 0x18,0x3, 0x74,0x1,
+0x22,0xbe,0x90,0x2, 0x18,0x8, 0xbe,0x0, 0x2, 0x18,0x3, 0x74,0x2, 0x22,0xb, 0x10,
+0x7e,0x83,0x21,0xf5,0xbc,0x81,0x18,0xb6,0x22,0x7e,0x8, 0x2, 0xe9,0x7e,0x34,0x0,
+0xb4,0xe4,0x2, 0x29,0x72,0xca,0xd8,0xca,0x79,0x7c,0xd3,0x12,0xbf,0x1a,0x7c,0x2b,
+0xa, 0xc3,0xa, 0xd1,0x7d,0x3d,0x2d,0x3c,0x7e,0xf4,0x0, 0x2, 0x7d,0x2f,0x12,0x26,
+0xc7,0x7d,0xe3,0x3e,0xe4,0x7e,0x5f,0x7, 0x28,0x7f,0x15,0x2d,0x3e,0xb, 0x1a,0x40,
+0xa, 0x22,0xa, 0x30,0x2d,0x32,0x7d,0x2f,0x12,0x26,0xc7,0x3e,0x34,0x7e,0xb3,0x24,
+0x3a,0x7e,0xf0,0x2, 0xac,0xfb,0x2d,0x37,0x2d,0x3b,0x7d,0x2a,0xb, 0x1a,0xf0,0xbe,
+0xd0,0x1, 0x78,0x16,0x7e,0xe4,0x0, 0x3, 0x7d,0x3f,0x7d,0x2e,0x12,0x26,0xc7,0x2d,
+0xf3,0x7d,0x34,0x7d,0x2e,0x12,0x26,0xc7,0x2d,0x43,0x7e,0x70,0x2, 0xac,0x70,0x7d,
+0xe3,0x2d,0xe7,0x7f,0x15,0x2d,0x3e,0xb, 0x1a,0xe0,0xbd,0xef,0x18,0x26,0x12,0xc0,
+0x85,0x2d,0x32,0x12,0xc0,0x7d,0xbd,0x3f,0x18,0x1a,0x7e,0x70,0x2, 0xac,0x71,0x12,
+0xc0,0x7d,0xbd,0x34,0x18,0xe, 0x7e,0x70,0x2, 0xac,0x73,0x12,0xc0,0x7d,0xbd,0x34,
+0x18,0x2, 0x80,0x4f,0x7d,0x3c,0x9d,0x3d,0xbe,0x34,0x0, 0x2, 0x58,0x1a,0xbd,0xef,
+0x18,0x16,0x12,0xc0,0x85,0x7d,0xe3,0x2d,0xe2,0x7e,0x1f,0x7, 0x28,0x2d,0x3e,0xb,
+0x1a,0x30,0xbd,0x3f,0x18,0x2, 0x80,0x2b,0xa, 0x20,0xa, 0x32,0x9d,0x32,0xbe,0x34,
+0x0, 0x2, 0x58,0x22,0x74,0x2, 0xac,0x1b,0x12,0x51,0xdf,0xb, 0x1a,0x30,0xbd,0x34,
+0x18,0x14,0x74,0x2, 0xac,0x3b,0x7e,0x1f,0x7, 0x28,0x2d,0x31,0xb, 0x1a,0x30,0xbd,
+0x34,0x18,0x3, 0x7e,0xa0,0x2, 0x7c,0xba,0xda,0x79,0xda,0xd8,0x22,0x2d,0x3b,0x7d,
+0x2a,0xb, 0x1a,0x30,0x22,0x7e,0x43,0x24,0x3a,0x7e,0x50,0x2, 0xac,0x45,0x7e,0x70,
+0x2, 0xac,0x72,0x22,0x6c,0xaa,0x6c,0x99,0x80,0xc, 0xa, 0xf9,0x9, 0xbf,0x24,0x46,
+0xbc,0xba,0x68,0x7, 0xb, 0x90,0x12,0xc0,0xc0,0x38,0xef,0x12,0xc0,0xc0,0x68,0x7,
+0xb, 0xa0,0xbe,0xa0,0x23,0x40,0xdf,0x7a,0xb, 0xa0,0x74,0x6e,0x7a,0x1b,0xb0,0x22,
+0x90,0x60,0x50,0xe4,0x93,0xbc,0xb9,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,
+0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x6f,0x93,0xd0,
+0x82,0xd0,0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,
+0x6b,0xda,0x7b,0x32,0xca,0x78,0xa9,0x31,0xe5,0x6, 0xa9,0xd5,0xea,0xa9,0xc5,0xea,
+0xa9,0x30,0xe5,0x19,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0x5, 0x64,0x7e,0x73,0x40,0x34,
+0xbe,0x71,0x64,0x38,0x2, 0xd2,0x17,0xa9,0xd0,0x9e,0xa9,0xd7,0x9e,0xa9,0x34,0xe5,
+0x5, 0xa9,0xc4,0xcd,0xc2,0x95,0xa9,0x32,0xe5,0x3, 0xa9,0xc2,0xcd,0xa9,0x33,0xe5,
+0x3, 0xa9,0xc3,0xcd,0xa9,0x37,0xe5,0x3, 0xa9,0xc7,0xcd,0xa9,0x36,0xe5,0x3, 0xa9,
+0xc6,0xcd,0xda,0x78,0x32,0xe5,0x9a,0x60,0x5, 0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0xc2,
+0x9a,0xa9,0xd4,0xa6,0xc2,0x88,0xd2,0xa8,0x22,0x7e,0x14,0xd7,0xe8,0x7e,0x4, 0x0,
+0xff,0x7e,0x34,0x47,0x52,0x7e,0x24,0x55,0x50,0x79,0x30,0x0, 0x2, 0x1b,0xa, 0x20,
+0x7e,0x34,0x45,0x20,0x7e,0x24,0x41,0x44,0x79,0x30,0x0, 0x6, 0x79,0x20,0x0, 0x4,
+0x7e,0x34,0x99,0x33,0x7e,0x24,0x66,0xcc,0x79,0x30,0x0, 0xa, 0x79,0x20,0x0, 0x8,
+0x7e,0x34,0x41,0x47,0x7e,0x24,0x46,0x4c,0x79,0x30,0x0, 0xe, 0x79,0x20,0x0, 0xc,
+0x22,0xd2,0xcd,0x7e,0x34,0x0, 0xed,0x12,0xc1,0xff,0x7e,0x34,0x20,0x5f,0x7e,0xf,
+0x3f,0xbe,0x79,0x30,0x0, 0x9c,0x7e,0x34,0x21,0x0, 0x7e,0xf, 0x3f,0xbe,0x79,0x30,
+0x0, 0xaa,0x7e,0x34,0x84,0xc0,0x7e,0xf, 0x3f,0xbe,0x79,0x30,0x0, 0xa0,0x7e,0x34,
+0x4, 0x8e,0x7e,0xf, 0x3f,0xbe,0x79,0x30,0x0, 0xa2,0x7e,0x34,0x29,0x90,0x7e,0xf,
+0x3f,0xbe,0x79,0x30,0x0, 0xa4,0x7e,0x34,0x6c,0xd1,0x7e,0xf, 0x3f,0xbe,0x79,0x30,
+0x0, 0xa6,0x7e,0x34,0x3, 0x64,0x7e,0xf, 0x3f,0xbe,0x79,0x30,0x0, 0xa8,0x22,0x7e,
+0xf, 0x3f,0xbe,0x79,0x30,0x0, 0x9e,0x22,0xa9,0xc6,0xeb,0xa9,0xd6,0xac,0xa9,0xd6,
+0xec,0xd2,0x86,0xa9,0xc2,0xeb,0xa9,0xd2,0xac,0xa9,0xd2,0xec,0xd2,0x82,0x22,0x75,
+0x9a,0x2f,0xa9,0xd1,0x99,0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0xc2,0x8e,0x43,0x89,0x20,
+0x75,0x8d,0x1, 0x75,0x8b,0x0, 0xd2,0x8e,0xd2,0xab,0x22,0x75,0xb7,0x0, 0x75,0xb8,
+0x0, 0x75,0xf7,0x0, 0x75,0xf8,0x0, 0xa9,0xd0,0xb7,0xd2,0xb8,0xa9,0xd5,0xb7,0xd2,
+0xbd,0xa9,0xd0,0xf7,0xd2,0xf8,0xa9,0xc1,0xb7,0xc2,0xb9,0xa9,0xc3,0xb7,0xc2,0xbb,
+0xa9,0xc6,0xb7,0xc2,0xbe,0x22,0x75,0xe7,0x6b,0x2, 0xc2,0x6c,0xe4,0x6d,0x33,0x7e,
+0x24,0x0, 0xff,0x7a,0x1b,0xb0,0x75,0xe9,0xff,0x80,0xfe,0xa9,0xd0,0x99,0xa9,0xc6,
+0xdf,0x22,0x7e,0x37,0x40,0x32,0xb, 0x34,0x7a,0x37,0x40,0x32,0xbe,0x34,0xff,0x0,
+0x40,0x8, 0x7e,0x34,0xff,0x0, 0x7a,0x37,0x40,0x32,0x22,0x7c,0x6b,0x6c,0x77,0x6c,
+0xaa,0x7e,0xb3,0x40,0x45,0xb4,0xa5,0x49,0xa9,0xc2,0xb4,0xa9,0xc6,0xb3,0x75,0xb5,
+0x5, 0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,0xa9,
+0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,
+0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0x71,
+0xb5,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0xa1,0xb5,0xa9,0xd2,
+0xb4,0x7c,0x47,0x6c,0x55,0xa, 0x3a,0x4d,0x32,0x22,0xa9,0xc6,0xb3,0x75,0xb5,0x0,
+0x22,0x74,0x6, 0x7d,0x30,0x7d,0x23,0x7c,0x6b,0xa, 0x14,0x7c,0x73,0x7d,0x52,0x7c,
+0xab,0x7e,0xb3,0x40,0x45,0xb4,0xa5,0x3f,0xa9,0xc2,0xb4,0xa9,0xc6,0xb3,0x75,0xb5,
+0x1, 0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,0xa9,0x36,0xb3,0xfc,0x12,0xc2,0xfa,0xa9,
+0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,
+0x7a,0x71,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0xa1,0xb5,0xa9,0x36,0xb3,
+0xfc,0xa9,0xc6,0xb3,0xa9,0xd2,0xb4,0x22,0x74,0x4, 0x7d,0x30,0x2, 0xc3,0x5, 0x74,
+0x6, 0x12,0xc2,0x9b,0x7d,0x3, 0x22,0xca,0xf8,0x7c,0xfb,0x74,0x2, 0x12,0xc2,0x9b,
+0x4c,0xff,0x78,0x5, 0x5e,0x70,0xdf,0x80,0x3, 0x4e,0x70,0x20,0x74,0x2, 0x12,0xc3,
+0x5, 0xda,0xf8,0x22,0xd2,0xc8,0x43,0xed,0xf, 0xc2,0xea,0x75,0xb3,0x13,0xa9,0xd1,
+0xb4,0xa9,0xc0,0xb4,0x12,0xc3,0xa7,0xe4,0x12,0xc3,0x67,0x2, 0xc3,0x9e,0xa9,0xc5,
+0xca,0xe4,0x7a,0xb3,0x40,0x45,0x22,0xa9,0xd5,0xca,0xa9,0xd1,0xea,0xa9,0xc1,0xea,
+0x74,0xa5,0x7a,0xb3,0x40,0x45,0x22,0x2e,0x34,0x10,0x0, 0x75,0x38,0x0, 0xa, 0x56,
+0xf5,0x37,0x7d,0x53,0xf5,0x36,0xa9,0xc2,0xb4,0x74,0x48,0x12,0xc3,0xea,0xe5,0x38,
+0x12,0xc3,0xea,0xe5,0x37,0x12,0xc3,0xea,0xe5,0x36,0x12,0xc3,0xea,0xe4,0x12,0xc3,
+0xea,0x7d,0x32,0x12,0xc3,0xf8,0xa9,0xd2,0xb4,0x22,0xf5,0xb5,0xa9,0x36,0xb3,0xfc,
+0xa9,0xc6,0xb3,0xd3,0x22,0x2, 0xc3,0xb7,0x6d,0x22,0x80,0x13,0x75,0xb5,0x0, 0xa9,
+0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0xe5,0xb5,0x7a,0xb, 0xb0,0xb, 0x14,0xb, 0x24,0xbd,
+0x32,0x38,0xe9,0x22,0x7c,0xab,0x9f,0x11,0x30,0x3, 0x22,0x6c,0x99,0x80,0x1a,0xa,
+0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0x7e,0x78,0x0, 0x1, 0x60,0x5, 0x2f,0x77,
+0x14,0x78,0xfb,0x4d,0x3f,0x4d,0x2e,0xb, 0x90,0xbc,0xa9,0x38,0xe2,0x22,0xca,0xf8,
+0x90,0x60,0x51,0xe4,0x93,0x7c,0xfb,0x7e,0x8, 0x31,0xbb,0x7e,0x34,0x0, 0x8, 0xe4,
+0x12,0x29,0x72,0x7e,0x8, 0x31,0xc3,0x7e,0x34,0x0, 0x24,0x74,0x3f,0x12,0x29,0x72,
+0xd2,0x3, 0x7e,0x8, 0x24,0xb0,0x7c,0xbf,0x12,0xc4,0x14,0x7e,0x8, 0x31,0xbb,0x7a,
+0xf, 0x31,0xe7,0x7f,0x1, 0x7a,0x17,0x31,0xeb,0x7d,0x32,0x7a,0x37,0x31,0xed,0x7e,
+0x18,0x31,0xc3,0x7a,0x1f,0x31,0xf3,0x6c,0x77,0x80,0x14,0xa, 0x27,0x9, 0x62,0x24,
+0xb0,0xbe,0x60,0x24,0x50,0x7, 0x12,0xc4,0xcc,0x19,0x51,0x31,0xc3,0xb, 0x70,0xbc,
+0xf7,0x38,0xe8,0x12,0xc4,0xb6,0x6d,0x33,0x7a,0x37,0x31,0xeb,0x7a,0x37,0x31,0xed,
+0x12,0xc4,0xb6,0xda,0xf8,0x22,0xa9,0xc6,0xea,0x7e,0x8, 0x31,0xe7,0xe4,0x12,0x1a,
+0x8b,0xa9,0xd6,0xea,0x7e,0x8, 0x31,0xe7,0xe4,0x2, 0x1a,0x8b,0xa, 0x27,0x9, 0x52,
+0x25,0x22,0xa, 0x16,0x22,0x7e,0x8, 0x31,0xbb,0x7e,0x34,0x0, 0x24,0x74,0x3f,0x12,
+0x29,0x72,0x6c,0x77,0x80,0x14,0xa, 0x27,0x9, 0x62,0x24,0xb0,0xbe,0x60,0x24,0x50,
+0x7, 0x12,0xc4,0xcc,0x19,0x51,0x31,0xbb,0xb, 0x70,0x7e,0x53,0x24,0x3a,0xbc,0x57,
+0x38,0xe4,0xe4,0x12,0x19,0xdd,0x7e,0x8, 0x31,0xbb,0xe4,0x12,0x1c,0x4f,0x74,0x1,
+0x2, 0x19,0xdd,0xca,0x3b,0x7e,0xd, 0x2b,0x7e,0x34,0x0, 0x48,0x74,0xff,0x12,0x29,
+0x72,0xa1,0xa6,0xa, 0xfa,0x12,0x57,0xad,0x12,0xb7,0x58,0x7c,0xe5,0x7a,0xe1,0x2f,
+0xa, 0x38,0x12,0xf, 0xf5,0x7c,0xb7,0xf5,0x30,0x12,0xc5,0xb9,0x7c,0xb7,0x60,0x5,
+0x3e,0x24,0x14,0x78,0xfb,0x6e,0x24,0xff,0xff,0x7e,0xd0,0x6, 0xac,0xde,0xe5,0x30,
+0xa, 0xfb,0x2d,0xf6,0x12,0xc5,0xa9,0xb, 0xa0,0xbc,0xfa,0x38,0xc6,0xa, 0x3a,0x12,
+0xb7,0xf5,0xa, 0x38,0x7e,0x24,0x0, 0xc, 0x8d,0x32,0x2e,0x34,0x0, 0x3, 0x7c,0xb7,
+0xf5,0x2f,0x2e,0x80,0x24,0xa, 0x68,0x1e,0x64,0x1e,0x64,0x1e,0x64,0x1e,0x64,0x7a,
+0xd1,0x30,0x12,0xc5,0xb9,0x7c,0xb7,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb,0x6e,0x24,
+0xff,0xff,0x7e,0xf1,0x2f,0x74,0x6, 0xac,0xfb,0xa, 0xfd,0x2d,0xf7,0x12,0xc5,0xa9,
+0xb, 0xa0,0xbc,0x9a,0x38,0xb7,0xda,0x3b,0x22,0x3e,0xf4,0x7e,0x6d,0x2b,0x2d,0xdf,
+0xb, 0x6a,0xf0,0x5d,0xf2,0x1b,0x6a,0xf0,0x22,0xa, 0x38,0x7e,0x24,0x0, 0x10,0x12,
+0x26,0xc7,0x7c,0x75,0x7e,0x24,0x0, 0x1, 0x22,0x7c,0x7b,0xa5,0xbf,0x0, 0x3, 0x74,
+0x10,0x22,0xbe,0x70,0x4, 0x38,0x4, 0x6c,0xaa,0x80,0x21,0xbe,0x70,0x8, 0x38,0x5,
+0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x70,0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80,0xd, 0xbe,
+0x70,0x20,0x38,0x5, 0x7e,0xa0,0x3, 0x80,0x3, 0x7e,0xa0,0x4, 0xa, 0x47,0x3e,0x44,
+0x3e,0x44,0x3e,0x44,0x7c,0xba,0x60,0x5, 0x1e,0x44,0x14,0x78,0xfb,0x7c,0xb9,0x22,
+0xca,0xf8,0x6d,0xee,0x7d,0xfe,0x7e,0x83,0x24,0x3a,0xa, 0xd8,0x90,0x60,0x9c,0xe4,
+0x93,0xb4,0xff,0x2f,0x7e,0x8, 0x1b,0xda,0x6c,0xaa,0x80,0x18,0x7e,0x70,0x2, 0xac,
+0x7a,0x49,0x23,0x1c,0x6a,0x7f,0x50,0x2d,0xb3,0xb, 0x5a,0xc0,0x9d,0xc2,0x59,0xc3,
+0x1c,0x22,0xb, 0xa0,0xbc,0x8a,0x38,0xe4,0x90,0x60,0x9a,0xe4,0x93,0x7c,0x9b,0x6d,
+0xdd,0x80,0x11,0x7e,0x8, 0x1c,0x6a,0x90,0x60,0x9a,0xe4,0x93,0xa, 0xcb,0x1b,0xc4,
+0x7d,0x3c,0x7c,0x97,0x6c,0xff,0x80,0x38,0x6c,0xaa,0x80,0x28,0xa, 0x3a,0x7d,0x23,
+0x2d,0x2e,0x3e,0x24,0x49,0xc2,0x1c,0x6a,0x2d,0x3d,0x3e,0x34,0x2d,0x31,0x7d,0x20,
+0xb, 0x1a,0xb0,0x7d,0x3c,0x9d,0x3b,0x12,0x29,0xb4,0x7d,0xa3,0xbd,0xfa,0x58,0x2,
+0x7d,0xfa,0xb, 0xa0,0xbc,0x8a,0x38,0xd4,0xa, 0xc8,0x2d,0xec,0x2d,0xdc,0xb, 0xf0,
+0xbc,0x9f,0x38,0xc4,0x7d,0x3f,0xda,0xf8,0x22,0xca,0x79,0x7f,0x61,0x7f,0x50,0x7e,
+0xa3,0x24,0x40,0xa, 0x3a,0x7e,0xa3,0x24,0x3f,0xa, 0x7a,0x2d,0x73,0x7e,0xd, 0x29,
+0x7c,0x7f,0x12,0x5f,0x36,0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x1d,0x29,0x7f,0x5,
+0x12,0x29,0x4d,0x1b,0xfd,0x7e,0xb3,0x24,0xdd,0xb4,0x1, 0x22,0x6c,0xaa,0x80,0x1a,
+0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x6, 0x2d,0x13,0xb, 0xa, 0x20,0x7f,0x5, 0x2d,0x13,
+0xb, 0xa, 0x30,0x9d,0x32,0x1b,0xa, 0x30,0xb, 0xa0,0xbc,0xfa,0x38,0xe2,0xda,0x79,
+0x22,0x7e,0x27,0x22,0x14,0x6d,0x11,0x9d,0x12,0x6c,0xaa,0x80,0x64,0x30,0x0, 0x2e,
+0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x6, 0x18,0x49,0x4, 0x4, 0x0, 0xbd,0x2, 0x8,
+0x11,0x7e,0xb3,0x1f,0x67,0xb4,0x1, 0x16,0x7d,0xf2,0x2d,0xf3,0x59,0xf4,0x6, 0x18,
+0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59,0x4, 0x6, 0x18,0x30,0x2,
+0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x6, 0x9e,0x49,0x4, 0x4, 0x86,0xbd,0x2,
+0x8, 0x11,0x7e,0xb3,0x1f,0x67,0xb4,0x1, 0x16,0x7d,0xf2,0x2d,0xf3,0x59,0xf4,0x6,
+0x9e,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59,0x4, 0x6, 0x9e,0xb,
+0xa0,0x7e,0xb3,0x24,0x40,0xa, 0xb, 0x7e,0xb3,0x24,0x3f,0xa, 0x4b,0x2d,0x40,0xa,
+0xa, 0xbd,0x4, 0x48,0x88,0x22,0x6c,0x33,0x80,0x9, 0xe4,0xa, 0x33,0x19,0xb3,0x20,
+0xe3,0xb, 0x30,0x90,0x60,0xa2,0xe4,0x93,0x12,0x53,0x49,0xb, 0x24,0xa, 0x33,0xbd,
+0x32,0x48,0xe7,0xe4,0x7a,0xb3,0x21,0xf5,0x7a,0xb3,0x21,0xf6,0x6d,0x33,0x7a,0x37,
+0x21,0xf7,0x7a,0x37,0x21,0xf9,0x7a,0x37,0x21,0xfb,0x7a,0x37,0x21,0xff,0x7e,0xd4,
+0x31,0xbd,0x5e,0xd4,0xff,0xfe,0x6d,0xcc,0x7e,0x1f,0x1b,0xd6,0x7a,0x37,0x31,0xfd,
+0x7d,0x3d,0x7a,0x37,0x32,0x1, 0x7e,0x34,0x1e,0x6a,0x7a,0x37,0x31,0xff,0x7e,0x73,
+0x24,0x39,0x7a,0x73,0x31,0xfa,0x7e,0x73,0x24,0x3a,0x7a,0x73,0x31,0xf9,0x7e,0x37,
+0x24,0x28,0x7a,0x37,0x32,0x3, 0x7e,0x37,0x24,0x2a,0x7a,0x37,0x32,0x5, 0x7e,0x37,
+0x24,0x2c,0x7a,0x37,0x32,0x7, 0x6d,0x33,0x9e,0x37,0x24,0x2c,0x7a,0x37,0x32,0x9,
+0x90,0x60,0xa2,0x93,0x7a,0xb3,0x31,0xfb,0x7e,0x73,0x40,0x40,0x7a,0x73,0x31,0xfc,
+0x7e,0x8, 0x31,0xf9,0x7e,0x18,0x32,0xb, 0x12,0x12,0x18,0x7e,0x73,0x32,0xb, 0x7a,
+0x73,0x21,0xf5,0x7e,0x73,0x32,0xc, 0x7a,0x73,0x21,0xf6,0x7e,0x37,0x32,0xd, 0x7a,
+0x37,0x21,0xf7,0x7e,0x37,0x32,0xf, 0x7a,0x37,0x21,0xf9,0x7e,0x37,0x32,0x15,0x7a,
+0x37,0x21,0xfb,0x7e,0x37,0x32,0x17,0x7d,0x23,0x7a,0x53,0x21,0xfd,0xa, 0x36,0x7a,
+0x73,0x21,0xfe,0x7e,0x37,0x32,0x11,0x7a,0x37,0x21,0xff,0x7e,0x37,0x32,0x13,0x7d,
+0x23,0x7a,0x53,0x22,0x1, 0xa, 0x36,0x7a,0x73,0x22,0x2, 0x6c,0x33,0x80,0x1b,0x12,
+0x65,0xdb,0x74,0x2, 0xac,0xb3,0x49,0x45,0x1e,0x6a,0xa, 0x38,0x7c,0x27,0x19,0x25,
+0x20,0x6b,0x7c,0x29,0x19,0x25,0x20,0x6c,0xb, 0x30,0x7e,0x23,0x21,0xf5,0xbc,0x23,
+0x38,0xdd,0x6c,0x33,0x80,0x1b,0x74,0x2, 0xac,0xb3,0x7f,0x16,0x2d,0x35,0xb, 0x1a,
+0x40,0xa, 0x38,0x7c,0x27,0x19,0x25,0x20,0xa7,0x7c,0x29,0x19,0x25,0x20,0xa8,0xb,
+0x30,0x7e,0x23,0x21,0xf6,0xbc,0x23,0x38,0xdd,0x22,0x7c,0x7b,0xa, 0x57,0x9e,0x54,
+0x0, 0x20,0xe, 0x54,0xe, 0x54,0xe, 0x54,0xe, 0x54,0x7c,0xab,0x7c,0x67,0x5e,0x60,
+0xf0,0xa5,0xbe,0x20,0x1d,0x7c,0xb7,0x54,0xf, 0x7e,0x24,0x0, 0x1, 0x60,0x5, 0x3e,
+0x24,0x14,0x78,0xfb,0x7e,0x73,0x40,0x23,0xa, 0x47,0x5d,0x42,0x7e,0x73,0x3, 0xef,
+0x80,0x36,0xa5,0xbe,0x30,0x18,0x12,0xc9,0x3d,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,
+0x7e,0x53,0x40,0x24,0xa, 0x45,0x5d,0x43,0x7e,0x73,0x3, 0xf0,0x80,0x1a,0x12,0xc9,
+0x3d,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0xa, 0x2a,0x9, 0xb2,0x40,0x23,0xa, 0x4b,
+0x5d,0x43,0xa, 0x5a,0x9, 0x75,0x3, 0xf1,0xa, 0x57,0x5d,0x54,0x22,0x7c,0xb7,0x54,
+0xf, 0x7e,0x34,0x0, 0x1, 0x22,0x7e,0xb3,0x3b,0x24,0xb4,0x4, 0x2, 0xd3,0x22,0xc3,
+0x22,0x7e,0xa3,0x3b,0x4c,0xbe,0xa0,0xf0,0x50,0x17,0x74,0x4, 0xa4,0x59,0x35,0x37,
+0x63,0x12,0x87,0xf2,0x59,0x25,0x37,0x65,0x7e,0xb3,0x3b,0x4c,0x4, 0x7a,0xb3,0x3b,
+0x4c,0x22,0x7d,0x51,0x7d,0x12,0x9d,0x35,0x12,0x29,0xb4,0x7c,0xa7,0x12,0x87,0xe3,
+0x7c,0xb7,0xbc,0xba,0x50,0x3, 0x7c,0xba,0x22,0x22,0x7d,0xf2,0x7d,0xe3,0x7e,0x8,
+0x3b,0x24,0x7e,0x34,0x0, 0x28,0xe4,0x12,0x29,0x72,0x7e,0x8, 0x37,0x63,0x7e,0x34,
+0x3, 0xc0,0x12,0x29,0x72,0x7a,0xb3,0x3, 0xf1,0x7e,0x34,0x62,0xa8,0x12,0x2d,0x68,
+0x7a,0x37,0x37,0x5b,0x7a,0xe7,0x3b,0x28,0x7a,0xf7,0x3b,0x2a,0x7a,0xe7,0x3b,0x2c,
+0x7a,0xe7,0x3b,0x30,0x7a,0xe7,0x3b,0x34,0x7a,0xe7,0x3b,0x38,0x7a,0xf7,0x3b,0x2e,
+0x7a,0xf7,0x3b,0x32,0x7a,0xf7,0x3b,0x36,0x7a,0xf7,0x3b,0x3a,0x7a,0xe7,0x37,0x5f,
+0x7a,0xf7,0x37,0x61,0x7a,0xb3,0x3b,0x4c,0x74,0x2, 0x7a,0xb3,0x3b,0x23,0x22,0x74,
+0xfe,0x7a,0xb3,0x3, 0xf1,0xe4,0x7a,0xb3,0x3b,0x24,0x22,0xca,0x3b,0xf5,0x2a,0x7f,
+0x31,0x7a,0xd, 0x26,0xe4,0x7a,0xb3,0x35,0x7d,0x7a,0xb3,0x35,0x7e,0x7a,0xb3,0x35,
+0x7f,0x7e,0x34,0x3, 0xe8,0x7a,0x37,0x35,0x84,0x74,0x3c,0x7a,0xb3,0x35,0x7c,0x75,
+0x2f,0x46,0x75,0x2b,0x0, 0x61,0xf2,0x12,0xcd,0x86,0x28,0x1e,0x7e,0x34,0x0, 0x44,
+0xca,0x39,0x7e,0x71,0x2b,0x74,0x44,0xac,0x7b,0x2e,0x34,0x1d,0xbf,0x7e,0x24,0x0,
+0xff,0x7e,0x8, 0x35,0x86,0x12,0x29,0x4d,0x1b,0xfd,0x6d,0x33,0x7a,0x37,0x35,0x80,
+0x7a,0x35,0x30,0x7a,0x37,0x35,0x82,0x7a,0x35,0x32,0x7a,0x35,0x34,0x7e,0x34,0x35,
+0x86,0x7a,0x35,0x36,0x7e,0x34,0x35,0xa6,0x7a,0x35,0x38,0x75,0x2c,0x0, 0x80,0x5f,
+0xe5,0x2c,0xa, 0x3b,0x7e,0xd, 0x26,0x12,0xcd,0x8e,0x2e,0x35,0x36,0x7e,0x39,0x70,
+0x12,0x57,0x74,0x7d,0xd3,0x7e,0xc7,0x35,0x82,0xbd,0xcd,0x58,0x4, 0x7a,0xd7,0x35,
+0x82,0xe5,0x2c,0xa, 0x3b,0x7f,0x3, 0x12,0xcd,0x8e,0x2e,0x35,0x38,0x7e,0x39,0x70,
+0x12,0x57,0x74,0x7d,0xc3,0x7e,0x35,0x32,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x32,0x7e,
+0x37,0x35,0x80,0x2d,0x3d,0x7a,0x37,0x35,0x80,0x7d,0x3c,0x2e,0x35,0x30,0x7a,0x35,
+0x30,0x2d,0xcd,0x7e,0x35,0x34,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x34,0x5, 0x2c,0xe5,
+0x2a,0xbe,0xb1,0x2c,0x38,0x9a,0xe5,0x2a,0xb4,0xa, 0x2a,0x7e,0x37,0x35,0x82,0xbe,
+0x34,0x0, 0x40,0x48,0xb, 0x7e,0x25,0x32,0xbe,0x24,0x0, 0x40,0x48,0x2, 0x61,0xf0,
+0xbe,0x34,0x0, 0x60,0x8, 0x2, 0x61,0xf0,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x60,0x8,
+0x2, 0x61,0xf0,0x80,0x28,0x7e,0x37,0x35,0x82,0xbe,0x34,0x0, 0x20,0x8, 0xb, 0x7e,
+0x25,0x32,0xbe,0x24,0x0, 0x20,0x8, 0x2, 0x61,0xf0,0xbe,0x34,0x0, 0x30,0x8, 0x2,
+0x61,0xf0,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x30,0x8, 0x2, 0x61,0xf0,0x7e,0xa3,0x3f,
+0x7a,0x74,0xc, 0xa4,0xbe,0x57,0x35,0x80,0x58,0x2, 0x61,0xf0,0x7e,0xa3,0x3f,0x7b,
+0x74,0xc, 0xa4,0xbe,0x55,0x30,0x58,0x2, 0x61,0xf0,0x7e,0x15,0x36,0x6d,0x0, 0x7e,
+0x1d,0x26,0xe5,0x2a,0x12,0xcc,0x2d,0x7a,0xb3,0x35,0x7b,0x7e,0x15,0x38,0x6d,0x0,
+0x7f,0x13,0xe5,0x2a,0x12,0xcc,0x2d,0xf5,0x2d,0x7e,0x73,0x35,0x7c,0xbe,0x73,0x35,
+0x7b,0x38,0x7d,0xbe,0x71,0x2d,0x38,0x78,0xe5,0x2d,0x7e,0x31,0x2d,0xac,0x3b,0x1a,
+0x2, 0x1a,0x0, 0x7e,0x73,0x35,0x7b,0xac,0x77,0x1a,0x26,0x1a,0x24,0x2f,0x10,0xe5,
+0x2d,0xa, 0x5b,0x6d,0x44,0x7e,0x33,0x35,0x7b,0xa, 0x13,0x6d,0x0, 0x2f,0x2, 0x12,
+0x27,0x15,0x7c,0xb7,0xf5,0x2e,0xe5,0x2f,0xbe,0xb1,0x2e,0x38,0x43,0x7e,0x37,0x35,
+0x82,0x2e,0x35,0x32,0x2e,0x35,0x34,0x7a,0x35,0x3a,0xe5,0x2e,0xa, 0x2b,0x7e,0x34,
+0x0, 0x64,0x9d,0x32,0x3e,0x34,0x2e,0x35,0x3a,0x7a,0x35,0x3a,0x7e,0x37,0x35,0x84,
+0xbe,0x35,0x3a,0x8, 0x1b,0x7e,0x35,0x3a,0x7a,0x37,0x35,0x84,0xe5,0x2e,0x7a,0xb3,
+0x35,0x7e,0x7e,0x73,0x35,0xc8,0x7a,0x73,0x35,0x7f,0xe5,0x2b,0x7a,0xb3,0x35,0x7d,
+0x5, 0x2b,0x12,0xcd,0x86,0x28,0x2, 0x41,0x27,0x7e,0xa3,0x35,0x7e,0xbe,0xa1,0x2f,
+0x40,0x20,0x7e,0xb3,0x35,0x7f,0xbe,0xb0,0x0, 0x28,0x17,0xbe,0xb0,0xff,0x50,0x12,
+0x7e,0x73,0x35,0x7d,0xa, 0x37,0xb, 0x34,0x7a,0x73,0x3f,0x77,0x7a,0xb3,0x3f,0x79,
+0x80,0x6, 0x74,0x7c,0x7a,0xb3,0x3f,0x77,0x7c,0xba,0xda,0x3b,0x22,0xca,0x3b,0x7c,
+0xfb,0x7f,0x61,0x7f,0x40,0x9f,0x11,0x7f,0x51,0x7f,0x71,0x7a,0x1d,0x3c,0x7a,0x1d,
+0x40,0x7a,0x1d,0x44,0xbe,0xf0,0xa, 0x78,0x6, 0x7e,0x54,0x1, 0x3c,0x80,0x4, 0x7e,
+0x54,0x2, 0x35,0x7a,0x57,0x35,0xca,0x6c,0xee,0x80,0x60,0xa, 0x5e,0x7f,0x14,0x12,
+0xcd,0x7e,0x7a,0x55,0x4a,0xa, 0x5e,0x7f,0x16,0x12,0xcd,0x7e,0x7a,0x55,0x48,0x7e,
+0x35,0x48,0x12,0x6e,0xaa,0x2f,0x50,0x7e,0x65,0x4a,0x7d,0x16,0x1a,0x2, 0x1a,0x0,
+0x2f,0x70,0x12,0x6e,0xaa,0x12,0xcd,0x74,0x7e,0x1d,0x3c,0x2f,0x10,0x7a,0x1d,0x3c,
+0x7d,0x16,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x4a,0x12,0xcd,0x74,0x7e,0x1d,0x40,0x2f,
+0x10,0x7a,0x1d,0x40,0x7e,0x15,0x4a,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x48,0x12,0xcd,
+0x74,0x7e,0x1d,0x44,0x2f,0x10,0x7a,0x1d,0x44,0xb, 0xe0,0xbc,0xfe,0x38,0x9c,0xa,
+0xdf,0x6d,0xcc,0x7f,0x15,0x7f,0x6, 0x12,0x27,0x66,0x7f,0x51,0x7f,0x17,0x7f,0x6,
+0x12,0x27,0x66,0x7f,0x71,0x7e,0x94,0x0, 0x64,0x7e,0x1d,0x3c,0x7d,0x19,0x12,0x27,
+0xa, 0x7e,0x87,0x35,0xca,0x7d,0x18,0x7d,0xd8,0x1a,0x12,0x1a,0xc2,0x7f,0x6, 0x12,
+0x27,0x66,0x7a,0x1d,0x3c,0x7e,0x1d,0x40,0x7d,0x19,0x12,0x27,0xa, 0x7f,0x6, 0x12,
+0x27,0x66,0x7a,0x1d,0x40,0x7e,0x1d,0x44,0x7d,0x19,0x12,0x27,0xa, 0x7d,0x18,0x1a,
+0x2, 0x1a,0x0, 0x12,0x27,0x66,0x7a,0x1d,0x44,0x7f,0x15,0x7f,0x7, 0x12,0x26,0xf9,
+0x7e,0x6d,0x44,0x9f,0x61,0x7f,0x15,0x7f,0x5, 0x12,0x26,0xf9,0x7e,0x5d,0x3c,0x9f,
+0x51,0x7f,0x17,0x7f,0x7, 0x12,0x26,0xf9,0x7e,0x7d,0x40,0x9f,0x71,0xbe,0x58,0x0,
+0x0, 0x68,0x6, 0xbe,0x78,0x0, 0x0, 0x78,0x6, 0x7e,0x44,0x0, 0x64,0x80,0x18,0x7f,
+0x16,0x7d,0x19,0x12,0x27,0xa, 0x7f,0x5, 0x12,0x27,0x66,0x7f,0x6, 0x12,0x26,0xf9,
+0x7f,0x7, 0x12,0x27,0x66,0x7d,0x43,0xbe,0x44,0x0, 0x0, 0x18,0x2, 0x6d,0x44,0x7c,
+0xb9,0xda,0x3b,0x22,0x1a,0x26,0x1a,0x24,0x12,0x26,0xf9,0x7f,0x1, 0x22,0x2d,0x35,
+0x7e,0x1b,0x70,0xa, 0x57,0x22,0x7e,0x73,0x40,0x29,0xbe,0x71,0x2b,0x22,0x2d,0x13,
+0x7e,0xb, 0x50,0xa, 0x25,0x22,0xca,0x79,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x7f,
+0x70,0x2d,0xf4,0xb, 0x7a,0xf0,0x7d,0x7f,0x7c,0xbf,0xa, 0xfa,0x19,0xbf,0x3f,0x7c,
+0x7f,0x71,0x2d,0xf4,0xb, 0x7a,0x40,0x7c,0xb9,0xa, 0x4a,0x19,0xb4,0x3f,0x9c,0xb,
+0xa0,0xbe,0xa0,0x20,0x40,0xd4,0x7e,0x8, 0x3f,0x7c,0x7e,0x18,0x3f,0x9c,0x74,0x20,
+0x12,0xc9,0xfb,0xda,0x79,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x3f,0x78,
+0xbe,0x70,0x20,0x40,0x52,0x7e,0xf0,0x2, 0x80,0x3c,0xa, 0x3f,0x6d,0x22,0x74,0x5,
+0x2f,0x11,0x14,0x78,0xfb,0x7e,0x33,0x3f,0x78,0xa, 0x13,0x6d,0x0, 0x12,0x27,0x15,
+0x7c,0xe7,0xbe,0xe0,0x2, 0x50,0x3, 0x7e,0xe0,0x2, 0xa, 0x6f,0x1b,0x64,0xa, 0x3e,
+0x1b,0x34,0x7c,0xc7,0x7f,0x5, 0x7c,0xbd,0x12,0xce,0x40,0x7f,0x6, 0x7c,0xbd,0x7c,
+0x7c,0x12,0xce,0x40,0xb, 0xf0,0x7e,0x73,0x3f,0x78,0xbc,0x7f,0x50,0xbc,0x7f,0x5,
+0x7f,0x16,0x12,0xcd,0x96,0x80,0x6, 0x74,0x7e,0x7a,0xb3,0x3f,0x77,0xda,0x3b,0x22,
+0x7c,0x97,0x7c,0xab,0x7f,0x10,0x7e,0x30,0x2, 0xac,0x3a,0x2d,0x13,0x7d,0x2, 0xb,
+0xa, 0x10,0x7e,0x10,0x2, 0xac,0x19,0x7f,0x71,0x2d,0xf0,0xb, 0x7a,0x0, 0x7c,0x21,
+0xa5,0xba,0x0, 0x14,0xa, 0x3, 0x1b,0x7a,0x0, 0xbc,0x9a,0x68,0x24,0x6d,0x44,0x74,
+0x2, 0xa4,0x2d,0x35,0x1b,0x1a,0x40,0x22,0xbc,0x9a,0x68,0x15,0xa, 0x2, 0xa, 0x13,
+0x2d,0x10,0xe, 0x14,0x1b,0x7a,0x10,0x6d,0x11,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a,
+0x10,0x22,0xca,0xf8,0x7f,0x51,0x7f,0x40,0x7e,0x37,0x3b,0x34,0x7a,0x35,0x2a,0x7e,
+0x37,0x3b,0x32,0x7a,0x35,0x2c,0x7e,0x37,0x3b,0x40,0x7a,0x35,0x26,0x7e,0x37,0x3b,
+0x42,0x7a,0x35,0x28,0x6c,0xff,0x80,0x1e,0x7e,0x34,0x0, 0x26,0x7e,0x14,0x0, 0x2f,
+0x74,0x9, 0x12,0x27,0x9a,0x74,0x2, 0xac,0xbf,0x7f,0x4, 0x2d,0x15,0x7f,0x15,0x2d,
+0x35,0x12,0xa6,0x2a,0xb, 0xf0,0x7e,0x73,0x3f,0x78,0xbc,0x7f,0x38,0xda,0xda,0xf8,
+0x22,0xca,0x3b,0x7f,0x71,0x7e,0x60,0x1, 0xb, 0xa, 0x20,0xb, 0x7a,0x50,0x7c,0x4b,
+0x7a,0x53,0x35,0x7b,0x7a,0x43,0x36,0x6b,0x7e,0x70,0x1, 0x7e,0xa0,0x1, 0x2, 0xd0,
+0x5, 0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x60,0x2d,0xd4,0xb, 0x6a,0xd0,0x7d,0x7d,0x7c,
+0xbf,0xf5,0x26,0x7f,0x67,0x2d,0xd4,0xb, 0x6a,0x40,0xa, 0xd5,0xa, 0xbb,0x7d,0xab,
+0x9d,0xad,0x7d,0x7a,0x7c,0x8f,0xbe,0x80,0x0, 0x58,0x5, 0x6e,0x80,0xff,0xb, 0x80,
+0xa, 0xa4,0xa, 0x79,0x9d,0x7a,0xbe,0xf0,0x0, 0x58,0x5, 0x6e,0xf0,0xff,0xb, 0xf0,
+0xbe,0x80,0x2, 0x58,0x8, 0xbe,0xf0,0x2, 0x58,0x3, 0x2, 0xd0,0x3, 0xbe,0x60,0x0,
+0x18,0x2, 0xe1,0xeb,0xbe,0x70,0xec,0x28,0x3, 0x2, 0xd0,0x10,0xbe,0x80,0x8, 0x58,
+0x5, 0xbe,0xf0,0x8, 0x48,0x61,0xa, 0xa7,0xb, 0xa4,0x7d,0x6a,0x7c,0x7d,0xa, 0xa5,
+0x2d,0xab,0x12,0xd0,0xa3,0x19,0xba,0x35,0x7b,0xa, 0xd9,0xa, 0xa4,0x2d,0xad,0x12,
+0xd0,0xa3,0x19,0xba,0x36,0x6b,0x9, 0xba,0x35,0x7b,0xa, 0xdb,0xa, 0xc5,0x2d,0xcd,
+0xe, 0xc4,0x7d,0x6c,0x7c,0xbd,0xa, 0xc7,0x19,0xbc,0x35,0x7a,0x9, 0xbc,0x36,0x6b,
+0xa, 0xcb,0xa, 0xa4,0x2d,0xac,0x12,0xd0,0xa3,0x19,0xba,0x36,0x6a,0x2d,0xdb,0x12,
+0xd0,0x70,0x19,0xbd,0x35,0x7c,0xa, 0xd9,0x12,0xd0,0x6e,0x19,0xbd,0x36,0x6c,0xb,
+0xd5,0x7d,0x6d,0x7c,0x7d,0x80,0x24,0xbe,0x80,0x4, 0x58,0x5, 0xbe,0xf0,0x4, 0x48,
+0x1a,0xe5,0x26,0xa, 0xcb,0xa, 0xd5,0x12,0xd0,0x6e,0x19,0xbd,0x35,0x7b,0xa, 0xc9,
+0xa, 0xd4,0x12,0xd0,0x6e,0x19,0xbd,0x36,0x6b,0xb, 0x70,0xbe,0x70,0xf0,0x50,0x20,
+0x7e,0x51,0x26,0x7c,0x49,0xe5,0x26,0xa, 0xd7,0x19,0xbd,0x35,0x7b,0x19,0x9d,0x36,
+0x6b,0xb, 0x70,0xb, 0xa0,0x7e,0xb3,0x3f,0x78,0xbc,0xba,0x28,0x3, 0x2, 0xcf,0x1,
+0x7a,0x73,0x3f,0x78,0x7e,0xa0,0x1, 0x80,0x25,0xa, 0x3a,0x9, 0xb3,0x35,0x7b,0xa,
+0x2b,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x60,0x2d,0xd3,0x1b,0x6a,0x20,0xa, 0x2a,0x9,
+0xb2,0x36,0x6b,0xa, 0x4b,0x2d,0x3f,0x7d,0x2e,0x1b,0x1a,0x40,0xb, 0xa0,0x7e,0xb3,
+0x3f,0x78,0xbc,0xba,0x38,0xd3,0xda,0x3b,0x22,0x6d,0x0, 0x7e,0xf4,0xd0,0x0, 0x7e,
+0xe4,0x0, 0x7, 0x7f,0x17,0x12,0x27,0x66,0x7d,0x13,0xb, 0x14,0x7e,0x34,0x0, 0x6,
+0x8d,0x13,0xad,0x13,0x6d,0x0, 0x7f,0x17,0x12,0x27,0x66,0x7d,0x13,0x22,0x2d,0xdc,
+0xe, 0xd4,0x7d,0x6d,0x7c,0xbd,0xa, 0xd7,0x22,0x7e,0x7d,0x2b,0x2d,0xf3,0xb, 0x7a,
+0x30,0x4d,0x32,0x1b,0x7a,0x30,0xb, 0x90,0x22,0x74,0x1, 0x7a,0xb3,0x24,0xdd,0x7a,
+0xb3,0x24,0xfb,0x22,0x7d,0x30,0xad,0x31,0x7c,0x76,0x7c,0x65,0xa, 0x24,0x7d,0x13,
+0x5d,0x1e,0x22,0xe, 0xa4,0x7d,0x6a,0x7c,0xbd,0xa, 0xa7,0x22,0x7e,0x18,0x6, 0x18,
+0x7a,0x1f,0x7, 0x24,0x22,0x7e,0x1f,0x24,0xe9,0x6d,0x22,0x5e,0x60,0x1, 0x7a,0x1f,
+0x24,0xe9,0x22,0x49,0x25,0x22,0xd3,0x74,0x9, 0xac,0xbe,0x49,0x35,0x22,0x1f,0x22,
+0x7e,0x70,0x6, 0xac,0x7a,0x2e,0x34,0x2, 0xe9,0x6d,0x22,0x22,0x6e,0x34,0xff,0xff,
+0xb, 0x34,0x7a,0x37,0x24,0x2a,0x22,0x7a,0x37,0x24,0x1b,0x7e,0x34,0x61,0x69,0x22,
+0x7e,0x34,0x0, 0x48,0xe4,0x2, 0x29,0x72,0x7e,0x34,0x0, 0xc, 0xe4,0x2, 0x29,0x72,
+0x7c,0xf5,0x7c,0xe6,0x7c,0xd7,0x7c,0xcb,0x22,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,
+0x93,0x22,0x7e,0x8, 0x0, 0x25,0x7e,0x18,0x0, 0x24,0x22,0xa, 0x2d,0x1b,0x24,0xa,
+0x3a,0xbd,0x32,0x22,0x6d,0x33,0xe4,0x6c,0x55,0x2, 0x1c,0xa6,0x7e,0x37,0x1f,0x65,
+0x7a,0x37,0x30,0x49,0x22,0x7e,0x34,0x13,0x1a,0x7a,0x37,0x30,0x4b,0x22,0x7e,0x73,
+0x3f,0x42,0x7a,0x73,0x24,0xfe,0x22,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x10,0x22,0x12,
+0x0, 0xe, 0x7e,0x1f,0x1b,0xd2,0x22,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0x22,0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/firmware/fw_sample.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/fw_sample.i
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_touch/include/firmware/fw_sample.i