From c5f5a64314fda9d46efe919522de54dd0559ebd7 Mon Sep 17 00:00:00 2001 From: Gao Pan Date: Thu, 16 Mar 2017 16:31:56 +0800 Subject: MLK-14392-1 input: touch: add focaltech touch screen support add focaltech touch screen support Signed-off-by: Gao Pan (cherry-pick from 595cefbee5586e77ceb9ad900c256177a98367c7) --- .../bindings/input/touchscreen/focaltech-ts.txt | 46 + arch/arm/configs/imx_v7_defconfig | 1 + drivers/input/touchscreen/Kconfig | 2 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/focaltech_touch/Kconfig | 16 + drivers/input/touchscreen/focaltech_touch/Makefile | 13 + .../touchscreen/focaltech_touch/focaltech_common.h | 215 +++ .../touchscreen/focaltech_touch/focaltech_config.h | 226 ++++ .../touchscreen/focaltech_touch/focaltech_core.c | 1420 ++++++++++++++++++++ .../touchscreen/focaltech_touch/focaltech_core.h | 187 +++ .../focaltech_touch/focaltech_esdcheck.c | 473 +++++++ .../focaltech_touch/focaltech_ex_mode.c | 357 +++++ .../focaltech_touch/focaltech_gesture.c | 652 +++++++++ .../touchscreen/focaltech_touch/focaltech_i2c.c | 209 +++ .../focaltech_touch/focaltech_point_report_check.c | 151 +++ .../touchscreen/focaltech_touch/focaltech_sensor.c | 311 +++++ .../include/firmware/FT8716_app_sample.i | 0 .../focaltech_touch/include/firmware/lcd_cfg.i | 0 .../pramboot/FT8606_Pramboot_V0.7_20150507.i | 244 ++++ .../pramboot/FT8607_Pramboot_V0.3_20160727.i | 248 ++++ .../pramboot/FT8716_Pramboot_V0.5_20160723.i | 303 +++++ .../pramboot/FT8736_Pramboot_V0.4_20160627.i | 288 ++++ include/linux/wakelock.h | 67 + 23 files changed, 5430 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt create mode 100644 drivers/input/touchscreen/focaltech_touch/Kconfig create mode 100644 drivers/input/touchscreen/focaltech_touch/Makefile create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_common.h create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_config.h create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_core.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_core.h create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c create mode 100644 drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c create mode 100644 drivers/input/touchscreen/focaltech_touch/include/firmware/FT8716_app_sample.i create mode 100644 drivers/input/touchscreen/focaltech_touch/include/firmware/lcd_cfg.i create mode 100644 drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i create mode 100644 drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i create mode 100644 drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i create mode 100644 drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i create mode 100644 include/linux/wakelock.h diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt new file mode 100644 index 000000000000..b8e46cc8f8e8 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/focaltech-ts.txt @@ -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; + }; + }; diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index b3f1aa064bf3..b90ee2c07bec 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -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 diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 1beb19718488..c6cd111d374a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1240,3 +1240,5 @@ config TOUCHSCREEN_ROHM_BU21023 module will be called bu21023_ts. endif + +source "drivers/input/touchscreen/focaltech_touch/Kconfig" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 27de5a491f7a..7037a08af011 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -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 index 000000000000..e1ec3b91202e --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/Kconfig @@ -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 index 000000000000..1b2b8ec8acd4 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/Makefile @@ -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 index 000000000000..c55c5904a3dc --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h @@ -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 index 000000000000..51de298bb0c6 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h @@ -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 index 000000000000..0e3da4229968 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c @@ -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 +#include +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include +#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, ®_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 index 000000000000..55ab92cecc73 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "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 index 000000000000..565507d02523 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_esdcheck.c @@ -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, ®_addr, 1, ®_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, ®_addr, 1, ®_value, 1); + if (err < 0) { + FTS_ERROR("[ESD]: Read Reg 0x91 failed ret = %d!!", err); + fts_esdcheck_data.i2c_nack_cnt++; + } else { + if (reg_value == fts_esdcheck_data.flow_work_cnt_last) + fts_esdcheck_data.flow_work_hold_cnt++; + else + fts_esdcheck_data.flow_work_hold_cnt = 0; + + 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, ®_addr, 1, ®_value, 1); + if (err < 0) { + fts_esdcheck_data.i2c_nack_cnt++; + } else if ((reg_value & 0x70) == FTS_REG_WORKMODE_FACTORY_VALUE) { + FTS_INFO("[ESD]: In factory mode," + "not check esd, return 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 index 000000000000..6ab5d47170cc --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c @@ -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 index 000000000000..9faabb8681bb --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c @@ -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 index 000000000000..75cd917eae2b --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c @@ -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, ®addr, 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 index 000000000000..0fa561748f75 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_point_report_check.c @@ -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 index 000000000000..4a62ee65eaa6 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_sensor.c @@ -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 index 000000000000..e69de29bb2d1 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 index 000000000000..e69de29bb2d1 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 index 000000000000..f031758e0207 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8606_Pramboot_V0.7_20150507.i @@ -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 index 000000000000..ebb31f1ebc7c --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8607_Pramboot_V0.3_20160727.i @@ -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 index 000000000000..805c8bfaf191 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8716_Pramboot_V0.5_20160723.i @@ -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 index 000000000000..b1e3b1c08564 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_touch/include/pramboot/FT8736_Pramboot_V0.4_20160627.i @@ -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 index 000000000000..f4a698a22880 --- /dev/null +++ b/include/linux/wakelock.h @@ -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 +#include + +/* 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 -- cgit v1.2.3