MLK-14392-1 input: touch: add focaltech touch screen support
authorGao Pan <pandy.gao@nxp.com>
Thu, 16 Mar 2017 08:31:56 +0000 (16:31 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:21:33 +0000 (15:21 -0500)
add focaltech touch screen support

Signed-off-by: Gao Pan <pandy.gao@nxp.com>
(cherry-pick from 595cefbee5586e77ceb9ad900c256177a98367c7)

23 files changed:
Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt [new file with mode: 0644]
arch/arm/configs/imx_v7_defconfig
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/focaltech_touch/Kconfig [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/Makefile [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_common.h [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_config.h [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_core.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_core.h [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i [new file with mode: 0644]
drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i [new file with mode: 0644]
include/linux/wakelock.h [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt
new file mode 100644 (file)
index 0000000..b8e46cc
--- /dev/null
@@ -0,0 +1,46 @@
+FocalTech touch controller
+
+The focaltech controller is connected to host processor via i2c.
+The controller generates interrupts when the user touches the panel.
+The host controller is expected to read the touch coordinates over
+i2c and pass the coordinates to the rest of the system.
+
+Required properties:
+ - compatible          : should be "focaltech,fts"
+ - reg                 : i2c slave address of the device, should be <0x38>
+ - interrupt-parent    : parent of interrupt
+ - interrupts          : irq gpio, "0x02" stands for that the irq triggered by falling edge.
+ - focaltech,irq-gpio  : irq gpio, same as "interrupts" node.
+ - focaltech,reset-gpio        : reset gpio
+ - focaltech,num-max-touches   : maximum number of touches support
+ - focaltech,display-coords    : display resolution in pixels. A four tuple consisting of minX, minY, maxX and maxY.
+
+Optional properties:
+ - focaltech,have-key          : specify if virtual keys are supported
+ - focaltech,key-number                : number of keys
+ - focaltech,keys              : virtual key codes mapping to the coords
+ - focaltech,key-y-coord       : constant y coordinate of keys, depends on the y resolution
+ - focaltech,key-x-coords      : constant x coordinates of keys, depends on the x resolution
+ - focaltech,swap-xy           : swap x-y coordinates
+
+
+Example:
+       i2c@f9927000 {
+               focaltech@38{
+                       compatible = "focaltech,fts";
+                       reg = <0x38>;
+                       interrupt-parent = <&msm_gpio>;
+                       interrupts = <13 0x02>;
+                       focaltech,reset-gpio = <&msm_gpio 12 0x01>;
+                       focaltech,irq-gpio = <&msm_gpio 13 0x02>;
+                       focaltech,max-touch-number = <5>;
+                       focaltech,display-coords =  <0 0 1080 1920>;
+
+                       focaltech,have-key;
+                       focaltech,key-number = <3>;
+                       focaltech,keys = <139 102 158>;
+                       focaltech,key-y-coord = <2000>;
+                       focaltech,key-x-coords = <200 600 800>;
+                       focaltech,swap-xy;
+               };
+       };
index b3f1aa0..b90ee2c 100644 (file)
@@ -167,6 +167,7 @@ CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
 CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_TOUCHSCREEN_TSC2007=y
 CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_TOUCHSCREEN_FTS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MMA8450=y
 CONFIG_INPUT_MPL3115=y
index 1beb197..c6cd111 100644 (file)
@@ -1240,3 +1240,5 @@ config TOUCHSCREEN_ROHM_BU21023
          module will be called bu21023_ts.
 
 endif
+
+source "drivers/input/touchscreen/focaltech_touch/Kconfig"
index 27de5a4..7037a08 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELO)         += elo.o
 obj-$(CONFIG_TOUCHSCREEN_ELAN_TS)      += elan_ts.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX)       += egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)        += egalax_ts_serial.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)          += focaltech_touch/
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)      += fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)       += goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)      += ili210x.o
diff --git a/drivers/input/touchscreen/focaltech_touch/Kconfig b/drivers/input/touchscreen/focaltech_touch/Kconfig
new file mode 100644 (file)
index 0000000..e1ec3b9
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Focaltech Touchscreen driver configuration
+#
+
+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
diff --git a/drivers/input/touchscreen/focaltech_touch/Makefile b/drivers/input/touchscreen/focaltech_touch/Makefile
new file mode 100644 (file)
index 0000000..1b2b8ec
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# 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_esdcheck.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)  +=  focaltech_ex_mode.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)  +=  focaltech_gesture.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)   +=  focaltech_point_report_check.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)   +=  focaltech_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_FTS)   +=  focaltech_sensor.o
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h
new file mode 100644 (file)
index 0000000..c55c590
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ *
+ * FocalTech fts TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_common.h
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-16
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+#ifndef __LINUX_FOCALTECH_COMMON_H__
+#define __LINUX_FOCALTECH_COMMON_H__
+
+#include "focaltech_config.h"
+
+/*****************************************************************************
+* Macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_VERSION     "Focaltech V1.2 20161229"
+
+#define FLAGBIT(x)             (0x00000001 << (x))
+#define FLAGBITS(x, y)         ((0xFFFFFFFF >> (32 - (y) - 1)) << (x))
+
+#define FLAG_ICSERIALS_LEN      5
+#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 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 I2C_BUFFER_LENGTH_MAXINUM           256
+#define FILE_NAME_LENGTH                    128
+#define ENABLE                              1
+#define DISABLE                             0
+/*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_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_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_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_ESD_SATURATE                0xED
+
+/*****************************************************************************
+*  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
+*****************************************************************************/
+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;
+};
+
+/* 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);
+
+/*****************************************************************************
+* DEBUG function define here
+*****************************************************************************/
+#if FTS_DEBUG_EN
+#define FTS_DEBUG_LEVEL     1
+
+#if (FTS_DEBUG_LEVEL == 2)
+#define FTS_DEBUG(fmt, args...) \
+       printk(KERN_ERR "[FTS][%s]"fmt"\n", __func__, ##args)
+#else
+#define FTS_DEBUG(fmt, args...) \
+       printk(KERN_ERR "[FTS]"fmt"\n", ##args)
+#endif
+
+#define FTS_FUNC_ENTER() \
+       printk(KERN_ERR "[FTS]%s: Enter\n", __func__)
+#define FTS_FUNC_EXIT() \
+       printk(KERN_ERR "[FTS]%s: Exit(%d)\n", __func__, __LINE__)
+#else
+#define FTS_DEBUG(fmt, args...)
+#define FTS_FUNC_ENTER()
+#define FTS_FUNC_EXIT()
+#endif
+
+#define FTS_INFO(fmt, args...) do {    \
+               if (g_show_log) \
+                       printk(KERN_ERR "[FTS][Info]"fmt"\n", ##args); \
+       } while (0)
+
+#define FTS_ERROR(fmt, args...)  do {  \
+               if (g_show_log) \
+                       printk(KERN_ERR "[FTS][Error]"fmt"\n", ##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
new file mode 100644 (file)
index 0000000..51de298
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_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
+
+/*************************************************/
+
+/*
+ * choose your ic chip type of focaltech
+ */
+#define FTS_CHIP_TYPE   _FT5416
+
+/******************* Enables *********************/
+/*********** 1 to enable, 0 to disable ***********/
+
+/*
+ * show debug log info
+ * enable it for debug, disable it for release
+ */
+#define FTS_DEBUG_EN                            1
+
+/*
+ * Linux MultiTouch Protocol
+ * 1: Protocol B(default), 0: Protocol A
+ */
+#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
+ */
+#define FTS_GESTURE_EN                          0
+
+/*
+ * ESD check & protection
+ * default: disable
+ */
+#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
+ * 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
+
+/*
+ * Customer power enable
+ * enable it when customer need control TP power
+ * default: disable
+ */
+#define FTS_POWER_SOURCE_CUST_EN                0
+
+/****************************************************/
+
+/********************** Upgrade ****************************/
+/*
+ * auto upgrade, please keep enable
+ */
+#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
+
+/*
+ * FW_APP.i file for upgrade
+ * define your own fw_app, the sample one is invalid
+ */
+#define FTS_UPGRADE_FW_APP                      "include/firmware/FT8716_app_sample.i"
+
+/*
+ * lcd_cfg.i file for lcd cfg upgrade
+ * define your own lcd_cfg.i, the sample one is invalid
+ */
+#define FTS_UPGRADE_LCD_CFG                     "include/firmware/lcd_cfg.i"
+
+/* get vedor id from flash
+ * default: enable
+ */
+#define FTS_GET_VENDOR_ID                       0
+
+/*
+ * vendor_id(s) for the ic
+ * you need confirm vendor_id for upgrade
+ * if only one vendor, ignore vendor_2_id, otherwise
+ * you need define both of them
+ */
+#define FTS_VENDOR_1_ID                         0x8d
+#define FTS_VENDOR_2_ID                         0x8d
+
+/*
+ * 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
+
+/*********************************************************/
+
+#endif /* _LINUX_FOCLATECH_CONFIG_H_ */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
new file mode 100644 (file)
index 0000000..0e3da42
--- /dev/null
@@ -0,0 +1,1420 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_core.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#define FTS_SUSPEND_LEVEL 1    /* Early-suspend level */
+#endif
+
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define FTS_DRIVER_NAME                     "fts_ts"
+#define INTERVAL_READ_REG                   20
+#define TIMEOUT_READ_REG                    300
+#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 };
+#endif
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+static void fts_release_all_finger(void);
+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)
+{
+       int ret = 0;
+       int cnt = 0;
+       u8 reg_value = 0;
+
+       do {
+               ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &reg_value);
+               if (ret < 0)
+                       FTS_INFO("TP Not Ready, ReadData = 0x%x", reg_value);
+               else {
+                       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);
+
+       /* error: not get correct reg data */
+       return -1;
+}
+
+/*****************************************************************************
+*  Name: fts_recover_state
+*  Brief: Need execute this function when reset
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+void fts_tp_state_recovery(struct i2c_client *client)
+{
+       /* 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_release_all_finger();
+}
+
+/*****************************************************************************
+*  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);
+
+       return 0;
+}
+
+/*****************************************************************************
+*  Name: fts_irq_disable
+*  Brief: disable irq
+*  Input:
+*   sync:
+*  Output:
+*  Return:
+*****************************************************************************/
+void fts_irq_disable(void)
+{
+       unsigned long irqflags;
+
+       spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+
+       if (!fts_wq_data->irq_disable) {
+               disable_irq(fts_wq_data->client->irq);
+               fts_wq_data->irq_disable = 1;
+       }
+
+       spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+}
+
+/*****************************************************************************
+*  Name: fts_irq_enable
+*  Brief: enable irq
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+void fts_irq_enable(void)
+{
+       unsigned long irqflags = 0;
+
+       spin_lock_irqsave(&fts_wq_data->irq_lock, irqflags);
+
+       if (fts_wq_data->irq_disable) {
+               enable_irq(fts_wq_data->client->irq);
+               fts_wq_data->irq_disable = 0;
+       }
+
+       spin_unlock_irqrestore(&fts_wq_data->irq_lock, irqflags);
+}
+
+/*****************************************************************************
+*  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)
+{
+       int err, len;
+
+       FTS_FUNC_ENTER();
+
+       /* 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);
+
+       __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);
+
+#if FTS_MT_PROTOCOL_B_EN
+       input_mt_init_slots(input_dev, pdata->max_touch_number,
+                           INPUT_MT_DIRECT);
+#else
+       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
+
+       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;
+
+}
+
+/*****************************************************************************
+* Power Control
+*****************************************************************************/
+#if FTS_POWER_SOURCE_CUST_EN
+static int fts_power_source_init(struct fts_ts_data *data)
+{
+       int rc;
+
+       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;
+
+       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);
+}
+
+#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 += sprintf(g_sz_debug, "%02X,%02X,%02X", buf[0], buf[1], buf[2]);
+       for (i = 0; i < len; i++)
+               count += sprintf(g_sz_debug + 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) {
+               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);
+                               }
+                       } else {
+                               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 -1;
+}
+
+#if FTS_MT_PROTOCOL_B_EN
+static int fts_input_dev_report_b(struct ts_event *event,
+                                 struct fts_ts_data *data)
+{
+       int i = 0;
+       int uppoint = 0;
+       int touchs = 0;
+
+       for (i = 0; i < event->touch_point; i++) {
+               input_mt_slot(data->input_dev, event->au8_finger_id[i]);
+
+               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 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;
+#endif
+                       input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+                                        event->pressure[i]);
+#endif
+
+                       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]);
+
+                       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 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++;
+                       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
+                       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 < 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
+                       }
+               }
+       }
+
+       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;
+
+}
+
+#else
+static int fts_input_dev_report_a(struct ts_event *event,
+                                 struct fts_ts_data *data)
+{
+       int i = 0;
+       int uppoint = 0;
+       int touchs = 0;
+
+       for (i = 0; i < event->touch_point; i++) {
+
+               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]);
+#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;
+#endif
+                       input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+                                        event->pressure[i]);
+#endif
+
+                       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]);
+
+                       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]);
+
+                       input_mt_sync(data->input_dev);
+
+#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++;
+               }
+       }
+
+       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;
+}
+#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);
+
+#if FTS_GESTURE_EN
+       {
+               u8 state;
+
+               if (data->suspended) {
+                       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
+
+#if FTS_READ_TOUCH_BUFFER_DIVIDED
+       memset(buf, 0xFF, POINT_READ_BUF);
+       memset(event, 0, sizeof(struct ts_event));
+
+       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;
+
+       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 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;
+
+               if (data->pdata->swap)
+                       swap(event->au16_x[i], event->au16_y[i]);
+
+               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 (0 == event->area[i])
+                       event->area[i] = 0x09;
+
+               if (0 == event->pressure[i])
+                       event->pressure[i] = 0x3f;
+
+               if ((event->au8_touch_event[i] == 0
+                    || event->au8_touch_event[i] == 2)
+                   && (event->point_num == 0))
+                       break;
+       }
+       return 0;
+}
+
+/*****************************************************************************
+*  Name: fts_report_value
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static void fts_report_value(struct fts_ts_data *data)
+{
+       struct ts_event *event = &data->event;
+
+       FTS_DEBUG("point number: %d, touch point: %d", event->point_num,
+                 event->touch_point);
+
+       if (0 == fts_input_dev_report_key_event(event, data))
+               return;
+#if FTS_MT_PROTOCOL_B_EN
+       fts_input_dev_report_b(event, data);
+#else
+       fts_input_dev_report_a(event, data);
+#endif
+
+       return;
+
+}
+
+/*****************************************************************************
+*  Name: fts_ts_interrupt
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static irqreturn_t fts_ts_interrupt(int irq, void *dev_id)
+{
+       struct fts_ts_data *fts_ts = dev_id;
+       int ret = -1;
+
+       if (!fts_ts) {
+               FTS_ERROR("[INTR]: Invalid fts_ts");
+               return IRQ_HANDLED;
+       }
+#if FTS_ESDCHECK_EN
+       fts_esdcheck_set_intr(1);
+#endif
+
+       ret = fts_read_touchdata(fts_wq_data);
+
+       if (ret == 0)
+               fts_report_value(fts_wq_data);
+#if FTS_ESDCHECK_EN
+       fts_esdcheck_set_intr(0);
+#endif
+
+       return IRQ_HANDLED;
+}
+
+/*****************************************************************************
+*  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->swap = of_property_read_bool(np, "focaltech,swap-xy");
+
+       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)
+                       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);
+
+       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);
+#endif
+
+       err = fts_gpio_configure(data);
+       if (err < 0) {
+               FTS_ERROR("[GPIO]Failed to configure the gpios");
+               goto free_gpio;
+       }
+
+       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;
+       }
+#endif
+
+#if FTS_POINT_REPORT_CHECK_EN
+       fts_point_report_check_init();
+#endif
+
+       fts_ex_mode_init(client);
+
+#if FTS_GESTURE_EN
+       fts_gesture_init(input_dev, client);
+#endif
+
+#if FTS_ESDCHECK_EN
+       fts_esdcheck_init();
+#endif
+
+       fts_irq_enable();
+
+#if FTS_TEST_EN
+       fts_test_init(client);
+#endif
+
+#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);
+#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
+
+       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;
+
+}
+
+/*****************************************************************************
+*  Name: fts_ts_remove
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static int fts_ts_remove(struct i2c_client *client)
+{
+       struct fts_ts_data *data = i2c_get_clientdata(client);
+
+       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
+
+       fts_ex_mode_exit(client);
+
+#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;
+}
+
+/*****************************************************************************
+*  Name: fts_ts_suspend
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static int fts_ts_suspend(struct device *dev)
+{
+       struct fts_ts_data *data = dev_get_drvdata(dev);
+       int retval = 0;
+
+       FTS_FUNC_ENTER();
+       if (data->suspended) {
+               FTS_INFO("Already in suspend state");
+               FTS_FUNC_EXIT();
+               return -1;
+       }
+
+       fts_release_all_finger();
+
+#if FTS_GESTURE_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
+
+#if FTS_ESDCHECK_EN
+       fts_esdcheck_suspend();
+#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 -1;
+       }
+#if (!FTS_CHIP_IDC)
+       fts_reset_proc(200);
+#endif
+
+       fts_tp_state_recovery(data->client);
+
+#if FTS_GESTURE_EN
+       if (fts_gesture_resume(data->client) == 0) {
+               int err;
+
+               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;
+       }
+#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;
+       }
+#endif
+
+       data->suspended = false;
+
+       fts_irq_enable();
+
+#if FTS_ESDCHECK_EN
+       fts_esdcheck_resume();
+#endif
+       FTS_FUNC_EXIT();
+       return 0;
+}
+
+/*****************************************************************************
+* I2C Driver
+*****************************************************************************/
+static const struct i2c_device_id fts_ts_id[] = {
+       {FTS_DRIVER_NAME, 0},
+       {},
+};
+
+MODULE_DEVICE_TABLE(i2c, fts_ts_id);
+
+static struct of_device_id fts_match_table[] = {
+       {.compatible = "focaltech,fts",},
+       {},
+};
+
+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,
+};
+
+/*****************************************************************************
+*  Name: fts_ts_init
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static int __init fts_ts_init(void)
+{
+       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;
+}
+
+/*****************************************************************************
+*  Name: fts_ts_exit
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static void __exit fts_ts_exit(void)
+{
+       i2c_del_driver(&fts_ts_driver);
+}
+
+module_init(fts_ts_init);
+module_exit(fts_ts_exit);
+
+MODULE_AUTHOR("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
new file mode 100644 (file)
index 0000000..55ab92c
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_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
+*****************************************************************************/
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/debugfs.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <asm/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 "focaltech_common.h"
+
+/*****************************************************************************
+* 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
+#define FTS_ONE_TCH_LEN                     6
+#define POINT_READ_BUF  (3 + FTS_ONE_TCH_LEN * FTS_MAX_POINTS)
+
+#define FTS_MAX_ID                          0x0F
+#define FTS_TOUCH_X_H_POS                   3
+#define FTS_TOUCH_X_L_POS                   4
+#define FTS_TOUCH_Y_H_POS                   5
+#define FTS_TOUCH_Y_L_POS                   6
+#define FTS_TOUCH_PRE_POS                   7
+#define FTS_TOUCH_AREA_POS                  8
+#define FTS_TOUCH_POINT_NUM                 2
+#define FTS_TOUCH_EVENT_POS                 3
+#define FTS_TOUCH_ID_POS                    5
+#define FTS_COORDS_ARR_SIZE                 4
+
+#define FTS_TOUCH_DOWN      0
+#define FTS_TOUCH_UP        1
+#define FTS_TOUCH_CONTACT   2
+
+#define FTS_SYSFS_ECHO_ON(buf)         ((strnicmp(buf, "1", 1)  == 0) || \
+                                       (strnicmp(buf, "on", 2) == 0))
+#define FTS_SYSFS_ECHO_OFF(buf)                ((strnicmp(buf, "0", 1)  == 0) || \
+                                       (strnicmp(buf, "off", 3) == 0))
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+struct fts_ts_platform_data {
+       u32 irq_gpio;
+       u32 irq_gpio_flags;
+       u32 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 swap;
+};
+
+struct ts_event {
+       u16 au16_x[FTS_MAX_POINTS];     /*x coordinate */
+       u16 au16_y[FTS_MAX_POINTS];     /*y coordinate */
+       u16 pressure[FTS_MAX_POINTS];
+       /* touch event: 0 -- down; 1-- up; 2 -- contact */
+       u8 au8_touch_event[FTS_MAX_POINTS];
+       u8 au8_finger_id[FTS_MAX_POINTS];       /*touch ID */
+       u8 area[FTS_MAX_POINTS];
+       u8 touch_point;
+       u8 point_num;
+};
+
+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;
+#endif
+       struct work_struct touch_event_work;
+       struct workqueue_struct *ts_workqueue;
+       struct regulator *vdd;
+       struct regulator *vcc_i2c;
+       spinlock_t irq_lock;
+       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;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+       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;
+
+#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
new file mode 100644 (file)
index 0000000..565507d
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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: luoguojin
+*
+*   Created: 2016-08-03
+*
+*  Abstract: ESD check function
+*
+*   Version: v1.0
+*
+* Revision History:
+*        v1.0:
+*            First release. By luougojin 2016-08-03
+*****************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+#if FTS_ESDCHECK_EN
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+#define ESDCHECK_WAIT_TIME              1000
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+struct fts_esdcheck_st {
+       u8 active:1;
+       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;
+       u8 flow_work_cnt_last;
+       u32 hardware_reset_cnt;
+       u32 i2c_nack_cnt;
+       u32 i2c_dataerror_cnt;
+};
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct delayed_work fts_esdcheck_work;
+static struct workqueue_struct *fts_esdcheck_workqueue;
+static struct fts_esdcheck_st fts_esdcheck_data;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* Static function prototypes
+*****************************************************************************/
+
+/*****************************************************************************
+* functions body
+*****************************************************************************/
+/*****************************************************************************
+*  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)
+{
+       u8 val;
+       int ret;
+
+       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);
+       }
+
+       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;
+       }
+
+       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;
+       }
+
+       return 0;
+}
+
+/*****************************************************************************
+*  Name: fts_esdcheck_tp_reset
+*  Brief: esd check algorithm
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static int fts_esdcheck_tp_reset(void)
+{
+       FTS_FUNC_ENTER();
+
+       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_FUNC_EXIT();
+       return 0;
+}
+
+/*****************************************************************************
+*  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)
+{
+       int err = 0;
+       int i = 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, &reg_addr, 1, &reg_value, 1);
+
+               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;
+                        else
+                               fts_esdcheck_data.i2c_dataerror_cnt++;
+               }
+       }
+
+       /* if can't get correct data in 3 times, then need hardware reset */
+       if (i >= 3) {
+               FTS_ERROR
+                   ("[ESD]: Read Chip id 3 times failed,"
+                                       "need execute TP reset!!");
+               return 1;
+       }
+
+       return 0;
+}
+
+/*****************************************************************************
+*  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)
+{
+       int err = 0;
+       u8 reg_value = 0;
+       u8 reg_addr = 0;
+
+       reg_addr = FTS_REG_FLOW_WORK_CNT;
+       err = fts_i2c_read(fts_i2c_client, &reg_addr, 1, &reg_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;
+
+               fts_esdcheck_data.flow_work_cnt_last = reg_value;
+       }
+
+       /*
+        * 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(reg0x91) keep a value"
+                               "for 5 times, need execute TP reset!!");
+               return 1;
+       }
+
+       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 immediately!!");
+               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 immediately!!");
+               /* 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 apk or adb command mode,"
+                               "not check esd, return immediately!!");
+               return 0;
+       }
+
+       /* 4. In factory mode, can't check esd */
+       reg_addr = FTS_REG_WORKMODE;
+       err = fts_i2c_read(fts_i2c_client, &reg_addr, 1, &reg_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 immediately!!");
+               return 0;
+       }
+
+       /* 5. Get Chip ID */
+       hardware_reset = get_chip_id();
+
+       /*
+        * 6. get Flow work cnt: 0x91 If no change for 5 times,
+        * then ESD and reset
+        */
+       if (!hardware_reset)
+               hardware_reset = get_flow_cnt();
+
+       /* 7. If need hardware reset, then handle it here */
+       if (hardware_reset == 1)
+               fts_esdcheck_tp_reset();
+
+       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;
+}
+
+/*****************************************************************************
+*  Name: fts_esdcheck_func
+*  Brief: fts_esdcheck_func
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+static void esdcheck_func(struct work_struct *work)
+{
+       FTS_FUNC_ENTER();
+
+       idc_esdcheck_lcderror();
+
+       esdcheck_algorithm();
+
+       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;
+}
+
+/*****************************************************************************
+*  Name: fts_esdcheck_get_status(void)
+*  Brief: get current status
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+int fts_esdcheck_get_status(void)
+{
+       /* interrupt don't add debug message */
+       return fts_esdcheck_data.active;
+}
+
+/*****************************************************************************
+*  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;
+}
+
+/*****************************************************************************
+*  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);
+               }
+       }
+
+       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;
+}
+
+/*****************************************************************************
+*  Name: fts_esdcheck_resume
+*  Brief: Run when tp resume
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+int fts_esdcheck_resume(void)
+{
+       FTS_FUNC_ENTER();
+       fts_esdcheck_switch(ENABLE);
+       fts_esdcheck_data.suspend = 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)
+{
+       FTS_FUNC_ENTER();
+
+       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!!");
+
+       memset((u8 *) &fts_esdcheck_data, 0, sizeof(struct fts_esdcheck_st));
+
+       fts_esdcheck_switch(ENABLE);
+       FTS_FUNC_EXIT();
+       return 0;
+}
+
+/*****************************************************************************
+*  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)
+{
+       FTS_FUNC_ENTER();
+
+       destroy_workqueue(fts_esdcheck_workqueue);
+
+       FTS_FUNC_EXIT();
+       return 0;
+}
+#endif /* FTS_ESDCHECK_EN */
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
new file mode 100644 (file)
index 0000000..6ab5d47
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ *
+ * FocalTech ftxxxx TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_ex_mode.c
+*
+*    Author: Liu WeiGuang
+*
+*   Created: 2016-08-31
+*
+*  Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* 1.Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+/*****************************************************************************
+* 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;
+};
+
+struct fts_mode_flag g_fts_mode_flag;
+
+/*****************************************************************************
+* 4.Static variables
+*****************************************************************************/
+
+/*****************************************************************************
+* 5.Global variable or extern global variabls/functions
+*****************************************************************************/
+int fts_enter_glove_mode(struct i2c_client *client, int mode);
+int fts_glove_init(struct i2c_client *client);
+int fts_glove_exit(struct i2c_client *client);
+
+int fts_enter_cover_mode(struct i2c_client *client, int mode);
+int fts_cover_init(struct i2c_client *client);
+int fts_cover_exit(struct i2c_client *client);
+
+int fts_enter_charger_mode(struct i2c_client *client, int mode);
+int fts_charger_init(struct i2c_client *client);
+int fts_charger_exit(struct i2c_client *client);
+
+/*****************************************************************************
+* 6.Static function prototypes
+*******************************************************************************/
+
+#if FTS_GLOVE_EN
+static ssize_t fts_touch_glove_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "Glove: %s\n",
+                       g_fts_mode_flag.fts_glove_mode_flag ? "On" : "Off");
+}
+
+static ssize_t fts_touch_glove_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_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;
+               }
+       }
+       FTS_INFO("[Mode]glove mode status:  %d",
+                g_fts_mode_flag.fts_glove_mode_flag);
+       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)
+{
+       int ret = 0;
+       static u8 buf_addr[2] = { 0 };
+       static u8 buf_value[2] = { 0 };
+
+       buf_addr[0] = FTS_REG_GLOVE_MODE_EN;
+
+       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;
+
+}
+
+/* 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, S_IRUGO | S_IWUSR, 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)
+{
+       return snprintf(buf, PAGE_SIZE, "Cover: %s\n",
+                       g_fts_mode_flag.fts_cover_mode_flag ? "On" : "Off");
+}
+
+static ssize_t fts_touch_cover_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_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;
+               }
+       }
+       FTS_INFO("[Mode]cover mode status:  %d",
+                g_fts_mode_flag.fts_cover_mode_flag);
+       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)
+{
+       int ret = 0;
+       static u8 buf_addr[2] = { 0 };
+       static u8 buf_value[2] = { 0 };
+
+       buf_addr[0] = FTS_REG_COVER_MODE_EN;
+
+       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;
+
+}
+
+/* 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, S_IRUGO | S_IWUSR, 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)
+{
+       return snprintf(buf, PAGE_SIZE, "Charger: %s\n",
+                       g_fts_mode_flag.fts_charger_mode_flag ? "On" : "Off");
+}
+
+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;
+
+       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
+*
+*/
+static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR, fts_touch_charger_show,
+                  fts_touch_charger_store);
+
+#endif
+
+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,
+};
+
+static struct attribute_group fts_touch_mode_group = {
+       .attrs = fts_touch_mode_attrs,
+};
+
+int fts_ex_mode_init(struct i2c_client *client)
+{
+       int err = 0;
+
+       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;
+
+       err = sysfs_create_group(&client->dev.kobj, &fts_touch_mode_group);
+       if (0 != err) {
+               FTS_ERROR("[Mode]create sysfs failed.");
+               sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
+               return -EIO;
+       }
+
+       FTS_DEBUG("[Mode]create sysfs succeeded");
+
+       return err;
+
+}
+
+int fts_ex_mode_exit(struct i2c_client *client)
+{
+       sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
+       return 0;
+}
+
+int fts_ex_mode_recovery(struct i2c_client *client)
+{
+       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;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
new file mode 100644 (file)
index 0000000..9faabb8
--- /dev/null
@@ -0,0 +1,652 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_gestrue.c
+*
+* Author: Focaltech Driver Team
+*
+* Created: 2016-08-08
+*
+* Abstract:
+*
+* Reference:
+*
+*****************************************************************************/
+
+/*****************************************************************************
+* 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
+#define  KEY_GESTURE_LEFT                       KEY_LEFT
+#define  KEY_GESTURE_RIGHT                      KEY_RIGHT
+#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_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_O                               0x30
+#define GESTURE_W                               0x31
+#define GESTURE_M                               0x32
+#define GESTURE_E                               0x33
+#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 FTS_GESTURE_OUTPUT_ADRESS               0xD3
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+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;
+};
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static struct fts_gesture_st fts_gesture_data;
+extern struct fts_ts_data *fts_wq_data;
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* 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);
+
+/* sysfs gesture node
+ *   read example: cat  fts_gesture_mode        ---read gesture mode
+ *   write example:echo 01 > fts_gesture_mode   ---write gesture mode to 01
+ *
+ */
+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
+ */
+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,
+};
+
+static struct attribute_group fts_gesture_group = {
+       .attrs = fts_gesture_mode_attrs,
+};
+
+/************************************************************************
+* Name: fts_gesture_show
+* Brief:  no
+* Input: device, device attribute, char buf
+* Output: no
+* Return:
+***********************************************************************/
+static ssize_t fts_gesture_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       int count;
+       u8 val;
+       struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+
+       mutex_lock(&fts_input_dev->mutex);
+       fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val);
+       count =
+           sprintf(buf, "Gesture Mode: %s\n",
+                   fts_gesture_data.mode ? "On" : "Off");
+       count += sprintf(buf + count, "Reg(0xD0) = %d\n", val);
+       mutex_unlock(&fts_input_dev->mutex);
+
+       return count;
+}
+
+/************************************************************************
+* Name: fts_gesture_store
+* Brief:  no
+* Input: device, device attribute, char buf, char count
+* Output: no
+* 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:  no
+* Input: device, device attribute, char buf
+* Output: no
+* 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:  no
+* Input: device, device attribute, char buf, char count
+* Output: no
+* 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: None
+* Return: 0-success or 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_mode_group(sysfs) create failed!");
+               sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
+               return ret;
+       }
+       return 0;
+}
+
+/*****************************************************************************
+*   Name: fts_gesture_recovery
+*  Brief: recovery gesture state when reset
+*  Input:
+* Output: None
+* Return:
+*****************************************************************************/
+void fts_gesture_recovery(struct i2c_client *client)
+{
+       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);
+       }
+}
+
+/*****************************************************************************
+*   Name: fts_gesture_init
+*  Brief:
+*  Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client)
+{
+       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);
+
+       __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_create_gesture_sysfs(client);
+       fts_gesture_data.mode = 0;
+       fts_gesture_data.active = 0;
+       FTS_FUNC_EXIT();
+       return 0;
+}
+
+/************************************************************************
+* Name: fts_gesture_exit
+* Brief:  remove sys
+* Input: i2c info
+* Output: no
+* Return: no
+***********************************************************************/
+int fts_gesture_exit(struct i2c_client *client)
+{
+       sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
+       return 0;
+}
+
+/*****************************************************************************
+*   Name: fts_check_gesture
+*  Brief:
+*  Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+static void fts_check_gesture(struct input_dev *input_dev, int gesture_id)
+{
+       char *envp[2];
+       int gesture;
+
+       FTS_FUNC_ENTER();
+       switch (gesture_id) {
+       case GESTURE_LEFT:
+               envp[0] = "GESTURE=LEFT";
+               gesture = KEY_GESTURE_LEFT;
+               break;
+       case GESTURE_RIGHT:
+               envp[0] = "GESTURE=RIGHT";
+               gesture = KEY_GESTURE_RIGHT;
+               break;
+       case GESTURE_UP:
+               envp[0] = "GESTURE=UP";
+               gesture = KEY_GESTURE_UP;
+               break;
+       case GESTURE_DOWN:
+               envp[0] = "GESTURE=DOWN";
+               gesture = KEY_GESTURE_DOWN;
+               break;
+       case GESTURE_DOUBLECLICK:
+               envp[0] = "GESTURE=DOUBLE_CLICK";
+               gesture = KEY_POWER;
+               break;
+       case GESTURE_O:
+               envp[0] = "GESTURE=O";
+               gesture = KEY_GESTURE_O;
+               break;
+       case GESTURE_W:
+               envp[0] = "GESTURE=W";
+               gesture = KEY_GESTURE_W;
+               break;
+       case GESTURE_M:
+               envp[0] = "GESTURE=M";
+               gesture = KEY_GESTURE_M;
+               break;
+       case GESTURE_E:
+               envp[0] = "GESTURE=E";
+               gesture = KEY_GESTURE_E;
+               break;
+       case GESTURE_L:
+               envp[0] = "GESTURE=L";
+               gesture = KEY_GESTURE_L;
+               break;
+       case GESTURE_S:
+               envp[0] = "GESTURE=S";
+               gesture = KEY_GESTURE_S;
+               break;
+       case GESTURE_V:
+               envp[0] = "GESTURE=V";
+               gesture = KEY_GESTURE_V;
+               break;
+       case GESTURE_Z:
+               envp[0] = "GESTURE=Z";
+               gesture = KEY_GESTURE_Z;
+               break;
+       case GESTURE_C:
+               envp[0] = "GESTURE=C";
+               gesture = KEY_GESTURE_C;
+               break;
+       default:
+               envp[0] = "GESTURE=NONE";
+               gesture = -1;
+               break;
+       }
+       FTS_DEBUG("envp[0]: %s", envp[0]);
+       /* report event key */
+       /*if (gesture != -1)
+          {
+          input_report_key(input_dev, gesture, 1);
+          input_sync(input_dev);
+          input_report_key(input_dev, gesture, 0);
+          input_sync(input_dev);
+          } */
+
+       envp[1] = NULL;
+       kobject_uevent_env(&fts_wq_data->client->dev.kobj, KOBJ_CHANGE, envp);
+       sysfs_notify(&fts_wq_data->client->dev.kobj, NULL, "GESTURE_ID");
+
+       FTS_FUNC_EXIT();
+}
+
+/************************************************************************
+*   Name: fts_gesture_readdata
+* Brief: read data from TP register
+* Input: no
+* Output: no
+* 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_readdata
+* Brief: read data from TP register
+* Input: no
+* Output: no
+* 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;
+       }
+
+       /* FW recognize gesture */
+       if (chip_types.chip_idh == 0x54 || chip_types.chip_idh == 0x58
+           || chip_types.chip_idh == 0x86 || chip_types.chip_idh == 0x87
+           || chip_types.chip_idh == 0x64) {
+               memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
+               gestrue_id = buf[0];
+               pointnum = buf[1];
+               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_check_gesture(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);
+               }
+               FTS_FUNC_EXIT();
+               return 0;
+       }
+       /* other IC's gestrue in driver */
+       if (0x24 == buf[0]) {
+               gestrue_id = 0x24;
+               fts_check_gesture(fts_input_dev, gestrue_id);
+               FTS_DEBUG("[GESTURE]%d check_gesture gestrue_id", gestrue_id);
+               FTS_FUNC_EXIT();
+               return -1;
+       }
+
+       /* Host Driver recognize gesture */
+       pointnum = buf[1];
+       read_bytes = ((int)pointnum) * 4 + 2;
+       buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
+       ret = fts_gesture_read_buffer(client, buf, read_bytes);
+       if (ret < 0) {
+               FTS_ERROR ("[GESTURE]Driver recognize gesture -"
+                                       "Read gesture touch data failed!!");
+               FTS_FUNC_EXIT();
+               return ret;
+       }
+
+       /*
+        * Host Driver recognize gesture, need gesture lib.a
+        * Not use now for compatibility
+        gestrue_id = fetch_object_sample(buf, pointnum);
+        */
+       gestrue_id = 0x24;
+       fts_check_gesture(fts_input_dev, gestrue_id);
+       FTS_DEBUG("[GESTURE]%d read gestrue_id", gestrue_id);
+
+       for (i = 0; i < pointnum; i++) {
+               fts_gesture_data.coordinate_x[i] =
+                   (((s16) buf[0 + (4 * i + 8)]) & 0x0F) << 8 |
+                   (((s16) buf[1 + (4 * i + 8)]) & 0xFF);
+               fts_gesture_data.coordinate_y[i] =
+                   (((s16) buf[2 + (4 * i + 8)]) & 0x0F) << 8 |
+                   (((s16) buf[3 + (4 * i + 8)]) & 0xFF);
+       }
+       FTS_FUNC_EXIT();
+       return -1;
+}
+
+/*****************************************************************************
+*   Name: fts_gesture_suspend
+*  Brief:
+*  Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_suspend(struct i2c_client *i2c_client)
+{
+       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 -1;
+       }
+
+       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);
+               msleep(1);
+               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 -1;
+       }
+
+       fts_gesture_data.active = 1;
+       FTS_DEBUG("[GESTURE]Enter into gesture(suspend) successfully!");
+       FTS_FUNC_EXIT();
+       return 0;
+}
+
+/*****************************************************************************
+*   Name: fts_gesture_resume
+*  Brief:
+*  Input:
+* Output: None
+* Return: None
+*****************************************************************************/
+int fts_gesture_resume(struct i2c_client *client)
+{
+       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 -1;
+       }
+
+       fts_gesture_data.active = 0;
+       for (i = 0; i < 5; i++) {
+               fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, 0x00);
+               msleep(1);
+               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;
+}
+#endif
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c
new file mode 100644 (file)
index 0000000..75cd917
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_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
+************************************************************************/
+
+/*****************************************************************************
+* Included header files
+*****************************************************************************/
+#include "focaltech_core.h"
+
+/*****************************************************************************
+* Private constant and macro definitions using #define
+*****************************************************************************/
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+/*****************************************************************************
+* Static variables
+*****************************************************************************/
+static DEFINE_MUTEX(i2c_rw_access);
+
+/*****************************************************************************
+* Global variable or extern global variabls/functions
+*****************************************************************************/
+
+/*****************************************************************************
+* 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)
+{
+       int ret = 0;
+
+       mutex_lock(&i2c_rw_access);
+
+       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_transfer(write)"
+                                       "error,ret=%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_transfer(read)"
+                                       "error, ret=%d!!", ret);
+                       }
+               }
+       }
+
+       mutex_unlock(&i2c_rw_access);
+       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 ret = 0;
+
+       mutex_lock(&i2c_rw_access);
+       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("%s: i2c_transfer(write) error, ret=%d",
+                                 __func__, ret);
+               }
+       }
+       mutex_unlock(&i2c_rw_access);
+
+       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)
+{
+       u8 buf[2] = { 0 };
+
+       buf[0] = regaddr;
+       buf[1] = regvalue;
+       return fts_i2c_write(client, buf, sizeof(buf));
+}
+
+/************************************************************************
+* 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)
+{
+       return fts_i2c_read(client, &regaddr, 1, regvalue, 1);
+}
+
+/************************************************************************
+* Name: fts_i2c_init
+* Brief: fts i2c init
+* Input:
+* Output:
+* Return:
+***********************************************************************/
+int fts_i2c_init(void)
+{
+       FTS_FUNC_ENTER();
+
+       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;
+}
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
new file mode 100644 (file)
index 0000000..0fa5617
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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_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
+*****************************************************************************/
+
+/*****************************************************************************
+* 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
+
+/*****************************************************************************
+* Private enumerations, structures and unions using typedef
+*****************************************************************************/
+
+/*****************************************************************************
+* 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)
+{
+
+#if FTS_MT_PROTOCOL_B_EN
+       unsigned int finger_count = 0;
+
+       FTS_FUNC_ENTER();
+
+       for (finger_count = 0; finger_count < FTS_MAX_POINTS; 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);
+
+       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));
+
+}
+
+/*****************************************************************************
+*  Name: fts_point_report_check_init
+*  Brief:
+*  Input:
+*  Output:
+*  Return: < 0: Fail to create esd check queue
+*****************************************************************************/
+int fts_point_report_check_init(void)
+{
+       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"
+                               "fts_point_report_check_workqueue!!");
+       } else {
+               FTS_DEBUG("[POINT_REPORT]: Success to create"
+                               "fts_point_report_check_workqueue!!");
+       }
+
+       FTS_FUNC_EXIT();
+
+       return 0;
+}
+
+/*****************************************************************************
+*  Name: fts_point_report_check_exit
+*  Brief:
+*  Input:
+*  Output:
+*  Return:
+*****************************************************************************/
+int fts_point_report_check_exit(void)
+{
+       FTS_FUNC_ENTER();
+
+       destroy_workqueue(fts_point_report_check_workqueue);
+
+       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
new file mode 100644 (file)
index 0000000..4a62ee6
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ *
+ * FocalTech TouchScreen driver.
+ *
+ * Copyright (c) 2010-2016, 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/FT8716_app_sample.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i b/drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i
new file mode 100644 (file)
index 0000000..f031758
--- /dev/null
@@ -0,0 +1,244 @@
+0x2, 0x9, 0x9b, 0xca, 0x39, 0x12, 0xc, 0x4b, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+    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, 0xff, 0x2, 0xa, 0x70, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc,
+    0x36, 0x12, 0xc, 0x1d, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+    0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+    0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+    0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+    0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3, 0x7e, 0x35, 0xc,
+    0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+    0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+    0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3,
+    0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+    0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+    0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+    0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x8, 0xf3, 0x80, 0x19, 0x74, 0x2,
+    0x12, 0x8, 0x3d, 0x5e, 0x70, 0xf4, 0x12, 0x9, 0xe7, 0x7e, 0x35, 0xc, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0x42, 0xd3, 0xda, 0x3b,
+    0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xc, 0x60, 0xf3, 0x9f, 0x46,
+    0xb9, 0x2, 0xfd, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21, 0x14, 0x78, 0x3, 0x2, 0x2,
+    0xbf, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x30, 0x1b, 0xb1, 0x78, 0x3, 0x2,
+    0x2, 0x7c, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x8d, 0x1b, 0xb1, 0x78, 0x3,
+    0x2, 0x2, 0xa6, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xbb, 0x24, 0xaf, 0x78,
+    0x3, 0x2, 0x3, 0x29, 0x24, 0xfd, 0x68, 0x2d, 0x14, 0x78, 0x3, 0x2, 0x2,
+    0xc2, 0x14, 0x78, 0x3, 0x2, 0x2, 0xbf, 0x1b, 0xb2, 0x78, 0x3, 0x2, 0x2,
+    0xbf, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12, 0x24, 0xeb, 0x68,
+    0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xbf, 0x24, 0x77, 0x68, 0x3, 0x2,
+    0x3, 0x33, 0x2, 0x3, 0x30, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x16, 0x0,
+    0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2,
+    0x80, 0x3, 0x2, 0x3, 0x33, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78,
+    0x3, 0x2, 0x3, 0x33, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68,
+    0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8,
+    0x0, 0x3e, 0x2, 0x2, 0x4d, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0x4d, 0x2, 0x2,
+    0xe7, 0x2, 0x2, 0xee, 0x2, 0x3, 0x6, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16,
+    0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x39,
+    0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39, 0x2e,
+    0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10,
+    0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39, 0x69,
+    0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x33,
+    0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x25, 0x7c,
+    0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2,
+    0x3, 0x33, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8, 0x1,
+    0x4a, 0x7a, 0xd, 0x39, 0x2, 0x2, 0xd6, 0x2, 0x2, 0xe7, 0xa, 0x57, 0x6d,
+    0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+    0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+    0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0x25, 0xbe, 0x60, 0x1, 0x68, 0x9,
+    0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+    0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+    0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe,
+    0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3,
+    0x33, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2, 0x22, 0x1b,
+    0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68, 0x38, 0x1b,
+    0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3, 0x6d, 0x11,
+    0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa, 0x57,
+    0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd, 0x39, 0x69,
+    0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa,
+    0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79, 0x30, 0x0, 0x4,
+    0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32,
+    0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22, 0x7e, 0x34,
+    0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0xca, 0x3b, 0x7a, 0x15,
+    0x8, 0x7f, 0x31, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x0, 0x38, 0x4f, 0x7e,
+    0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe, 0x1, 0x80, 0x43, 0x7e, 0x34,
+    0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xc,
+    0x1, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x8, 0x2e, 0x38,
+    0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2,
+    0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e,
+    0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe, 0x34, 0x0, 0x80, 0x78, 0xe0,
+    0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38, 0xb4, 0xe5, 0xe, 0x60, 0x5,
+    0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8, 0x7a, 0x35, 0x11, 0x7f, 0x13,
+    0x7e, 0x8, 0x2, 0x56, 0x12, 0xc, 0x1, 0x6d, 0x33, 0x80, 0x17, 0x7e, 0x35,
+    0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c, 0x76,
+    0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0x7e, 0x35,
+    0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b, 0x22, 0x80, 0x18, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22,
+    0x78, 0xe0, 0x22, 0x56, 0x30, 0x2e, 0x36, 0x4d, 0x61, 0x79, 0x20, 0x30,
+    0x37, 0x20, 0x32, 0x30, 0x31, 0x35, 0x0, 0x46, 0x54, 0x53, 0x38, 0x36, 0x30,
+    0x36, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xb, 0xbd,
+    0x2, 0x5, 0x66, 0x7e, 0x35, 0x2e, 0x1b, 0x34, 0x68, 0x57, 0x1b, 0x35, 0x78,
+    0x3, 0x2, 0x4, 0xb3, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4, 0xdd, 0xb, 0x35, 0x68,
+    0x3, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x30,
+    0x5, 0x5, 0x12, 0xb, 0xf0, 0xc2, 0x5, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x4,
+    0x7a, 0x35, 0xc, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8,
+    0x12, 0x0, 0x46, 0xd2, 0x5, 0x7e, 0x2d, 0x33, 0x69, 0x12, 0x0, 0x4, 0x69,
+    0x32, 0x0, 0x2, 0xb, 0x2a, 0x20, 0x12, 0x9, 0x48, 0x2e, 0x34, 0x10, 0x0,
+    0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7e, 0x34, 0x1, 0x0, 0x7a,
+    0x35, 0x11, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e,
+    0x14, 0x0, 0x8, 0x12, 0xc, 0x1, 0x20, 0x0, 0x3, 0x2, 0x5, 0x52, 0x7e, 0x1d,
+    0x33, 0x29, 0xb1, 0x0, 0x8, 0xf5, 0x91, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a,
+    0x35, 0x2e, 0x7a, 0x35, 0x30, 0x7e, 0x18, 0x0, 0x16, 0x7a, 0x1d, 0xa, 0x7e,
+    0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12,
+    0x3, 0x34, 0x12, 0xb, 0xf0, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d,
+    0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5,
+    0x23, 0xb4, 0x80, 0xb, 0xe4, 0x12, 0xa, 0x32, 0x74, 0x1, 0x12, 0xa, 0x32,
+    0x80, 0x4e, 0x12, 0x6, 0xd8, 0x80, 0x49, 0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5,
+    0x23, 0xb4, 0x80, 0x11, 0x7e, 0xf0, 0x1, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb,
+    0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4, 0x80, 0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf,
+    0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5,
+    0x37, 0xa, 0x3b, 0x9e, 0x34, 0x0, 0x80, 0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9,
+    0x7c, 0xbe, 0x12, 0x5, 0x6d, 0xb, 0xe0, 0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd,
+    0x38, 0xf1, 0x12, 0xb, 0xf0, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30,
+    0x4, 0x11, 0x7e, 0x34, 0x13, 0x88, 0x12, 0x3, 0xdd, 0x7e, 0x34, 0x13, 0x88,
+    0x12, 0x3, 0xdd, 0x75, 0xe9, 0xff, 0x30, 0x6, 0x3, 0x2, 0x4, 0x26, 0x22,
+    0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x80, 0x4a, 0xd2, 0x7, 0x12, 0xb,
+    0xdd, 0x74, 0x20, 0xca, 0xb8, 0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11,
+    0x14, 0x78, 0xfb, 0xda, 0xb8, 0x12, 0xb, 0x44, 0xa9, 0xd2, 0xb4, 0x12, 0xc,
+    0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4,
+    0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xc,
+    0x5c, 0x2, 0x6, 0x3f, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0x3, 0xdd,
+    0xd2, 0x86, 0x2, 0x6, 0x3f, 0x74, 0x1, 0x12, 0x7, 0xd5, 0x74, 0x1, 0x6d,
+    0x33, 0x12, 0x9, 0xe7, 0xe4, 0x12, 0x8, 0x3d, 0x5e, 0x34, 0x80, 0x0, 0x7c,
+    0x4f, 0x6c, 0x55, 0x3e, 0x24, 0x4d, 0x32, 0x12, 0x9, 0xe7, 0x74, 0x4, 0x6d,
+    0x33, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x50, 0x12, 0x9, 0xe7, 0x7e, 0x34,
+    0x0, 0x19, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0x9,
+    0xe7, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0,
+    0x11, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3, 0xdd, 0x74, 0x4,
+    0x7e, 0x34, 0x0, 0x10, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3,
+    0xdd, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5, 0x12,
+    0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12,
+    0x9, 0xe7, 0xda, 0xf8, 0x22, 0xca, 0x3b, 0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12,
+    0x7c, 0xb7, 0xf5, 0x13, 0x74, 0x1, 0x7e, 0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34,
+    0x4e, 0x60, 0x80, 0x12, 0x9, 0xe7, 0x12, 0x7, 0xd5, 0xa9, 0xc2, 0xb4, 0xa9,
+    0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75,
+    0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33, 0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35,
+    0x14, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+    0xb3, 0x7e, 0x35, 0x14, 0x5e, 0x34, 0x0, 0x1, 0xbe, 0x34, 0x0, 0x1, 0x78,
+    0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0x3, 0xdd, 0x7e, 0x35, 0x14, 0xb, 0x34,
+    0x7a, 0x35, 0x14, 0x7e, 0x35, 0x10, 0xbe, 0x35, 0x14, 0x38, 0xcb, 0xa9,
+    0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5,
+    0xda, 0x3b, 0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16, 0xd2, 0x7, 0x12, 0xb, 0xdd,
+    0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xc, 0x36, 0xa9, 0xd2, 0xb4, 0x12, 0x0,
+    0x2e, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0x7, 0xd5, 0xe4, 0x6d, 0x33, 0x12,
+    0x9, 0xe7, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9, 0xe7, 0x74, 0x4, 0x6d, 0x33,
+    0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x54, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0,
+    0x19, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x55, 0x12, 0x9, 0xe7,
+    0x7e, 0x34, 0xa2, 0x1c, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x15,
+    0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0x3, 0xdd, 0x74, 0x4, 0x7e,
+    0x34, 0x0, 0x14, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x19, 0x12, 0x3, 0xdd,
+    0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5,
+    0x12, 0x3, 0xdd, 0xe4, 0x12, 0x7, 0xd5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7,
+    0x2, 0x9, 0xe7, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24, 0xfd, 0x68,
+    0x38, 0x1b, 0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b, 0xb2, 0x68,
+    0x3e, 0x24, 0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5, 0xbf, 0x0, 0x5,
+    0x7e, 0xa0, 0x86, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e, 0xa0, 0xa6, 0x80,
+    0x3a, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31, 0xa5, 0xbf, 0x1,
+    0x2d, 0x7e, 0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d, 0x39, 0x2d, 0x31,
+    0x29, 0xa1, 0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80, 0x16, 0xa5, 0xbf,
+    0x0, 0x9, 0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80, 0x9, 0xa5, 0xbf,
+    0x1, 0x5, 0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22, 0xca, 0x79, 0xbe,
+    0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0x8, 0x3d, 0x7d, 0x73, 0x6c, 0xff,
+    0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x6c, 0xff, 0x7e, 0xf0, 0xf,
+    0x7d, 0x37, 0x12, 0x9, 0xe7, 0x6c, 0xff, 0x7e, 0xf0, 0x6a, 0x7d, 0x37, 0x12,
+    0x9, 0xe7, 0x7e, 0x34, 0x0, 0x5, 0x12, 0x3, 0xdd, 0x80, 0x30, 0x74, 0x1,
+    0x7e, 0x34, 0xdf, 0xff, 0x12, 0x9, 0xe7, 0x74, 0x6, 0x12, 0x8, 0x3d, 0x7d,
+    0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0x7d, 0x37, 0x12, 0x9, 0xe7,
+    0x7d, 0x37, 0x12, 0x9, 0xe7, 0x74, 0x2, 0x12, 0x8, 0x3d, 0x7d, 0x73, 0x4e,
+    0xf0, 0x1, 0x7d, 0x37, 0x12, 0x9, 0xe7, 0xda, 0x79, 0x22, 0xa9, 0xc2, 0xb4,
+    0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+    0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0,
+    0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+    0xb3, 0x75, 0xb5, 0x0, 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,
+    0xca, 0xf8, 0x7e, 0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91, 0x20,
+    0x87, 0x3, 0x7e, 0xf1, 0xe4, 0x30, 0x6, 0x30, 0x7e, 0x34, 0x0, 0x2, 0x7a,
+    0x35, 0x11, 0x7e, 0x18, 0x7, 0x80, 0x7e, 0x8, 0x0, 0x8, 0x12, 0xc, 0x1,
+    0xe5, 0x8, 0xbe, 0xb0, 0xff, 0x68, 0x17, 0xe5, 0x8, 0x60, 0x13, 0xe5, 0x9,
+    0xa, 0x2b, 0xe5, 0x8, 0xa, 0x3b, 0x2d, 0x32, 0xbe, 0x34, 0x0, 0xff, 0x78,
+    0x3, 0x7e, 0xf1, 0x8, 0x5e, 0xf0, 0xfe, 0x7a, 0xf1, 0x92, 0xd2, 0xe8, 0xc2,
+    0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0xf8, 0x22, 0x7f,
+    0x70, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0x74, 0x2, 0x12, 0xb, 0x44, 0x6d, 0x33,
+    0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5, 0xb5, 0xa9, 0x36,
+    0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10, 0xbd, 0x23, 0x38,
+    0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+    0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34,
+    0x1, 0xf4, 0x38, 0x3, 0x2, 0xc, 0x5c, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88,
+    0x12, 0x3, 0xdd, 0xd2, 0x86, 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, 0x75, 0x84,
+    0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b, 0x44, 0x78, 0xf9,
+    0x7e, 0xf8, 0x2, 0xd5, 0xd2, 0x5, 0xc2, 0x6, 0x75, 0x16, 0x0, 0x75, 0x17,
+    0x0, 0x75, 0x18, 0x0, 0xd2, 0x0, 0xc2, 0x2, 0xc2, 0x3, 0xc2, 0x4, 0x75,
+    0x21, 0x0, 0x75, 0x22, 0x0, 0x75, 0x23, 0x80, 0x75, 0x2e, 0x0, 0x75, 0x2f,
+    0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75, 0x37, 0xb,
+    0x75, 0x38, 0x0, 0x75, 0x3d, 0x1, 0x2, 0x4, 0x20, 0x7d, 0x23, 0xa, 0x36,
+    0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x1, 0xa9, 0x36,
+    0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5,
+    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, 0x7c, 0xab, 0xd2, 0x7, 0x12,
+    0xb, 0xdd, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23, 0x6d, 0x33, 0x12, 0xb, 0x44,
+    0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x41, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35,
+    0x17, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x5,
+    0xdc, 0x38, 0x3, 0x2, 0xc, 0x5c, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12,
+    0x3, 0xdd, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca, 0x1b, 0xca, 0xb, 0xd2, 0x0,
+    0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91, 0xe5, 0x38, 0x70, 0x3, 0x7a,
+    0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0x20, 0x5, 0x38, 0x30, 0x2, 0x6, 0xe4,
+    0x12, 0x7, 0x67, 0xf5, 0x91, 0x30, 0x91, 0xb, 0xc2, 0x91, 0x5, 0x38, 0xe5,
+    0x38, 0x12, 0x7, 0x67, 0xf5, 0x91, 0xda, 0xb, 0xda, 0x1b, 0xda, 0x2b, 0x32,
+    0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x23, 0x74, 0x2, 0x12, 0x8,
+    0x3d, 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6,
+    0xa9, 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x9, 0xe7, 0x74, 0x2,
+    0x12, 0x8, 0x3d, 0x80, 0x8, 0xe5, 0x23, 0xb4, 0x80, 0x3, 0x12, 0xb, 0x16,
+    0xda, 0xf8, 0x22, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0xa9, 0xc2, 0xb4, 0x74, 0x9f,
+    0x12, 0xc, 0x36, 0x12, 0xc, 0x1d, 0xa9, 0xd2, 0xb4, 0x60, 0x3, 0xb4, 0xff,
+    0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca, 0x75, 0xed,
+    0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea, 0x74, 0x1, 0x2,
+    0xa, 0xac, 0x22, 0xd2, 0x7, 0x12, 0xb, 0xdd, 0xa9, 0xc2, 0xb4, 0x74, 0x5,
+    0x12, 0xc, 0x36, 0x12, 0xc, 0x1d, 0x7c, 0xab, 0xa9, 0xd2, 0xb4, 0x5e, 0xa0,
+    0xe3, 0xa9, 0xc2, 0xb4, 0x74, 0x1, 0x12, 0xc, 0x36, 0x7c, 0xba, 0x12, 0xc,
+    0x36, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d,
+    0x12, 0x7c, 0xb3, 0xf5, 0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3,
+    0xf5, 0x13, 0x7c, 0xb7, 0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xc,
+    0x36, 0xe5, 0x14, 0x12, 0xc, 0x36, 0xe5, 0x13, 0x12, 0xc, 0x36, 0xe5, 0x12,
+    0x2, 0xc, 0x36, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5, 0xa, 0x44,
+    0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb, 0x12, 0xc,
+    0x36, 0xe5, 0x15, 0x12, 0xc, 0x36, 0xe5, 0x14, 0x12, 0xc, 0x36, 0xe5, 0x13,
+    0x12, 0xc, 0x36, 0xe4, 0x2, 0xc, 0x36, 0xd2, 0xcf, 0x85, 0x3d, 0xcc, 0x75,
+    0xec, 0xff, 0x75, 0xee, 0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0x40, 0xa9, 0xc5,
+    0xca, 0x75, 0xed, 0xf, 0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94,
+    0x22, 0x12, 0xb, 0x9c, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6,
+    0x12, 0xc, 0x2a, 0x12, 0xa, 0xe3, 0x12, 0x8, 0x9a, 0x12, 0xc, 0xf, 0xd2,
+    0xaf, 0x30, 0x3, 0xfd, 0x2, 0xc, 0x54, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4,
+    0x74, 0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xc, 0x36, 0xa9, 0xd2, 0xb4, 0x22,
+    0xe5, 0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12, 0x3,
+    0xdd, 0xd2, 0x86, 0x22, 0x12, 0xb, 0x71, 0x7e, 0x35, 0x11, 0x12, 0x0, 0xe,
+    0xa9, 0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1,
+    0x75, 0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9,
+    0xd1, 0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0xd3, 0x22, 0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x17,
+    0xd2, 0x8c, 0x22, 0x7e, 0x35, 0x17, 0xb, 0x34, 0x7a, 0x35, 0x17, 0x22, 0x85,
+    0x3d, 0xcc, 0xe5, 0x3d, 0x2, 0xa, 0xac, 0x2, 0xc, 0x4b, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i
new file mode 100644 (file)
index 0000000..ebb31f1
--- /dev/null
@@ -0,0 +1,248 @@
+0x2, 0x9, 0xb2, 0xca, 0x39, 0x12, 0xc, 0x71, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+    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, 0xff, 0x2, 0xa, 0x87, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc,
+    0x5c, 0x12, 0xc, 0x43, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+    0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+    0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+    0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+    0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa, 0x7e, 0x35, 0xc,
+    0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+    0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+    0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa,
+    0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+    0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+    0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+    0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x9, 0xa, 0x80, 0x19, 0x74, 0x2,
+    0x12, 0x8, 0xad, 0x5e, 0x70, 0xf4, 0x12, 0x9, 0xfe, 0x7e, 0x35, 0xc, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0x42, 0xd3, 0xda, 0x3b,
+    0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xc, 0x86, 0xf3, 0x79, 0x96,
+    0x69, 0x34, 0xcb, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21, 0x14, 0x78, 0x3, 0x2, 0x2,
+    0xcd, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x30, 0x1b, 0xb1, 0x78, 0x3, 0x2,
+    0x2, 0x7c, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x8d, 0x1b, 0xb1, 0x78, 0x3,
+    0x2, 0x2, 0xb4, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xc9, 0x24, 0xaf, 0x78,
+    0x3, 0x2, 0x3, 0x37, 0x24, 0xfd, 0x68, 0x2d, 0x14, 0x78, 0x3, 0x2, 0x2,
+    0xd0, 0x14, 0x78, 0x3, 0x2, 0x2, 0xcd, 0x1b, 0xb2, 0x78, 0x3, 0x2, 0x2,
+    0xcd, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12, 0x24, 0xeb, 0x68,
+    0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xcd, 0x24, 0x77, 0x68, 0x3, 0x2,
+    0x3, 0x41, 0x2, 0x3, 0x3e, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x16, 0x0,
+    0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2,
+    0x80, 0x3, 0x2, 0x3, 0x41, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78,
+    0x3, 0x2, 0x3, 0x41, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68,
+    0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8,
+    0x0, 0x3e, 0x2, 0x2, 0x4d, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0x4d, 0x2, 0x2,
+    0xf5, 0x2, 0x2, 0xfc, 0x2, 0x3, 0x14, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16,
+    0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x39,
+    0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39, 0x2e,
+    0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10,
+    0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39, 0x69,
+    0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x41,
+    0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x33, 0x7c,
+    0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2,
+    0x3, 0x41, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8, 0x1,
+    0x4a, 0x7a, 0xd, 0x39, 0x2, 0x2, 0xe4, 0x2, 0x2, 0xf5, 0xa, 0x57, 0x6d,
+    0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+    0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+    0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0x33, 0xbe, 0x60, 0x1, 0x68, 0x9,
+    0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+    0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+    0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x8, 0x7a,
+    0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x9, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5,
+    0xbe, 0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3,
+    0x2, 0x3, 0x41, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2,
+    0x22, 0x1b, 0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68,
+    0x38, 0x1b, 0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3,
+    0x6d, 0x11, 0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22,
+    0xa, 0x57, 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd,
+    0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0,
+    0x2, 0x1b, 0xa, 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79,
+    0x30, 0x0, 0x4, 0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30,
+    0x2d, 0x32, 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22,
+    0x7e, 0x34, 0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0xca, 0x3b,
+    0x7a, 0x15, 0x8, 0x7f, 0x31, 0x75, 0xe, 0x0, 0x7e, 0x35, 0x8, 0xbe, 0x34,
+    0x0, 0x0, 0x38, 0x4f, 0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe,
+    0x1, 0x80, 0x43, 0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e,
+    0x8, 0x2, 0x56, 0x12, 0xc, 0x27, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80,
+    0x7a, 0x35, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e,
+    0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c,
+    0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe,
+    0x34, 0x0, 0x80, 0x78, 0xe0, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38,
+    0xb4, 0xe5, 0xe, 0x60, 0x5, 0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8,
+    0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xc, 0x27, 0x6d,
+    0x33, 0x80, 0x17, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa,
+    0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34,
+    0x7a, 0x35, 0xf, 0x7e, 0x35, 0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b,
+    0x22, 0xe5, 0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12,
+    0xb, 0xb0, 0xd2, 0x86, 0x22, 0xff, 0x56, 0x30, 0x2e, 0x33, 0x4a, 0x75, 0x6c,
+    0x20, 0x32, 0x37, 0x20, 0x32, 0x30, 0x31, 0x36, 0x0, 0x46, 0x54, 0x53, 0x38,
+    0x36, 0x30, 0x37, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74,
+    0x12, 0xb, 0xf4, 0x2, 0x5, 0x66, 0x7e, 0x35, 0x2e, 0x1b, 0x34, 0x68, 0x57,
+    0x1b, 0x35, 0x78, 0x3, 0x2, 0x4, 0xb3, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4,
+    0xdd, 0xb, 0x35, 0x68, 0x3, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+    0x7a, 0x35, 0x30, 0x30, 0x5, 0x5, 0x12, 0x3, 0xee, 0xc2, 0x5, 0x7e, 0xd,
+    0x33, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0xc, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa,
+    0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46, 0xd2, 0x5, 0x7e, 0x2d, 0x33,
+    0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2, 0xb, 0x2a, 0x20, 0x12, 0x9,
+    0x5f, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+    0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x11, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0,
+    0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0xc, 0x27, 0x20, 0x0, 0x3,
+    0x2, 0x5, 0x52, 0x7e, 0x1d, 0x33, 0x29, 0xb1, 0x0, 0x8, 0xf5, 0x91, 0x2,
+    0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x7e, 0x18, 0x0,
+    0x16, 0x7a, 0x1d, 0xa, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa,
+    0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x3, 0x42, 0x12, 0x3, 0xee, 0x7e, 0x34,
+    0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30,
+    0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5, 0x23, 0xb4, 0x80, 0xb, 0xe4, 0x12, 0xa,
+    0x49, 0x74, 0x1, 0x12, 0xa, 0x49, 0x80, 0x4e, 0x12, 0x6, 0xd8, 0x80, 0x49,
+    0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5, 0x23, 0xb4, 0x80, 0x11, 0x7e, 0xf0, 0x1,
+    0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4, 0x80,
+    0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0,
+    0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5, 0x37, 0xa, 0x3b, 0x9e, 0x34, 0x0, 0x80,
+    0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5, 0x6d, 0xb, 0xe0,
+    0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd, 0x38, 0xf1, 0x12, 0x3, 0xee, 0x7e, 0x34,
+    0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30, 0x4, 0x11, 0x7e, 0x34, 0x13, 0x88, 0x12,
+    0xb, 0xb0, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0x75, 0xe9, 0xff, 0x30,
+    0x6, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4,
+    0x80, 0x4a, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0x20, 0xca, 0xb8, 0xa, 0x3f,
+    0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda, 0xb8, 0x12, 0xb,
+    0x2b, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+    0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x17, 0xbe, 0x34,
+    0x1, 0xf4, 0x38, 0x6, 0x12, 0xc, 0x82, 0x2, 0x6, 0x3f, 0xc2, 0x86, 0x7e,
+    0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 0x2, 0x6, 0x3f, 0x74, 0x1,
+    0x12, 0x8, 0x45, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0xe4, 0x12, 0x8,
+    0xad, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e, 0x24, 0x4d, 0x32,
+    0x12, 0x9, 0xfe, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0,
+    0x50, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4,
+    0x7e, 0x34, 0x0, 0x51, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xb,
+    0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0,
+    0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10, 0x12, 0x9, 0xfe,
+    0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9,
+    0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0xe4, 0x12, 0x8, 0x45, 0x74,
+    0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0x9, 0xfe, 0xda, 0xf8, 0x22, 0xca, 0x3b,
+    0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12, 0x7c, 0xb7, 0xf5, 0x13, 0x74, 0x1, 0x7e,
+    0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80, 0x12, 0x9, 0xfe, 0x12,
+    0x8, 0x45, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36,
+    0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+    0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33,
+    0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x14, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5,
+    0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x35, 0x14, 0x5e, 0x34, 0x0,
+    0x1, 0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0xb,
+    0xb0, 0x7e, 0x35, 0x14, 0xb, 0x34, 0x7a, 0x35, 0x14, 0x7e, 0x35, 0x10, 0xbe,
+    0x35, 0x14, 0x38, 0xcb, 0xa9, 0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb,
+    0xb0, 0xe4, 0x12, 0x8, 0x45, 0xda, 0x3b, 0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16,
+    0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xc, 0x5c,
+    0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0x8,
+    0x45, 0xe4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x9,
+    0xfe, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x54, 0x12,
+    0x9, 0xfe, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34,
+    0x0, 0x55, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xb, 0xb0, 0x74,
+    0x4, 0x7e, 0x34, 0x0, 0x15, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0xa0, 0x12,
+    0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x14, 0x12, 0x9, 0xfe, 0x7e, 0x34,
+    0x0, 0x19, 0x12, 0xb, 0xb0, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9,
+    0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0xe4, 0x12, 0x8, 0x45, 0x74,
+    0x4, 0x7e, 0x34, 0xff, 0xf7, 0x2, 0x9, 0xfe, 0xca, 0xf8, 0xc2, 0x7, 0x7e,
+    0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91, 0x20, 0x7, 0x10, 0x7e,
+    0xf1, 0xe4, 0xbe, 0xf0, 0x2, 0x40, 0x5, 0xbe, 0xf0, 0xfd, 0x28, 0x3, 0x7e,
+    0xf0, 0x70, 0x30, 0x6, 0x38, 0x7e, 0x34, 0x0, 0x2, 0x7a, 0x35, 0x11, 0x7e,
+    0x18, 0x7, 0x80, 0x7e, 0x8, 0x0, 0x8, 0x12, 0xc, 0x27, 0xe5, 0x8, 0xbe,
+    0xb0, 0xff, 0x68, 0x19, 0xe5, 0x8, 0x60, 0x15, 0xe5, 0x9, 0xa, 0x2b, 0xe5,
+    0x8, 0xa, 0x3b, 0x2d, 0x32, 0xbe, 0x34, 0x0, 0xff, 0x78, 0x5, 0x7e, 0xf1,
+    0x8, 0xd2, 0x7, 0x20, 0x7, 0x3, 0x7e, 0xf0, 0x70, 0x5e, 0xf0, 0xfe, 0x7a,
+    0xf1, 0x92, 0xd2, 0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2,
+    0xad, 0xda, 0xf8, 0x22, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24,
+    0xfd, 0x68, 0x38, 0x1b, 0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b,
+    0xb2, 0x68, 0x3e, 0x24, 0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5,
+    0xbf, 0x0, 0x5, 0x7e, 0xa0, 0x86, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e,
+    0xa0, 0xa7, 0x80, 0x3a, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31,
+    0xa5, 0xbf, 0x1, 0x2d, 0x7e, 0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d,
+    0x39, 0x2d, 0x31, 0x29, 0xa1, 0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80,
+    0x16, 0xa5, 0xbf, 0x0, 0x9, 0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80,
+    0x9, 0xa5, 0xbf, 0x1, 0x5, 0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22,
+    0xca, 0x79, 0xbe, 0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0x8, 0xad, 0x7d,
+    0x73, 0x6c, 0xff, 0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x6c, 0xff,
+    0x7e, 0xf0, 0xf, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x6c, 0xff, 0x7e, 0xf0, 0x6a,
+    0x7d, 0x37, 0x12, 0x9, 0xfe, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xb, 0xb0, 0x80,
+    0x30, 0x74, 0x1, 0x7e, 0x34, 0xdf, 0xff, 0x12, 0x9, 0xfe, 0x74, 0x6, 0x12,
+    0x8, 0xad, 0x7d, 0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x7d, 0x37,
+    0x12, 0x9, 0xfe, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0x74, 0x2, 0x12, 0x8, 0xad,
+    0x7d, 0x73, 0x4e, 0xf0, 0x1, 0x7d, 0x37, 0x12, 0x9, 0xfe, 0xda, 0x79, 0x22,
+    0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3,
+    0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 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, 0x7f, 0x70, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0x2, 0x12, 0xb,
+    0x2b, 0x6d, 0x33, 0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5,
+    0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10,
+    0xbd, 0x23, 0x38, 0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0, 0x2e,
+    0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35,
+    0x17, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x3, 0x2, 0xc, 0x82, 0xc2, 0x86, 0x7e,
+    0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 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, 0x75, 0x84, 0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0,
+    0x1b, 0x44, 0x78, 0xf9, 0x7e, 0xf8, 0x2, 0xd5, 0xd2, 0x5, 0xc2, 0x6, 0x75,
+    0x16, 0x0, 0x75, 0x17, 0x0, 0x75, 0x18, 0x0, 0xd2, 0x0, 0xc2, 0x2, 0xc2,
+    0x3, 0xc2, 0x4, 0x75, 0x21, 0x0, 0x75, 0x22, 0x0, 0x75, 0x23, 0x80, 0x75,
+    0x2e, 0x0, 0x75, 0x2f, 0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32,
+    0x0, 0x75, 0x37, 0xb, 0x75, 0x38, 0x0, 0x75, 0x3d, 0x1, 0x2, 0x4, 0x20,
+    0x7d, 0x23, 0xa, 0x36, 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+    0xb5, 0x1, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0xf5, 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,
+    0x7c, 0xab, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23,
+    0x6d, 0x33, 0x12, 0xb, 0x2b, 0xa9, 0xd2, 0xb4, 0x12, 0xc, 0x67, 0x12, 0x0,
+    0x2e, 0x50, 0x9, 0x7e, 0x35, 0x17, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e,
+    0x35, 0x17, 0xbe, 0x34, 0x5, 0xdc, 0x38, 0x3, 0x2, 0xc, 0x82, 0xc2, 0x86,
+    0x7e, 0x34, 0x13, 0x88, 0x12, 0xb, 0xb0, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca,
+    0x1b, 0xca, 0xb, 0xd2, 0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91,
+    0xe5, 0x38, 0x70, 0x3, 0x7a, 0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0x20, 0x5,
+    0x38, 0x30, 0x2, 0x6, 0xe4, 0x12, 0x7, 0xd7, 0xf5, 0x91, 0x30, 0x91, 0xb,
+    0xc2, 0x91, 0x5, 0x38, 0xe5, 0x38, 0x12, 0x7, 0xd7, 0xf5, 0x91, 0xda, 0xb,
+    0xda, 0x1b, 0xda, 0x2b, 0x32, 0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9, 0xc2, 0xb4,
+    0x74, 0x9f, 0x12, 0xc, 0x5c, 0x12, 0xc, 0x43, 0xa9, 0xd2, 0xb4, 0x60, 0x3,
+    0xb4, 0xff, 0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca,
+    0x75, 0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea,
+    0x74, 0x1, 0x2, 0xb, 0x58, 0x2, 0xa, 0xf8, 0xd2, 0x7, 0x12, 0xc, 0x14, 0xa9,
+    0xc2, 0xb4, 0x74, 0x5, 0x12, 0xc, 0x5c, 0x12, 0xc, 0x43, 0x7c, 0xab, 0xa9,
+    0xd2, 0xb4, 0xd2, 0x7, 0x12, 0xc, 0x14, 0x5e, 0xa0, 0xe3, 0xa9, 0xc2, 0xb4,
+    0x74, 0x1, 0x12, 0xc, 0x5c, 0x7c, 0xba, 0x12, 0xc, 0x5c, 0xa9, 0xd2, 0xb4,
+    0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d, 0x12, 0x7c, 0xb3, 0xf5,
+    0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3, 0xf5, 0x13, 0x7c, 0xb7,
+    0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xc, 0x5c, 0xe5, 0x14, 0x12,
+    0xc, 0x5c, 0xe5, 0x13, 0x12, 0xc, 0x5c, 0xe5, 0x12, 0x2, 0xc, 0x5c, 0xca,
+    0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x21, 0x74, 0x2, 0x12, 0x8, 0xad,
+    0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6, 0xa9,
+    0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x9, 0xfe, 0x74, 0x2, 0x12,
+    0x8, 0xad, 0xda, 0xf8, 0x22, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5,
+    0xa, 0x44, 0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb,
+    0x12, 0xc, 0x5c, 0xe5, 0x15, 0x12, 0xc, 0x5c, 0xe5, 0x14, 0x12, 0xc, 0x5c,
+    0xe5, 0x13, 0x12, 0xc, 0x5c, 0xe4, 0x2, 0xc, 0x5c, 0x80, 0x18, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22,
+    0x78, 0xe0, 0x22, 0xd2, 0xcf, 0x85, 0x3d, 0xcc, 0x75, 0xec, 0xff, 0x75,
+    0xee, 0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0x40, 0xa9, 0xc5, 0xca, 0x75, 0xed,
+    0xf, 0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0x12, 0xb,
+    0xd3, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6, 0x12, 0xc, 0x50,
+    0x12, 0xa, 0xc3, 0x12, 0x7, 0x67, 0x12, 0xc, 0x35, 0xd2, 0xaf, 0x30, 0x3,
+    0xfd, 0x2, 0xc, 0x7a, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4, 0x74, 0x6, 0x80,
+    0x2, 0x74, 0x4, 0x12, 0xc, 0x5c, 0xa9, 0xd2, 0xb4, 0x22, 0x12, 0xb, 0x85,
+    0x7e, 0x35, 0x11, 0x12, 0x0, 0xe, 0xa9, 0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c,
+    0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75, 0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75,
+    0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2,
+    0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1, 0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5,
+    0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xd3, 0x22, 0xc2, 0x8c,
+    0x6d, 0x33, 0x7a, 0x35, 0x17, 0xd2, 0x8c, 0x22, 0x7e, 0x35, 0x17, 0xb, 0x34,
+    0x7a, 0x35, 0x17, 0x22, 0x85, 0x3d, 0xcc, 0xe5, 0x3d, 0x2, 0xb, 0x58, 0x2,
+    0xc, 0x71, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i
new file mode 100644 (file)
index 0000000..805c8bf
--- /dev/null
@@ -0,0 +1,303 @@
+0x2, 0x3, 0x83, 0xca, 0x39, 0x12, 0xf, 0x3c, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+    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, 0xff, 0x2, 0xd, 0xf, 0xe5, 0x33, 0xb4, 0xc, 0xf, 0xc2, 0x86,
+    0xc2, 0x87, 0x7e, 0x34, 0x0, 0x64, 0x12, 0xe, 0x86, 0xd2, 0x86, 0xd2, 0x87,
+    0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x10, 0x7f, 0x31, 0xe5, 0x24,
+    0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+    0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0x16, 0x7e,
+    0x35, 0x14, 0xbe, 0x35, 0x16, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0x16, 0x7a,
+    0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0xa, 0xe6, 0x7e, 0x35, 0x14,
+    0x9e, 0x35, 0x16, 0x7a, 0x35, 0x14, 0x7e, 0x35, 0x16, 0x6d, 0x22, 0x2f,
+    0x31, 0x7e, 0x1d, 0x10, 0x2e, 0x35, 0x16, 0x7a, 0x1d, 0x10, 0x80, 0x27,
+    0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12,
+    0xa, 0xe6, 0x7e, 0x35, 0x14, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x14, 0x7e,
+    0x1d, 0x10, 0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x10, 0x2e, 0x38, 0x0, 0x80,
+    0x7e, 0x35, 0x14, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26,
+    0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0xa, 0xe6, 0x80, 0x19,
+    0x74, 0x2, 0x12, 0xa, 0x89, 0x5e, 0x70, 0xf4, 0x12, 0xc, 0x86, 0x7e, 0x35,
+    0x14, 0x7a, 0x35, 0x18, 0x7f, 0x13, 0x7e, 0xd, 0x10, 0x12, 0x8, 0xe, 0xd3,
+    0xda, 0x3b, 0x22, 0xa9, 0xc0, 0x93, 0x75, 0x39, 0x0, 0x32, 0xf, 0x60, 0xf0,
+    0x9f, 0x4c, 0xf1, 0xb3, 0xe, 0xce, 0xb9, 0x31, 0x46, 0xff, 0x0, 0xff, 0x0,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x22, 0x14, 0x78, 0x3,
+    0x2, 0x2, 0xda, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x3d, 0x1b, 0xb1, 0x78,
+    0x3, 0x2, 0x2, 0x89, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0x9a, 0x1b, 0xb1,
+    0x78, 0x3, 0x2, 0x2, 0xc1, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x2, 0xd6, 0x24,
+    0xaf, 0x78, 0x3, 0x2, 0x3, 0x3b, 0x24, 0xfd, 0x68, 0x3a, 0x14, 0x78, 0x3,
+    0x2, 0x2, 0xdd, 0x14, 0x78, 0x3, 0x2, 0x2, 0xda, 0x1b, 0xb2, 0x78, 0x3, 0x2,
+    0x2, 0xda, 0x24, 0xda, 0x68, 0x26, 0x24, 0xe6, 0x68, 0x1f, 0x24, 0xeb, 0x68,
+    0x3b, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x2, 0xda, 0x24, 0xe4, 0x78, 0x3, 0x2,
+    0x3, 0x46, 0x14, 0x78, 0x3, 0x2, 0x2, 0xda, 0x24, 0x94, 0x68, 0x3, 0x2, 0x3,
+    0x82, 0x2, 0x3, 0x42, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75, 0x3f, 0x0, 0x7c,
+    0x16, 0x2e, 0x10, 0x25, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe, 0x0, 0x2, 0x80,
+    0x3, 0x2, 0x3, 0x82, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0, 0x78, 0x3, 0x2,
+    0x3, 0x82, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14,
+    0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e, 0x8, 0x0, 0x44,
+    0x2, 0x2, 0x5a, 0x7e, 0x8, 0x1, 0x50, 0x2, 0x2, 0x5a, 0x2, 0x2, 0xfb, 0x2,
+    0x3, 0x2, 0x2, 0x3, 0x1a, 0xa, 0x27, 0x7e, 0xd, 0x3a, 0xb, 0x16, 0xb, 0xa,
+    0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd, 0x3a, 0x79, 0x30,
+    0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x3f, 0x7e, 0x2d, 0x3a, 0x2e, 0x54, 0x0,
+    0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a, 0x10, 0x7e, 0xd,
+    0x3a, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x3a, 0x69, 0x50, 0x0,
+    0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3, 0x82, 0xb2, 0x1,
+    0x7a, 0xd, 0x34, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0x7f, 0x7c, 0xb6, 0x1b,
+    0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3, 0x2, 0x3, 0x82,
+    0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x44, 0x80, 0x4, 0x7e, 0x8, 0x1, 0x50, 0x7a,
+    0xd, 0x3a, 0x2, 0x2, 0xf3, 0x2, 0x2, 0xfb, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd,
+    0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0,
+    0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x3a, 0x7a, 0x1d, 0x34, 0xd2, 0x2, 0x7e,
+    0x34, 0x0, 0x1, 0x2, 0x3, 0x7f, 0xbe, 0x60, 0x1, 0x68, 0x9, 0xa5, 0xbe, 0x2,
+    0x5, 0x7a, 0x71, 0x3e, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75, 0xe6, 0x0, 0xe4,
+    0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b, 0xb0, 0x7e, 0x34,
+    0x1, 0x5, 0x7a, 0x1b, 0xb0, 0x7e, 0x34, 0x1, 0x8, 0x7a, 0x1b, 0xb0, 0x7e,
+    0x34, 0x1, 0x9, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe, 0x1, 0x4,
+    0x7a, 0x71, 0x38, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3, 0x82,
+    0x7a, 0x71, 0x23, 0x22, 0x7a, 0x71, 0x33, 0x22, 0xd2, 0x2, 0x22, 0x7c, 0xb6,
+    0x1b, 0xb1, 0x68, 0x18, 0x14, 0x68, 0x1c, 0x14, 0x68, 0x31, 0x14, 0x68,
+    0x3a, 0xb, 0xb2, 0x68, 0x3, 0x2, 0x3, 0x82, 0xa, 0x37, 0x7d, 0x3, 0x6d,
+    0x11, 0x80, 0x59, 0xa, 0x57, 0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d,
+    0x44, 0x7e, 0xd, 0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+    0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e,
+    0xd, 0x3a, 0x79, 0x30, 0x0, 0x4, 0x22, 0xa, 0x27, 0x7e, 0xd, 0x3a, 0xb,
+    0x16, 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3,
+    0x80, 0x44, 0x7e, 0x34, 0x0, 0x4, 0x7a, 0x35, 0x2f, 0x75, 0x3f, 0x0, 0x22,
+    0x1b, 0x61, 0x68, 0x15, 0xb, 0x60, 0x78, 0x34, 0x7c, 0x27, 0x6c, 0x33, 0x6d,
+    0x0, 0x7e, 0x1d, 0x3a, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa,
+    0x57, 0x6d, 0x44, 0x7e, 0xd, 0x3a, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20,
+    0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0xe4, 0x7a, 0xb3, 0x2,
+    0xe4, 0x7e, 0x34, 0x0, 0x5, 0x7a, 0x35, 0x2f, 0x22, 0x75, 0x84, 0x1, 0x7e,
+    0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b, 0x44, 0x78, 0xf9, 0x7e,
+    0xf8, 0x2, 0xe8, 0xd2, 0x7, 0xc2, 0x8, 0x75, 0x3f, 0x0, 0x75, 0x40, 0x87,
+    0x75, 0x41, 0xa6, 0x75, 0x42, 0x0, 0x75, 0x43, 0x0, 0xd2, 0x0, 0xc2, 0x2,
+    0xc2, 0x3, 0xc2, 0x4, 0x75, 0x22, 0x0, 0x75, 0x23, 0x0, 0x75, 0x24, 0x80,
+    0x75, 0x2f, 0x0, 0x75, 0x30, 0x0, 0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75,
+    0x33, 0x0, 0x75, 0x38, 0xb, 0x75, 0x39, 0x0, 0x75, 0x3e, 0x1, 0x7e, 0x4,
+    0x0, 0xff, 0x7e, 0x14, 0xf, 0x50, 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,
+    0x4, 0x20, 0xff, 0xff, 0x56, 0x30, 0x2e, 0x35, 0x4a, 0x75, 0x6c, 0x20, 0x32,
+    0x33, 0x20, 0x32, 0x30, 0x31, 0x36, 0x0, 0x46, 0x54, 0x53, 0x38, 0x37, 0x31,
+    0x36, 0x5f, 0x70, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xe, 0x63,
+    0x2, 0x5, 0xbc, 0x7e, 0x35, 0x2f, 0x1b, 0x34, 0x68, 0x60, 0x1b, 0x35, 0x78,
+    0x3, 0x2, 0x4, 0xbc, 0x1b, 0x34, 0x78, 0x3, 0x2, 0x4, 0xe6, 0x1b, 0x34,
+    0x78, 0x3, 0x2, 0x5, 0x96, 0x2e, 0x34, 0x0, 0x3, 0x68, 0x3, 0x2, 0x5, 0xa8,
+    0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31, 0x30, 0x7, 0x5, 0x12, 0x0,
+    0x2e, 0xc2, 0x7, 0x7e, 0xd, 0x34, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0x14,
+    0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46,
+    0xd2, 0x7, 0x7e, 0x2d, 0x34, 0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2,
+    0xb, 0x2a, 0x20, 0x12, 0xb, 0xe2, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x91,
+    0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x15, 0x7e,
+    0xd, 0x34, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12,
+    0xe, 0xf2, 0x20, 0x0, 0x3, 0x2, 0x5, 0xa8, 0x7e, 0x1d, 0x34, 0x29, 0xb1,
+    0x0, 0x8, 0xf5, 0x91, 0x2, 0x5, 0xa8, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a,
+    0x35, 0x31, 0x7e, 0x18, 0x0, 0x3f, 0x7a, 0x1d, 0xe, 0x7e, 0xd, 0x34, 0x69,
+    0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x7, 0x62, 0x12,
+    0x0, 0x2e, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x91, 0x7e, 0x18, 0x10, 0x0,
+    0x7a, 0x1d, 0x8, 0xd2, 0x5, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31,
+    0xe5, 0x38, 0xb4, 0xa, 0x17, 0xe5, 0x24, 0xb4, 0x80, 0xc, 0xe4, 0x12, 0xc,
+    0xd1, 0x74, 0x1, 0x12, 0xc, 0xd1, 0x2, 0x5, 0x7f, 0x12, 0x8, 0xa4, 0x2, 0x5,
+    0x7f, 0xe5, 0x38, 0xb4, 0xb, 0x27, 0xe5, 0x24, 0xb4, 0x80, 0x11, 0x7e, 0xf0,
+    0x1, 0x7c, 0xbf, 0x12, 0x5, 0xc3, 0xb, 0xf0, 0xbe, 0xf0, 0x11, 0x78, 0xf4,
+    0x80, 0x51, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0xc3, 0xb, 0xf0, 0xbe,
+    0xf0, 0x40, 0x78, 0xf4, 0x80, 0x40, 0xe5, 0x38, 0xa, 0x3b, 0x9e, 0x34, 0x0,
+    0x80, 0x7c, 0xe7, 0xe5, 0x24, 0xb4, 0x80, 0x10, 0xa, 0x3e, 0x6d, 0x22, 0x74,
+    0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0x7a, 0x1d, 0x8, 0x80, 0xe, 0xa, 0x3e,
+    0x6d, 0x22, 0x74, 0xa, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0x7a, 0x1d, 0x8, 0x6c,
+    0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5, 0xc3, 0xb, 0xe0, 0xb, 0xd0, 0xe5,
+    0x23, 0xbc, 0xbd, 0x38, 0xf1, 0x7e, 0x1d, 0x8, 0x12, 0xe, 0xd, 0x92, 0x5,
+    0x12, 0x0, 0x2e, 0x30, 0x5, 0x1b, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x31,
+    0x80, 0x12, 0x6d, 0x33, 0x7a, 0x35, 0x2f, 0x7a, 0x35, 0x31, 0x7e, 0xd, 0x34,
+    0x69, 0x30, 0x0, 0x2, 0x12, 0x6, 0x98, 0x30, 0x4, 0x11, 0x7e, 0x34, 0x13,
+    0x88, 0x12, 0xe, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0x75, 0xe9,
+    0xff, 0x30, 0x8, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb, 0xe5,
+    0x24, 0xb4, 0x80, 0x4a, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0x20, 0xca, 0xb8,
+    0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda, 0xb8,
+    0x12, 0xd, 0xb3, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe, 0xca, 0x50,
+    0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x42,
+    0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xf, 0x4d, 0x2, 0x6, 0x95, 0xc2,
+    0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x2, 0x6, 0x95,
+    0x74, 0x1, 0x12, 0xa, 0x21, 0x74, 0x1, 0x6d, 0x33, 0x12, 0xc, 0x86, 0xe4,
+    0x12, 0xa, 0x89, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e, 0x24,
+    0x4d, 0x32, 0x12, 0xc, 0x86, 0x74, 0x4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x7e,
+    0x34, 0x0, 0x50, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86,
+    0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0xc, 0x86, 0x7e, 0x34, 0xa2, 0x1c,
+    0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0xc, 0x86, 0x7e,
+    0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10, 0x12,
+    0xc, 0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x6d, 0x33,
+    0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86, 0xe4, 0x12, 0xa,
+    0x21, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0xc, 0x86, 0xda, 0xf8, 0x22,
+    0xca, 0xf8, 0xe4, 0x7a, 0xb3, 0x2, 0xe4, 0xe5, 0x24, 0xbe, 0xb0, 0x80, 0x68,
+    0x9, 0x74, 0x1, 0x7a, 0xb3, 0x2, 0xe4, 0x2, 0x7, 0x5f, 0xbe, 0x34, 0xff,
+    0xff, 0x68, 0x6, 0xbe, 0x34, 0x0, 0x12, 0x50, 0x4, 0x7e, 0x34, 0x0, 0x12,
+    0x7d, 0x13, 0x6d, 0x0, 0x74, 0xc, 0x2f, 0x0, 0x14, 0x78, 0xfb, 0x7a, 0xd,
+    0xc, 0x7c, 0xb7, 0x12, 0x5, 0xc3, 0x7e, 0x1d, 0xc, 0x12, 0xe, 0xd, 0xe4,
+    0x33, 0x7c, 0xfb, 0xbe, 0xf0, 0x1, 0x78, 0xa, 0x7e, 0xb3, 0x2, 0xe4, 0x44,
+    0x2, 0x7a, 0xb3, 0x2, 0xe4, 0x6c, 0xaa, 0xa, 0x3a, 0x19, 0xa3, 0x2, 0xdc,
+    0xb, 0xa0, 0xbe, 0xa0, 0x8, 0x78, 0xf3, 0x7e, 0x34, 0x0, 0x8, 0x7a, 0x35,
+    0x14, 0x7e, 0x1d, 0xc, 0x7e, 0x8, 0x2, 0xdc, 0x12, 0x0, 0x46, 0x6c, 0xaa,
+    0xe4, 0xa, 0x4a, 0x19, 0xb4, 0x2, 0xdc, 0xb, 0xa0, 0xbe, 0xa0, 0x8, 0x78,
+    0xf3, 0x7e, 0x34, 0x0, 0x8, 0x7a, 0x35, 0x15, 0x7e, 0x1d, 0xc, 0x7e, 0x8,
+    0x2, 0xdc, 0x12, 0xe, 0xf2, 0x7e, 0xf0, 0x1, 0x6c, 0xaa, 0xa, 0x3a, 0x9,
+    0xb3, 0x2, 0xdc, 0xbc, 0xba, 0x68, 0x4, 0x6c, 0xff, 0x80, 0x7, 0xb, 0xa0,
+    0xbe, 0xa0, 0x8, 0x40, 0xeb, 0xbe, 0xf0, 0x1, 0x78, 0xa, 0x7e, 0xb3, 0x2,
+    0xe4, 0x44, 0x4, 0x7a, 0xb3, 0x2, 0xe4, 0x7e, 0xb3, 0x2, 0xe4, 0x44, 0x1,
+    0x7a, 0xb3, 0x2, 0xe4, 0xda, 0xf8, 0x22, 0xca, 0x3b, 0x7a, 0x15, 0xc, 0x7f,
+    0x31, 0x75, 0x12, 0x0, 0x7e, 0x35, 0xc, 0xbe, 0x34, 0x0, 0x0, 0x38, 0x4f,
+    0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0xc, 0x75, 0x12, 0x1, 0x80, 0x43, 0x7e,
+    0x34, 0x0, 0x80, 0x7a, 0x35, 0x15, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x5c, 0x12,
+    0xe, 0xf2, 0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x2e,
+    0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0x13, 0x7e, 0x35, 0x13, 0x9, 0x63,
+    0x2, 0x5c, 0x7e, 0xd, 0xe, 0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70,
+    0x7e, 0x35, 0x13, 0xb, 0x34, 0x7a, 0x35, 0x13, 0xbe, 0x34, 0x0, 0x80, 0x78,
+    0xe0, 0x7e, 0x35, 0xc, 0xbe, 0x34, 0x0, 0x80, 0x38, 0xb4, 0xe5, 0x12, 0x60,
+    0x5, 0xb, 0x34, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xc, 0x7a, 0x35, 0x15, 0x7f,
+    0x13, 0x7e, 0x8, 0x2, 0x5c, 0x12, 0xe, 0xf2, 0x6d, 0x33, 0x80, 0x17, 0x7e,
+    0x35, 0x13, 0x9, 0x63, 0x2, 0x5c, 0x7e, 0xd, 0xe, 0x7e, 0xb, 0x70, 0x6c,
+    0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0x13, 0xb, 0x34, 0x7a, 0x35, 0x13, 0x7e,
+    0x35, 0xc, 0xbe, 0x35, 0x13, 0x38, 0xde, 0xda, 0x3b, 0x22, 0xca, 0x3b, 0x7f,
+    0x30, 0x7c, 0xb6, 0xf5, 0x1a, 0x7c, 0xb7, 0xf5, 0x1b, 0x74, 0x1, 0x7e, 0x35,
+    0x18, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80, 0x12, 0xc, 0x86, 0x12, 0xa,
+    0x21, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x2, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+    0xb3, 0x85, 0x1a, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85,
+    0x1b, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x6d, 0x33, 0x80,
+    0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x1c, 0x7e, 0x1b, 0xb0, 0xf5, 0xb5, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e, 0x35, 0x1c, 0x5e, 0x34, 0x0, 0x1,
+    0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e, 0x34, 0x0, 0x78, 0x12, 0xe, 0x86,
+    0x7e, 0x35, 0x1c, 0xb, 0x34, 0x7a, 0x35, 0x1c, 0x7e, 0x35, 0x18, 0xbe, 0x35,
+    0x1c, 0x38, 0xcb, 0xa9, 0xd2, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86,
+    0xe4, 0x12, 0xa, 0x21, 0xda, 0x3b, 0x22, 0xe5, 0x24, 0xb4, 0x80, 0x16, 0xd2,
+    0x6, 0x12, 0xe, 0xdf, 0xa9, 0xc2, 0xb4, 0x74, 0x60, 0x12, 0xf, 0x27, 0xa9,
+    0xd2, 0xb4, 0x12, 0xe, 0xca, 0x40, 0xfb, 0x22, 0x74, 0x1, 0x12, 0xa, 0x21,
+    0xe4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x74, 0x1, 0x6d, 0x33, 0x12, 0xc, 0x86,
+    0x74, 0x4, 0x6d, 0x33, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x54, 0x12, 0xc,
+    0x86, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0,
+    0x55, 0x12, 0xc, 0x86, 0x7e, 0x34, 0xa2, 0x1c, 0x12, 0xe, 0x86, 0x74, 0x4,
+    0x7e, 0x34, 0x0, 0x15, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0xe,
+    0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x14, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0,
+    0x19, 0x12, 0xe, 0x86, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x4, 0x12, 0xc, 0x86,
+    0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86, 0xe4, 0x12, 0xa, 0x21, 0x74, 0x4,
+    0x7e, 0x34, 0xff, 0xf7, 0x2, 0xc, 0x86, 0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5,
+    0x22, 0x24, 0xfd, 0x68, 0x3c, 0x1b, 0xb1, 0x68, 0x26, 0x24, 0x9f, 0x68,
+    0x41, 0x1b, 0xb2, 0x68, 0x42, 0x24, 0x9e, 0x68, 0x39, 0x24, 0xe3, 0x68,
+    0x52, 0x24, 0x59, 0x78, 0x52, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x40, 0x80,
+    0x49, 0xa5, 0xbf, 0x1, 0x45, 0x7e, 0xa1, 0x41, 0x80, 0x40, 0xa5, 0xbf, 0x0,
+    0x5, 0x7e, 0xa1, 0x24, 0x80, 0x37, 0xa5, 0xbf, 0x1, 0x33, 0x7e, 0xa1, 0x3e,
+    0x80, 0x2e, 0xa, 0x17, 0x7e, 0x1d, 0x3a, 0x2d, 0x31, 0x29, 0xa1, 0x0, 0x8,
+    0x80, 0x21, 0x7e, 0xa1, 0x3f, 0x80, 0x1c, 0xa5, 0xbf, 0x0, 0x9, 0x7e, 0x35,
+    0x31, 0xa, 0x56, 0x7c, 0xab, 0x80, 0xf, 0xa5, 0xbf, 0x1, 0xb, 0x7e, 0x55,
+    0x31, 0x7c, 0xab, 0x80, 0x4, 0x7e, 0xa3, 0x2, 0xe4, 0x7c, 0xba, 0x22, 0xca,
+    0x79, 0x6c, 0xee, 0x7e, 0xf0, 0x70, 0x75, 0x91, 0x0, 0xc2, 0x90, 0xc2, 0x91,
+    0x30, 0x8, 0x31, 0x7e, 0x34, 0x0, 0x2, 0x7a, 0x35, 0x15, 0x9f, 0x11, 0x7e,
+    0x8, 0x0, 0xc, 0x12, 0xe, 0xf2, 0xe5, 0xc, 0xbe, 0xb0, 0xff, 0x68, 0x1a,
+    0xe5, 0xc, 0x60, 0x16, 0xe5, 0xd, 0xa, 0x2b, 0xe5, 0xc, 0xa, 0x3b, 0x2d,
+    0x32, 0xbe, 0x34, 0x0, 0xff, 0x78, 0x6, 0x7e, 0xf1, 0xc, 0x7e, 0xe0, 0x1,
+    0x4c, 0xee, 0x78, 0x1c, 0xa9, 0xd1, 0xcb, 0xd2, 0xcc, 0x12, 0xc, 0x35, 0x7c,
+    0xfb, 0xc2, 0xcc, 0xa9, 0xc1, 0xcb, 0xbe, 0xf0, 0x2, 0x40, 0x5, 0xbe, 0xf0,
+    0xfd, 0x28, 0x3, 0x7e, 0xf0, 0x70, 0x7c, 0xbf, 0x54, 0xfe, 0xf5, 0x92, 0xd2,
+    0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0x79,
+    0x22, 0xca, 0x79, 0xbe, 0xb0, 0x0, 0x28, 0x2e, 0x74, 0x6, 0x12, 0xa, 0x89,
+    0x7d, 0x73, 0x6c, 0xff, 0x7e, 0xf0, 0xa5, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x6c,
+    0xff, 0x7e, 0xf0, 0xf, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x6c, 0xff, 0x7e, 0xf0,
+    0x6a, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xe, 0x86,
+    0x80, 0x30, 0x74, 0x1, 0x7e, 0x34, 0xdf, 0xff, 0x12, 0xc, 0x86, 0x74, 0x6,
+    0x12, 0xa, 0x89, 0x7d, 0x73, 0x6c, 0xff, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x7d,
+    0x37, 0x12, 0xc, 0x86, 0x7d, 0x37, 0x12, 0xc, 0x86, 0x74, 0x2, 0x12, 0xa,
+    0x89, 0x7d, 0x73, 0x4e, 0xf0, 0x1, 0x7d, 0x37, 0x12, 0xc, 0x86, 0xda, 0x79,
+    0x22, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6,
+    0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5,
+    0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 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, 0x7f, 0x70, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0x2, 0x12,
+    0xd, 0xb3, 0x6d, 0x33, 0x80, 0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0,
+    0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25,
+    0x18, 0xbd, 0x23, 0x38, 0xe7, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe,
+    0xca, 0x50, 0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e,
+    0x35, 0x42, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x3, 0x2, 0xf, 0x4d, 0xc2, 0x86,
+    0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x22, 0xa9, 0xd1, 0xcb,
+    0xd2, 0xcc, 0x7e, 0x34, 0x0, 0x4, 0x7e, 0x8, 0x2, 0x5c, 0x74, 0xc, 0x12,
+    0xb, 0x8f, 0xa9, 0xd1, 0xcb, 0xc2, 0xcc, 0x6c, 0xaa, 0x7e, 0x70, 0x2, 0xac,
+    0x7a, 0x7e, 0x8, 0x2, 0x5c, 0x2d, 0x13, 0xb, 0xa, 0x30, 0x7d, 0x23, 0x7c,
+    0x45, 0x6c, 0x55, 0xa, 0x36, 0x4d, 0x32, 0x1b, 0xa, 0x30, 0xb, 0xa0, 0xbe,
+    0xa0, 0xc, 0x78, 0xde, 0x7e, 0x37, 0x2, 0x6c, 0x7d, 0x23, 0xa, 0x54, 0x7c,
+    0xa7, 0xb4, 0xe7, 0xb, 0xbe, 0xa0, 0x16, 0x78, 0x6, 0x75, 0x40, 0xe7, 0x75,
+    0x41, 0xa6, 0x22, 0x7e, 0x24, 0x0, 0x1, 0x7e, 0x7f, 0x2, 0xe5, 0x79, 0x27,
+    0x0, 0x6, 0x7e, 0x7f, 0x2, 0xe5, 0x69, 0x27, 0x0, 0x6, 0x4d, 0x22, 0x78,
+    0xf4, 0x5e, 0x60, 0x7f, 0x1b, 0x7a, 0x30, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x31,
+    0x0, 0x8, 0x4d, 0x33, 0x68, 0xf4, 0x6c, 0xaa, 0x80, 0x20, 0x6d, 0x44, 0x7e,
+    0x1f, 0x2, 0xe5, 0x1b, 0x1a, 0x40, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x41, 0x0,
+    0x8, 0x4d, 0x44, 0x68, 0xf4, 0x69, 0x41, 0x0, 0x2, 0x1b, 0xa, 0x40, 0xb,
+    0x15, 0xb, 0xa0, 0xbc, 0xba, 0x38, 0xdc, 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, 0x7e,
+    0x34, 0x0, 0x2, 0x7e, 0xf, 0x2, 0xe5, 0x79, 0x30, 0x0, 0x4, 0x7e, 0x34, 0x0,
+    0x1, 0x7e, 0xf, 0x2, 0xe5, 0x79, 0x30, 0x0, 0x6, 0x7e, 0xf, 0x2, 0xe5, 0x69,
+    0x30, 0x0, 0x6, 0x4d, 0x33, 0x78, 0xf4, 0x7e, 0x34, 0x0, 0x4, 0x1b, 0xa,
+    0x30, 0x7e, 0xf, 0x2, 0xe5, 0x69, 0x30, 0x0, 0x8, 0x4d, 0x33, 0x68, 0xf4,
+    0x6d, 0x33, 0x1b, 0xa, 0x30, 0x7e, 0x1f, 0x2, 0xe5, 0x69, 0x11, 0x0, 0x8,
+    0x4d, 0x11, 0x68, 0xf4, 0x69, 0x51, 0x0, 0x2, 0x5e, 0x54, 0x0, 0xfe, 0x22,
+    0x7d, 0x23, 0xa, 0x36, 0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+    0xb5, 0x1, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc,
+    0xa9, 0xc6, 0xb3, 0xf5, 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,
+    0x7c, 0xab, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23,
+    0x6d, 0x33, 0x12, 0xd, 0xb3, 0xa9, 0xd2, 0xb4, 0x12, 0xf, 0x32, 0x12, 0xe,
+    0xca, 0x50, 0x9, 0x7e, 0x35, 0x42, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e,
+    0x35, 0x42, 0xbe, 0x34, 0x5, 0xdc, 0x38, 0x3, 0x2, 0xf, 0x4d, 0xc2, 0x86,
+    0x7e, 0x34, 0x13, 0x88, 0x12, 0xe, 0x86, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca,
+    0x1b, 0xca, 0xb, 0xd2, 0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91,
+    0xe5, 0x39, 0x70, 0x3, 0x7a, 0x71, 0x22, 0xe5, 0x39, 0x12, 0x1, 0x20, 0x5,
+    0x39, 0x30, 0x2, 0x6, 0xe4, 0x12, 0x9, 0x33, 0xf5, 0x91, 0x30, 0x91, 0xb,
+    0xc2, 0x91, 0x5, 0x39, 0xe5, 0x39, 0x12, 0x9, 0x33, 0xf5, 0x91, 0xda, 0xb,
+    0xda, 0x1b, 0xda, 0x2b, 0x32, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0xa9, 0xc2, 0xb4,
+    0x74, 0x9f, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0xa9, 0xd2, 0xb4, 0x60, 0x3,
+    0xb4, 0xff, 0x1a, 0x75, 0x24, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca,
+    0x75, 0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea,
+    0x74, 0x1, 0x2, 0xd, 0xe0, 0x2, 0xd, 0x80, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0xa9,
+    0xc2, 0xb4, 0x74, 0x5, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0x7c, 0xab, 0xa9,
+    0xd2, 0xb4, 0xd2, 0x6, 0x12, 0xe, 0xdf, 0x5e, 0xa0, 0xe3, 0xa9, 0xc2, 0xb4,
+    0x74, 0x1, 0x12, 0xf, 0x27, 0x7c, 0xba, 0x12, 0xf, 0x27, 0xa9, 0xd2, 0xb4,
+    0x12, 0xe, 0xca, 0x40, 0xfb, 0x22, 0x7c, 0xab, 0x7d, 0x12, 0x7c, 0xb3, 0xf5,
+    0x1c, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c, 0xb3, 0xf5, 0x1b, 0x7c, 0xb7,
+    0xf5, 0x1a, 0xa9, 0xc2, 0xb4, 0x7c, 0xba, 0x12, 0xf, 0x27, 0xe5, 0x1c, 0x12,
+    0xf, 0x27, 0xe5, 0x1b, 0x12, 0xf, 0x27, 0xe5, 0x1a, 0x2, 0xf, 0x27, 0xca,
+    0xf8, 0x7c, 0xfb, 0xe5, 0x24, 0xb4, 0x81, 0x21, 0x74, 0x2, 0x12, 0xa, 0x89,
+    0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80, 0x6, 0xa9,
+    0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0xc, 0x86, 0x74, 0x2, 0x12,
+    0xa, 0x89, 0xda, 0xf8, 0x22, 0xd2, 0x6, 0x7e, 0x14, 0x0, 0x8, 0x7a, 0x15,
+    0x15, 0x7e, 0x8, 0x2, 0xdc, 0x12, 0xe, 0xf2, 0x6c, 0xaa, 0xa, 0x3a, 0x9,
+    0xb3, 0x2, 0xdc, 0xbe, 0xb0, 0xff, 0x68, 0x4, 0xc2, 0x6, 0x80, 0x7, 0xb,
+    0xa0, 0xbe, 0xa0, 0x8, 0x40, 0xea, 0xa2, 0x6, 0x22, 0x7d, 0x52, 0xf5, 0x19,
+    0x7c, 0xb6, 0x7c, 0xa5, 0xa, 0x44, 0xf5, 0x18, 0x7f, 0x21, 0xf5, 0x17, 0xa9,
+    0xc2, 0xb4, 0x74, 0xb, 0x12, 0xf, 0x27, 0xe5, 0x19, 0x12, 0xf, 0x27, 0xe5,
+    0x18, 0x12, 0xf, 0x27, 0xe5, 0x17, 0x12, 0xf, 0x27, 0xe4, 0x2, 0xf, 0x27,
+    0x12, 0xe, 0xa9, 0x12, 0xb, 0x3b, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x8, 0x30,
+    0x8, 0x6, 0x12, 0xf, 0x1b, 0x12, 0xd, 0x4b, 0x12, 0x9, 0xab, 0x12, 0xf, 0x0,
+    0xd2, 0xaf, 0x30, 0x3, 0xfd, 0x2, 0xf, 0x45, 0x80, 0x18, 0x0, 0x0, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x3e, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22, 0x78,
+    0xe0, 0x22, 0xd2, 0xcf, 0x85, 0x3e, 0xcc, 0x75, 0xec, 0xff, 0x75, 0xee,
+    0xff, 0x75, 0xeb, 0x3, 0x75, 0xac, 0xc0, 0xa9, 0xc5, 0xca, 0x75, 0xed, 0xf,
+    0x75, 0xad, 0xb0, 0xa9, 0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0xa9, 0xc2,
+    0xb4, 0x74, 0x5, 0x12, 0xf, 0x27, 0x12, 0xf, 0xe, 0xa9, 0xd2, 0xb4, 0x30,
+    0xe0, 0x2, 0xd3, 0x22, 0xc3, 0x22, 0xa9, 0xc2, 0xb4, 0x30, 0x6, 0x4, 0x74,
+    0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xf, 0x27, 0xa9, 0xd2, 0xb4, 0x22, 0x12,
+    0xe, 0x38, 0x7e, 0x35, 0x15, 0x12, 0x0, 0xe, 0xa9, 0xd2, 0xb4, 0xd3, 0x22,
+    0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75, 0x8a, 0x0, 0xd2, 0xa9,
+    0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xe5, 0xb5,
+    0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1, 0xb4, 0xa9, 0xc0, 0xb4,
+    0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xd3, 0x22,
+    0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x42, 0xd2, 0x8c, 0x22, 0x7e, 0x35,
+    0x42, 0xb, 0x34, 0x7a, 0x35, 0x42, 0x22, 0x85, 0x3e, 0xcc, 0xe5, 0x3e, 0x2,
+    0xd, 0xe0, 0x2, 0xf, 0x3c, 0x0, 0x1, 0x2, 0xe4, 0x0, 0x0, 0x4, 0x2, 0xe5,
+    0x0, 0x0, 0x9c, 0x0, 0x0, 0x0, 0xff,
diff --git a/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i
new file mode 100644 (file)
index 0000000..b1e3b1c
--- /dev/null
@@ -0,0 +1,288 @@
+0x2, 0x8, 0x9e, 0xca, 0x39, 0x12, 0xe, 0x6c, 0xda, 0x39, 0x32, 0x2, 0x0, 0x3,
+    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, 0xff, 0x2, 0xc, 0x47, 0xa9, 0xc2, 0xb4, 0x74, 0x5, 0x12, 0xe,
+    0x4d, 0x12, 0xe, 0x34, 0xa9, 0xd2, 0xb4, 0x30, 0xe0, 0x2, 0xd3, 0x22, 0xc3,
+    0x22, 0x2, 0x0, 0xf9, 0xca, 0x3b, 0x7a, 0xd, 0x8, 0x7f, 0x31, 0xe5, 0x23,
+    0xb4, 0x80, 0x2, 0x80, 0x3, 0x2, 0x0, 0xdc, 0x7f, 0x13, 0x5e, 0x34, 0x0,
+    0x7f, 0x7d, 0x23, 0x7e, 0x34, 0x0, 0x80, 0x9d, 0x32, 0x7a, 0x35, 0xe, 0x7e,
+    0x35, 0xc, 0xbe, 0x35, 0xe, 0x38, 0x2, 0x80, 0x5d, 0x7e, 0x35, 0xe, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba, 0x7e, 0x35, 0xc,
+    0x9e, 0x35, 0xe, 0x7a, 0x35, 0xc, 0x7e, 0x35, 0xe, 0x6d, 0x22, 0x2f, 0x31,
+    0x7e, 0x1d, 0x8, 0x2e, 0x35, 0xe, 0x7a, 0x1d, 0x8, 0x80, 0x27, 0x7e, 0x34,
+    0x0, 0x80, 0x7a, 0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba,
+    0x7e, 0x35, 0xc, 0x9e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0xc, 0x7e, 0x1d, 0x8,
+    0x2e, 0x34, 0x0, 0x80, 0x7a, 0x1d, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x7e, 0x35,
+    0xc, 0xbe, 0x34, 0x0, 0x80, 0x50, 0xd0, 0x4d, 0x33, 0x68, 0x26, 0x7a, 0x35,
+    0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0xa, 0xba, 0x80, 0x19, 0x74, 0x2,
+    0x12, 0xa, 0x5d, 0x5e, 0x70, 0xf4, 0x12, 0x3, 0xb4, 0x7e, 0x35, 0xc, 0x7a,
+    0x35, 0x10, 0x7f, 0x13, 0x7e, 0xd, 0x8, 0x12, 0x6, 0xeb, 0xd3, 0xda, 0x3b,
+    0x22, 0xa9, 0xc0, 0x93, 0x75, 0x38, 0x0, 0x32, 0xe, 0x8a, 0xf1, 0x75, 0xf4,
+    0xf8, 0xb, 0x7, 0xca, 0xca, 0x35, 0x35, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0xff, 0xac, 0xff, 0xac, 0x1,
+    0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x6b, 0xc2, 0x2, 0xe5, 0x21,
+    0x14, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0xb0,
+    0x1b, 0xb1, 0x78, 0x3, 0x2, 0x2, 0xfc, 0x1b, 0xb1, 0x78, 0x3, 0x2, 0x3, 0xd,
+    0x1b, 0xb1, 0x78, 0x3, 0x2, 0x3, 0x26, 0x24, 0xf9, 0x78, 0x3, 0x2, 0x3,
+    0x3b, 0x24, 0xaf, 0x78, 0x3, 0x2, 0x3, 0xa9, 0x24, 0xfd, 0x68, 0x2d, 0x14,
+    0x78, 0x3, 0x2, 0x3, 0x42, 0x14, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x1b, 0xb2,
+    0x78, 0x3, 0x2, 0x3, 0x3f, 0x24, 0xda, 0x68, 0x19, 0x24, 0xe6, 0x68, 0x12,
+    0x24, 0xeb, 0x68, 0x2e, 0x24, 0xf3, 0x78, 0x3, 0x2, 0x3, 0x3f, 0x24, 0x77,
+    0x68, 0x3, 0x2, 0x3, 0xb3, 0x2, 0x3, 0xb0, 0xbe, 0x60, 0x4, 0x50, 0xc, 0x75,
+    0x16, 0x0, 0x7c, 0x16, 0x2e, 0x10, 0x24, 0x7c, 0xb7, 0xa5, 0xf7, 0xa5, 0xbe,
+    0x0, 0x2, 0x80, 0x3, 0x2, 0x3, 0xb3, 0xd2, 0x2, 0x22, 0x7c, 0xb6, 0x24, 0x0,
+    0x78, 0x3, 0x2, 0x3, 0xb3, 0x1b, 0xb1, 0x68, 0x1e, 0x14, 0x68, 0x1e, 0x14,
+    0x68, 0x1e, 0x14, 0x68, 0x1e, 0xb, 0xb2, 0x78, 0x33, 0x30, 0x1, 0x7, 0x7e,
+    0x8, 0x0, 0x3e, 0x2, 0x2, 0xcd, 0x7e, 0x8, 0x1, 0x4a, 0x2, 0x2, 0xcd, 0x2,
+    0x3, 0x67, 0x2, 0x3, 0x6e, 0x2, 0x3, 0x86, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb,
+    0x16, 0xb, 0xa, 0x30, 0x2d, 0x32, 0x1b, 0xa, 0x30, 0x6d, 0x33, 0x7e, 0xd,
+    0x39, 0x79, 0x30, 0x0, 0x6, 0x22, 0x7c, 0xb7, 0x62, 0x16, 0x7e, 0x2d, 0x39,
+    0x2e, 0x54, 0x0, 0x6, 0xb, 0x2a, 0x20, 0x7d, 0x12, 0xb, 0x14, 0x1b, 0x2a,
+    0x10, 0x7e, 0xd, 0x39, 0x2d, 0x12, 0x39, 0x70, 0x0, 0x8, 0x7e, 0xd, 0x39,
+    0x69, 0x50, 0x0, 0x4, 0x69, 0x20, 0x0, 0x6, 0xbd, 0x25, 0x50, 0x3, 0x2, 0x3,
+    0xb3, 0xb2, 0x1, 0x7a, 0xd, 0x33, 0x7e, 0x34, 0x0, 0x2, 0x2, 0x3, 0xa5,
+    0x7c, 0xb6, 0x1b, 0xb1, 0x68, 0x1d, 0x14, 0x68, 0x1d, 0xb, 0xb1, 0x68, 0x3,
+    0x2, 0x3, 0xb3, 0x30, 0x1, 0x6, 0x7e, 0x8, 0x0, 0x3e, 0x80, 0x4, 0x7e, 0x8,
+    0x1, 0x4a, 0x7a, 0xd, 0x39, 0x2, 0x3, 0x56, 0x2, 0x3, 0x67, 0xa, 0x57, 0x6d,
+    0x44, 0x7e, 0xd, 0x39, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12,
+    0x79, 0x30, 0x0, 0x2, 0x1b, 0xa, 0x20, 0x7e, 0x1d, 0x39, 0x7a, 0x1d, 0x33,
+    0xd2, 0x2, 0x7e, 0x34, 0x0, 0x1, 0x2, 0x3, 0xa5, 0xbe, 0x60, 0x1, 0x68, 0x9,
+    0xa5, 0xbe, 0x2, 0x5, 0x7a, 0x71, 0x3d, 0xd2, 0x3, 0xd2, 0x2, 0x22, 0x75,
+    0xe6, 0x0, 0xe4, 0x7e, 0x34, 0x1, 0x4, 0x7e, 0x24, 0x0, 0xff, 0x7a, 0x1b,
+    0xb0, 0x7e, 0x34, 0x1, 0x5, 0x7a, 0x1b, 0xb0, 0xd2, 0x4, 0x22, 0xa5, 0xbe,
+    0x1, 0x4, 0x7a, 0x71, 0x37, 0x22, 0xa5, 0xbe, 0x2, 0x2, 0x80, 0x3, 0x2, 0x3,
+    0xb3, 0x7a, 0x71, 0x22, 0x22, 0x7a, 0x71, 0x32, 0x22, 0xd2, 0x2, 0x22, 0x1b,
+    0x61, 0x68, 0x21, 0x1b, 0x60, 0x68, 0x24, 0x1b, 0x60, 0x68, 0x38, 0x1b,
+    0x60, 0x68, 0x40, 0xb, 0x62, 0x78, 0x5d, 0xa, 0x37, 0x7d, 0x3, 0x6d, 0x11,
+    0x7e, 0x1d, 0x39, 0x79, 0x11, 0x0, 0x2, 0x1b, 0x1a, 0x0, 0x22, 0xa, 0x57,
+    0x7c, 0xab, 0xe4, 0x80, 0x2, 0xa, 0x57, 0x6d, 0x44, 0x7e, 0xd, 0x39, 0x69,
+    0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2f, 0x12, 0x79, 0x30, 0x0, 0x2, 0x1b, 0xa,
+    0x20, 0x22, 0x7c, 0x67, 0x6c, 0x77, 0x7e, 0xd, 0x39, 0x79, 0x30, 0x0, 0x4,
+    0x22, 0xa, 0x27, 0x7e, 0xd, 0x39, 0xb, 0x16, 0xb, 0xa, 0x30, 0x2d, 0x32,
+    0x1b, 0xa, 0x30, 0x7e, 0x34, 0x0, 0x3, 0x7a, 0x35, 0x2e, 0x22, 0x7e, 0x34,
+    0x0, 0x4, 0x7a, 0x35, 0x2e, 0x75, 0x16, 0x0, 0x22, 0x7d, 0x23, 0xa, 0x36,
+    0x7c, 0xa5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x1, 0xa9, 0x36,
+    0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5,
+    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, 0xff, 0x56, 0x30, 0x2e,
+    0x32, 0x5f, 0x4a, 0x75, 0x6e, 0x20, 0x32, 0x37, 0x20, 0x32, 0x30, 0x31,
+    0x36, 0x46, 0x54, 0x53, 0x38, 0x37, 0x33, 0x36, 0x5f, 0x50, 0x72, 0x61,
+    0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0xd, 0x73, 0x2, 0x5, 0x66, 0x7e, 0x35,
+    0x2e, 0x1b, 0x34, 0x68, 0x57, 0x1b, 0x35, 0x78, 0x3, 0x2, 0x4, 0xb3, 0x1b,
+    0x34, 0x78, 0x3, 0x2, 0x4, 0xdd, 0xb, 0x35, 0x68, 0x3, 0x2, 0x5, 0x52, 0x6d,
+    0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35, 0x30, 0x30, 0x5, 0x5, 0x12, 0xe, 0x7,
+    0xc2, 0x5, 0x7e, 0xd, 0x33, 0x69, 0x30, 0x0, 0x4, 0x7a, 0x35, 0xc, 0x69,
+    0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0x0, 0x46, 0xd2,
+    0x5, 0x7e, 0x2d, 0x33, 0x69, 0x12, 0x0, 0x4, 0x69, 0x32, 0x0, 0x2, 0xb,
+    0x2a, 0x20, 0x12, 0xb, 0xb6, 0x2e, 0x34, 0x10, 0x0, 0x2, 0x5, 0x4f, 0x6d,
+    0x33, 0x7a, 0x35, 0x2e, 0x7e, 0x34, 0x1, 0x0, 0x7a, 0x35, 0x11, 0x7e, 0xd,
+    0x33, 0x69, 0x30, 0x0, 0x2, 0xb, 0xa, 0x20, 0x2e, 0x14, 0x0, 0x8, 0x12, 0xe,
+    0x18, 0x20, 0x0, 0x3, 0x2, 0x5, 0x52, 0x7e, 0x1d, 0x33, 0x29, 0xb1, 0x0,
+    0x8, 0xf5, 0x91, 0x2, 0x5, 0x52, 0x6d, 0x33, 0x7a, 0x35, 0x2e, 0x7a, 0x35,
+    0x30, 0x7e, 0x18, 0x0, 0x16, 0x7a, 0x1d, 0xa, 0x7e, 0xd, 0x33, 0x69, 0x30,
+    0x0, 0x2, 0xb, 0xa, 0x20, 0x69, 0x10, 0x0, 0x4, 0x12, 0x6, 0x42, 0x12, 0xe,
+    0x7, 0x7e, 0x34, 0xf0, 0x55, 0x2, 0x5, 0x4f, 0x6d, 0x33, 0x7a, 0x35, 0x2e,
+    0x7a, 0x35, 0x30, 0xe5, 0x37, 0xb4, 0xa, 0x15, 0xe5, 0x23, 0xb4, 0x80, 0xb,
+    0xe4, 0x12, 0xc, 0x9, 0x74, 0x1, 0x12, 0xc, 0x9, 0x80, 0x4e, 0x12, 0x7,
+    0x81, 0x80, 0x49, 0xe5, 0x37, 0xb4, 0xb, 0x27, 0xe5, 0x23, 0xb4, 0x80, 0x11,
+    0x7e, 0xf0, 0x1, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb, 0xf0, 0xbe, 0xf0, 0x11,
+    0x78, 0xf4, 0x80, 0x2e, 0x7e, 0xf0, 0x4, 0x7c, 0xbf, 0x12, 0x5, 0x6d, 0xb,
+    0xf0, 0xbe, 0xf0, 0x40, 0x78, 0xf4, 0x80, 0x1d, 0xe5, 0x37, 0xa, 0x3b, 0x9e,
+    0x34, 0x0, 0x80, 0x7c, 0xe7, 0x6c, 0xdd, 0x80, 0x9, 0x7c, 0xbe, 0x12, 0x5,
+    0x6d, 0xb, 0xe0, 0xb, 0xd0, 0xe5, 0x22, 0xbc, 0xbd, 0x38, 0xf1, 0x12, 0xe,
+    0x7, 0x7e, 0x34, 0xf0, 0xaa, 0x7a, 0x35, 0x30, 0x30, 0x4, 0x11, 0x7e, 0x34,
+    0x13, 0x88, 0x12, 0xd, 0x96, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xd, 0x96, 0x75,
+    0xe9, 0xff, 0x30, 0x6, 0x3, 0x2, 0x4, 0x26, 0x22, 0xca, 0xf8, 0x7c, 0xfb,
+    0xe5, 0x23, 0xb4, 0x80, 0x4a, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0x74, 0x20, 0xca,
+    0xb8, 0xa, 0x3f, 0x6d, 0x22, 0x74, 0xc, 0x2f, 0x11, 0x14, 0x78, 0xfb, 0xda,
+    0xb8, 0x12, 0xd, 0x1b, 0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e,
+    0x50, 0x9, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35,
+    0x19, 0xbe, 0x34, 0x1, 0xf4, 0x38, 0x6, 0x12, 0xe, 0x7d, 0x2, 0x6, 0x3f,
+    0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12, 0xd, 0x96, 0xd2, 0x86, 0x2, 0x6,
+    0x3f, 0x74, 0x1, 0x12, 0x9, 0xf5, 0x74, 0x1, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+    0xe4, 0x12, 0xa, 0x5d, 0x5e, 0x34, 0x80, 0x0, 0x7c, 0x4f, 0x6c, 0x55, 0x3e,
+    0x24, 0x4d, 0x32, 0x12, 0x3, 0xb4, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+    0x7e, 0x34, 0x0, 0x50, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd,
+    0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x51, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0xa2,
+    0x1c, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x11, 0x12, 0x3, 0xb4,
+    0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x10,
+    0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4, 0x6d,
+    0x33, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0xe4, 0x12,
+    0x9, 0xf5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x12, 0x3, 0xb4, 0xda, 0xf8,
+    0x22, 0xca, 0x3b, 0x7a, 0x15, 0x8, 0x7f, 0x31, 0x7e, 0x35, 0x8, 0xbe, 0x34,
+    0x0, 0x0, 0x38, 0x4f, 0x7e, 0x34, 0xff, 0xff, 0x7a, 0x35, 0x8, 0x75, 0xe,
+    0x1, 0x80, 0x43, 0x7e, 0x34, 0x0, 0x80, 0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e,
+    0x8, 0x2, 0x56, 0x12, 0xe, 0x18, 0x7e, 0x35, 0x8, 0x9e, 0x34, 0x0, 0x80,
+    0x7a, 0x35, 0x8, 0x2e, 0x38, 0x0, 0x80, 0x6d, 0x33, 0x7a, 0x35, 0xf, 0x7e,
+    0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa, 0x7e, 0xb, 0x70, 0x6c,
+    0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34, 0x7a, 0x35, 0xf, 0xbe,
+    0x34, 0x0, 0x80, 0x78, 0xe0, 0x7e, 0x35, 0x8, 0xbe, 0x34, 0x0, 0x80, 0x38,
+    0xb4, 0xe5, 0xe, 0x60, 0x5, 0xb, 0x34, 0x7a, 0x35, 0x8, 0x7e, 0x35, 0x8,
+    0x7a, 0x35, 0x11, 0x7f, 0x13, 0x7e, 0x8, 0x2, 0x56, 0x12, 0xe, 0x18, 0x6d,
+    0x33, 0x80, 0x17, 0x7e, 0x35, 0xf, 0x9, 0x63, 0x2, 0x56, 0x7e, 0xd, 0xa,
+    0x7e, 0xb, 0x70, 0x6c, 0x76, 0x7a, 0xb, 0x70, 0x7e, 0x35, 0xf, 0xb, 0x34,
+    0x7a, 0x35, 0xf, 0x7e, 0x35, 0x8, 0xbe, 0x35, 0xf, 0x38, 0xde, 0xda, 0x3b,
+    0x22, 0xca, 0x3b, 0x7f, 0x30, 0x7c, 0xb6, 0xf5, 0x12, 0x7c, 0xb7, 0xf5,
+    0x13, 0x74, 0x1, 0x7e, 0x35, 0x10, 0x1e, 0x34, 0x1b, 0x34, 0x4e, 0x60, 0x80,
+    0x12, 0x3, 0xb4, 0x12, 0x9, 0xf5, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6, 0xb3, 0x75,
+    0xb5, 0x2, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9,
+    0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x12, 0xb5, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0x85, 0x13, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0x6d, 0x33, 0x80, 0x2a, 0x7f, 0x13, 0x2e, 0x35, 0x14, 0x7e,
+    0x1b, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x7e,
+    0x35, 0x14, 0x5e, 0x34, 0x0, 0x1, 0xbe, 0x34, 0x0, 0x1, 0x78, 0x7, 0x7e,
+    0x34, 0x0, 0x78, 0x12, 0xd, 0x96, 0x7e, 0x35, 0x14, 0xb, 0x34, 0x7a, 0x35,
+    0x14, 0x7e, 0x35, 0x10, 0xbe, 0x35, 0x14, 0x38, 0xcb, 0xa9, 0xd2, 0xb4,
+    0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0xe4, 0x12, 0x9, 0xf5, 0xda, 0x3b,
+    0x22, 0xe5, 0x23, 0xb4, 0x80, 0x16, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2,
+    0xb4, 0x74, 0x60, 0x12, 0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40,
+    0xfb, 0x22, 0x74, 0x1, 0x12, 0x9, 0xf5, 0xe4, 0x6d, 0x33, 0x12, 0x3, 0xb4,
+    0x74, 0x1, 0x6d, 0x33, 0x12, 0x3, 0xb4, 0x74, 0x4, 0x6d, 0x33, 0x12, 0x3,
+    0xb4, 0x7e, 0x34, 0x0, 0x54, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12,
+    0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x55, 0x12, 0x3, 0xb4, 0x7e, 0x34,
+    0xa2, 0x1c, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0, 0x15, 0x12, 0x3,
+    0xb4, 0x7e, 0x34, 0x0, 0xa0, 0x12, 0xd, 0x96, 0x74, 0x4, 0x7e, 0x34, 0x0,
+    0x14, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x19, 0x12, 0xd, 0x96, 0x74, 0x4,
+    0x7e, 0x34, 0x0, 0x4, 0x12, 0x3, 0xb4, 0x7e, 0x34, 0x0, 0x5, 0x12, 0xd,
+    0x96, 0xe4, 0x12, 0x9, 0xf5, 0x74, 0x4, 0x7e, 0x34, 0xff, 0xf7, 0x2, 0x3,
+    0xb4, 0xca, 0xf8, 0x7e, 0xf0, 0x70, 0xc2, 0x7, 0x75, 0x91, 0x0, 0xc2, 0x90,
+    0xc2, 0x91, 0x30, 0x6, 0x4e, 0x7e, 0x34, 0x0, 0x6, 0x7a, 0x35, 0x11, 0x7e,
+    0x18, 0xf, 0x80, 0x7e, 0x8, 0x2, 0xd6, 0x12, 0xe, 0x18, 0x7e, 0xb3, 0x2,
+    0xd6, 0x7e, 0x73, 0x2, 0xd7, 0x12, 0xd, 0xda, 0x92, 0x7, 0x30, 0x7, 0x6,
+    0x7e, 0xf3, 0x2, 0xd6, 0x80, 0x26, 0x7e, 0x34, 0x0, 0x6, 0x7a, 0x35, 0x11,
+    0x7e, 0x18, 0x11, 0x20, 0x7e, 0x8, 0x2, 0xf6, 0x12, 0xe, 0x18, 0x7e, 0xb3,
+    0x2, 0xf6, 0x7e, 0x73, 0x2, 0xf7, 0x12, 0xd, 0xda, 0x92, 0x7, 0x30, 0x7,
+    0x4, 0x7e, 0xf3, 0x2, 0xf6, 0x20, 0x6, 0x18, 0xd2, 0xcc, 0x12, 0xe, 0x58,
+    0x7c, 0xab, 0xc2, 0xcc, 0x7c, 0x7a, 0x6e, 0x70, 0xff, 0x12, 0xd, 0xda, 0x92,
+    0x7, 0x30, 0x7, 0x2, 0x7c, 0xfa, 0x5e, 0xf0, 0xfe, 0x7a, 0xf1, 0x92, 0xd2,
+    0xe8, 0xc2, 0xc0, 0xa9, 0xd5, 0xb7, 0xd2, 0xbd, 0xd2, 0xad, 0xda, 0xf8,
+    0x22, 0x75, 0x84, 0x1, 0x7e, 0x44, 0x1f, 0xff, 0xe4, 0x7a, 0x49, 0xb0, 0x1b,
+    0x44, 0x78, 0xf9, 0x7e, 0xf8, 0x3, 0x19, 0xd2, 0x5, 0xc2, 0x6, 0x75, 0x16,
+    0x0, 0x75, 0x17, 0x87, 0x75, 0x18, 0xc6, 0x75, 0x19, 0x0, 0x75, 0x1a, 0x0,
+    0xd2, 0x0, 0xc2, 0x2, 0xc2, 0x3, 0xc2, 0x4, 0x75, 0x21, 0x0, 0x75, 0x22,
+    0x0, 0x75, 0x23, 0x80, 0x75, 0x2e, 0x0, 0x75, 0x2f, 0x0, 0x75, 0x30, 0x0,
+    0x75, 0x31, 0x0, 0x75, 0x32, 0x0, 0x75, 0x37, 0xb, 0x75, 0x38, 0x0, 0x75,
+    0x3d, 0x1, 0x7e, 0x4, 0x0, 0xff, 0x7e, 0x14, 0xe, 0x80, 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, 0x4, 0x20, 0xca, 0x79, 0x7d, 0x73, 0x12, 0xe,
+    0x62, 0x7e, 0x34, 0x0, 0x1, 0x7e, 0xf, 0x3, 0x16, 0x79, 0x30, 0x0, 0x4,
+    0x7e, 0xf, 0x3, 0x16, 0x79, 0x30, 0x0, 0x6, 0x7e, 0x1f, 0x3, 0x16, 0x69,
+    0x11, 0x0, 0x6, 0x4d, 0x11, 0x68, 0x9, 0x7e, 0x15, 0x19, 0xbe, 0x14, 0x0,
+    0x3c, 0x28, 0xeb, 0x1b, 0x1a, 0x70, 0x7e, 0xf, 0x3, 0x16, 0x69, 0x30, 0x0,
+    0x8, 0x4d, 0x33, 0x78, 0x9, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x0, 0x3c, 0x28,
+    0xeb, 0x6d, 0x33, 0x1b, 0xa, 0x30, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x11, 0x0,
+    0x8, 0x4d, 0x11, 0x78, 0x9, 0x7e, 0x15, 0x19, 0xbe, 0x14, 0x0, 0x3c, 0x28,
+    0xeb, 0x69, 0x71, 0x0, 0x2, 0x12, 0xe, 0x7d, 0x7d, 0x37, 0xda, 0x79, 0x22,
+    0x7c, 0x7b, 0x7e, 0xa0, 0xef, 0xe5, 0x21, 0x24, 0xfd, 0x68, 0x38, 0x1b,
+    0xb1, 0x68, 0x22, 0x24, 0x9f, 0x68, 0x3d, 0x1b, 0xb2, 0x68, 0x3e, 0x24,
+    0x9e, 0x68, 0x35, 0x24, 0x3c, 0x78, 0x4c, 0xa5, 0xbf, 0x0, 0x5, 0x7e, 0xa1,
+    0x17, 0x80, 0x43, 0xa5, 0xbf, 0x1, 0x3f, 0x7e, 0xa1, 0x18, 0x80, 0x3a, 0xa5,
+    0xbf, 0x0, 0x5, 0x7e, 0xa1, 0x23, 0x80, 0x31, 0xa5, 0xbf, 0x1, 0x2d, 0x7e,
+    0xa1, 0x3d, 0x80, 0x28, 0xa, 0x17, 0x7e, 0x1d, 0x39, 0x2d, 0x31, 0x29, 0xa1,
+    0x0, 0x8, 0x80, 0x1b, 0x7e, 0xa1, 0x16, 0x80, 0x16, 0xa5, 0xbf, 0x0, 0x9,
+    0x7e, 0x35, 0x30, 0xa, 0x56, 0x7c, 0xab, 0x80, 0x9, 0xa5, 0xbf, 0x1, 0x5,
+    0x7e, 0x55, 0x30, 0x7c, 0xab, 0x7c, 0xba, 0x22, 0xca, 0x79, 0xbe, 0xb0, 0x0,
+    0x28, 0x2e, 0x74, 0x6, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x6c, 0xff, 0x7e, 0xf0,
+    0xa5, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x6c, 0xff, 0x7e, 0xf0, 0xf, 0x7d, 0x37,
+    0x12, 0x3, 0xb4, 0x6c, 0xff, 0x7e, 0xf0, 0x6a, 0x7d, 0x37, 0x12, 0x3, 0xb4,
+    0x7e, 0x34, 0x0, 0x5, 0x12, 0xd, 0x96, 0x80, 0x30, 0x74, 0x1, 0x7e, 0x34,
+    0xdf, 0xff, 0x12, 0x3, 0xb4, 0x74, 0x6, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x6c,
+    0xff, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x7d, 0x37, 0x12, 0x3, 0xb4, 0x7d, 0x37,
+    0x12, 0x3, 0xb4, 0x74, 0x2, 0x12, 0xa, 0x5d, 0x7d, 0x73, 0x4e, 0xf0, 0x1,
+    0x7d, 0x37, 0x12, 0x3, 0xb4, 0xda, 0x79, 0x22, 0xa9, 0xc2, 0xb4, 0xa9, 0xc6,
+    0xb3, 0x75, 0xb5, 0x5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5,
+    0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36,
+    0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9, 0xc6, 0xb3, 0x75,
+    0xb5, 0x0, 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, 0x7f, 0x70,
+    0xd2, 0x7, 0x12, 0xd, 0xf4, 0x74, 0x2, 0x12, 0xd, 0x1b, 0x6d, 0x33, 0x80,
+    0x12, 0x7f, 0x7, 0x2d, 0x13, 0x7e, 0xb, 0xb0, 0xf5, 0xb5, 0xa9, 0x36, 0xb3,
+    0xfc, 0xa9, 0xc6, 0xb3, 0xb, 0x34, 0x7e, 0x25, 0x10, 0xbd, 0x23, 0x38, 0xe7,
+    0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e, 0x35,
+    0x19, 0xbe, 0x34, 0x1, 0xf4, 0x28, 0xf2, 0x7e, 0x35, 0x19, 0xbe, 0x34, 0x1,
+    0xf4, 0x38, 0x3, 0x2, 0xe, 0x7d, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88, 0x12,
+    0xd, 0x96, 0xd2, 0x86, 0x22, 0xa9, 0xd1, 0xcb, 0xd2, 0xcc, 0x7e, 0x34, 0x0,
+    0x4, 0x7e, 0x8, 0x2, 0x56, 0x74, 0xc, 0x12, 0xb, 0x63, 0xa9, 0xd1, 0xcb,
+    0xc2, 0xcc, 0x6c, 0xaa, 0x7e, 0x70, 0x2, 0xac, 0x7a, 0x7e, 0x8, 0x2, 0x56,
+    0x2d, 0x13, 0xb, 0xa, 0x30, 0x7d, 0x23, 0x7c, 0x45, 0x6c, 0x55, 0xa, 0x36,
+    0x4d, 0x32, 0x1b, 0xa, 0x30, 0xb, 0xa0, 0xbe, 0xa0, 0xc, 0x78, 0xde, 0x7e,
+    0x37, 0x2, 0x66, 0x7d, 0x23, 0xa, 0x54, 0x7c, 0xa7, 0xb4, 0xe7, 0xb, 0xbe,
+    0xa0, 0x36, 0x78, 0x6, 0x75, 0x17, 0xe7, 0x75, 0x18, 0xc6, 0x22, 0x7e, 0x24,
+    0x0, 0x1, 0x7e, 0x7f, 0x3, 0x16, 0x79, 0x27, 0x0, 0x6, 0x7e, 0x7f, 0x3,
+    0x16, 0x69, 0x27, 0x0, 0x6, 0x4d, 0x22, 0x78, 0xf4, 0x5e, 0x60, 0x7f, 0x1b,
+    0x7a, 0x30, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x31, 0x0, 0x8, 0x4d, 0x33, 0x68,
+    0xf4, 0x6c, 0xaa, 0x80, 0x20, 0x6d, 0x44, 0x7e, 0x1f, 0x3, 0x16, 0x1b, 0x1a,
+    0x40, 0x7e, 0x1f, 0x3, 0x16, 0x69, 0x41, 0x0, 0x8, 0x4d, 0x44, 0x68, 0xf4,
+    0x69, 0x41, 0x0, 0x2, 0x1b, 0xa, 0x40, 0xb, 0x15, 0xb, 0xa0, 0xbc, 0xba,
+    0x38, 0xdc, 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, 0x7c, 0xab, 0xd2, 0x7,
+    0x12, 0xd, 0xf4, 0x74, 0xd8, 0xa, 0x3a, 0x7d, 0x23, 0x6d, 0x33, 0x12, 0xd,
+    0x1b, 0xa9, 0xd2, 0xb4, 0x12, 0xe, 0x62, 0x12, 0x0, 0x2e, 0x50, 0x9, 0x7e,
+    0x35, 0x19, 0xbe, 0x34, 0x5, 0xdc, 0x28, 0xf2, 0x7e, 0x35, 0x19, 0xbe, 0x34,
+    0x5, 0xdc, 0x38, 0x3, 0x2, 0xe, 0x7d, 0xc2, 0x86, 0x7e, 0x34, 0x13, 0x88,
+    0x12, 0xd, 0x96, 0xd2, 0x86, 0x22, 0xca, 0x2b, 0xca, 0x1b, 0xca, 0xb, 0xd2,
+    0x0, 0x30, 0x90, 0x1c, 0xc2, 0x90, 0x7e, 0x71, 0x91, 0xe5, 0x38, 0x70, 0x3,
+    0x7a, 0x71, 0x21, 0xe5, 0x38, 0x12, 0x1, 0xa0, 0x5, 0x38, 0x30, 0x2, 0x6,
+    0xe4, 0x12, 0x9, 0x87, 0xf5, 0x91, 0x30, 0x91, 0xb, 0xc2, 0x91, 0x5, 0x38,
+    0xe5, 0x38, 0x12, 0x9, 0x87, 0xf5, 0x91, 0xda, 0xb, 0xda, 0x1b, 0xda, 0x2b,
+    0x32, 0xca, 0xf8, 0x7c, 0xfb, 0xe5, 0x23, 0xb4, 0x81, 0x23, 0x74, 0x2, 0x12,
+    0xa, 0x5d, 0x4c, 0xff, 0x78, 0x8, 0xa9, 0xc0, 0xca, 0x5e, 0x70, 0xdf, 0x80,
+    0x6, 0xa9, 0xd0, 0xca, 0x4e, 0x70, 0x20, 0x74, 0x2, 0x12, 0x3, 0xb4, 0x74,
+    0x2, 0x12, 0xa, 0x5d, 0x80, 0x8, 0xe5, 0x23, 0xb4, 0x80, 0x3, 0x12, 0xc,
+    0xed, 0xda, 0xf8, 0x22, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2, 0xb4, 0x74,
+    0x9f, 0x12, 0xe, 0x4d, 0x12, 0xe, 0x34, 0xa9, 0xd2, 0xb4, 0x60, 0x3, 0xb4,
+    0xff, 0x1a, 0x75, 0x23, 0x81, 0xa9, 0xd5, 0xca, 0xa9, 0xd0, 0xca, 0x75,
+    0xed, 0x9f, 0x75, 0xad, 0x20, 0xa9, 0xd1, 0xea, 0xa9, 0xc1, 0xea, 0x74, 0x1,
+    0x2, 0xc, 0x83, 0x22, 0xd2, 0x7, 0x12, 0xd, 0xf4, 0xa9, 0xc2, 0xb4, 0x74,
+    0x5, 0x12, 0xe, 0x4d, 0x12, 0xe, 0x34, 0x7c, 0xab, 0xa9, 0xd2, 0xb4, 0x5e,
+    0xa0, 0xe3, 0xa9, 0xc2, 0xb4, 0x74, 0x1, 0x12, 0xe, 0x4d, 0x7c, 0xba, 0x12,
+    0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x12, 0x0, 0x2e, 0x40, 0xfb, 0x22, 0x7c, 0xab,
+    0x7d, 0x12, 0x7c, 0xb3, 0xf5, 0x14, 0x7c, 0x36, 0x7c, 0x25, 0xa, 0x4, 0x7c,
+    0xb3, 0xf5, 0x13, 0x7c, 0xb7, 0xf5, 0x12, 0xa9, 0xc2, 0xb4, 0x7c, 0xba,
+    0x12, 0xe, 0x4d, 0xe5, 0x14, 0x12, 0xe, 0x4d, 0xe5, 0x13, 0x12, 0xe, 0x4d,
+    0xe5, 0x12, 0x2, 0xe, 0x4d, 0x7d, 0x52, 0xf5, 0x15, 0x7c, 0xb6, 0x7c, 0xa5,
+    0xa, 0x44, 0xf5, 0x14, 0x7f, 0x21, 0xf5, 0x13, 0xa9, 0xc2, 0xb4, 0x74, 0xb,
+    0x12, 0xe, 0x4d, 0xe5, 0x15, 0x12, 0xe, 0x4d, 0xe5, 0x14, 0x12, 0xe, 0x4d,
+    0xe5, 0x13, 0x12, 0xe, 0x4d, 0xe4, 0x2, 0xe, 0x4d, 0x12, 0xd, 0xb9, 0x12,
+    0xb, 0xf, 0xa9, 0xa6, 0x94, 0xb3, 0x92, 0x6, 0x30, 0x6, 0x6, 0x12, 0xe,
+    0x41, 0x12, 0xc, 0xba, 0x12, 0x8, 0x10, 0x12, 0xe, 0x26, 0xd2, 0xaf, 0x30,
+    0x3, 0xfd, 0x2, 0xe, 0x75, 0x80, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0xe5, 0x3d, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+    0x0, 0x0, 0x0, 0x7d, 0x23, 0x1b, 0x34, 0x4d, 0x22, 0x78, 0xe0, 0x22, 0xd2,
+    0xcf, 0x85, 0x3d, 0xcc, 0x75, 0xec, 0xff, 0x75, 0xee, 0xff, 0x75, 0xeb, 0x3,
+    0x75, 0xac, 0x40, 0xa9, 0xc5, 0xca, 0x75, 0xed, 0xf, 0x75, 0xad, 0xb0, 0xa9,
+    0xd7, 0x94, 0xa9, 0xd4, 0x94, 0x22, 0xa, 0x27, 0xa, 0x3b, 0x2d, 0x32, 0xbe,
+    0x34, 0x0, 0xff, 0x78, 0xc, 0xbe, 0xb0, 0x2, 0x40, 0x7, 0xbe, 0xb0, 0xfe,
+    0x38, 0x2, 0xd3, 0x22, 0xc3, 0x22, 0xa9, 0xc2, 0xb4, 0x30, 0x7, 0x4, 0x74,
+    0x6, 0x80, 0x2, 0x74, 0x4, 0x12, 0xe, 0x4d, 0xa9, 0xd2, 0xb4, 0x22, 0xe5,
+    0x32, 0xb4, 0xc, 0xb, 0xc2, 0x86, 0x7e, 0x34, 0x0, 0x64, 0x12, 0xd, 0x96,
+    0xd2, 0x86, 0x22, 0x12, 0xd, 0x48, 0x7e, 0x35, 0x11, 0x12, 0x0, 0xe, 0xa9,
+    0xd2, 0xb4, 0xd3, 0x22, 0xc2, 0x8c, 0x43, 0x89, 0x2, 0x75, 0x8c, 0x1, 0x75,
+    0x8a, 0x0, 0xd2, 0xa9, 0x22, 0x75, 0xb5, 0x0, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0xe5, 0xb5, 0x22, 0xd2, 0xc8, 0x75, 0xb3, 0x13, 0xa9, 0xd1,
+    0xb4, 0xa9, 0xc0, 0xb4, 0x22, 0xf5, 0xb5, 0xa9, 0x36, 0xb3, 0xfc, 0xa9,
+    0xc6, 0xb3, 0xd3, 0x22, 0x7e, 0x34, 0x0, 0x4, 0x12, 0x9, 0x19, 0x7d, 0x53,
+    0x22, 0xc2, 0x8c, 0x6d, 0x33, 0x7a, 0x35, 0x19, 0xd2, 0x8c, 0x22, 0x7e,
+    0x35, 0x19, 0xb, 0x34, 0x7a, 0x35, 0x19, 0x22, 0x85, 0x3d, 0xcc, 0xe5, 0x3d,
+    0x2, 0xc, 0x83, 0x2, 0xe, 0x6c, 0x0, 0x4, 0x3, 0x16, 0x0, 0x0, 0x9c, 0x0,
+    0x0, 0x0,
diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
new file mode 100644 (file)
index 0000000..f4a698a
--- /dev/null
@@ -0,0 +1,67 @@
+/* include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/ktime.h>
+#include <linux/device.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend.
+ */
+
+enum {
+       WAKE_LOCK_SUSPEND, /* Prevent suspend */
+       WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+       struct wakeup_source ws;
+};
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+                                 const char *name)
+{
+       wakeup_source_init(&lock->ws, name);
+}
+
+static inline void wake_lock_destroy(struct wake_lock *lock)
+{
+       wakeup_source_trash(&lock->ws);
+}
+
+static inline void wake_lock(struct wake_lock *lock)
+{
+       __pm_stay_awake(&lock->ws);
+}
+
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout)
+{
+       __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout));
+}
+
+static inline void wake_unlock(struct wake_lock *lock)
+{
+       __pm_relax(&lock->ws);
+}
+
+static inline int wake_lock_active(struct wake_lock *lock)
+{
+       return lock->ws.active;
+}
+
+#endif