mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
PD#158972: touchscreen: focaltech ft3x27 driver support
Change-Id: I5e1de4a6074a75c288d52fd388323978415610bd Signed-off-by: Sunny Luo <sunny.luo@amlogic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
* Focaltech FT3x27 series touchscreen controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "focaltech,fts"
|
||||
- reg: I2C address of the chip. Should be 0x38
|
||||
- irq-gpio: GPIO pin used for IRQ
|
||||
- reset-gpio: GPIO pin used for reset
|
||||
- x_max: horizontal resolution
|
||||
- y_max: vertical resolution
|
||||
- max-touch-number: the max touch fingers support
|
||||
|
||||
Example:
|
||||
i2c1: i2c@1e000 {
|
||||
/* ... */
|
||||
|
||||
focaltech_ts@0x38 {
|
||||
compatible = "focaltech,fts";
|
||||
status = "okay";
|
||||
reg = <0x38>;
|
||||
reset-gpio = <&gpio GPIOZ_2 0x00>;
|
||||
irq-gpio = <&gpio GPIOZ_3 0x00>;
|
||||
x_max = <600>;
|
||||
y_max = <1024>;
|
||||
max-touch-number = <10>;
|
||||
};
|
||||
|
||||
/* ... */
|
||||
};
|
||||
@@ -14250,3 +14250,9 @@ AMLOGIC LEDRING DRIVER IOCTL
|
||||
M: Renjun Xu <renjun.xu@amlogic.com>
|
||||
F: drivers/amlogic/ledring/aml-is31fl32xx.c
|
||||
F: drivers/amlogic/ledring/aml-pca9557.c
|
||||
|
||||
AMLOGIC TOUCHSCREEN DRIVER
|
||||
M: Sunny Luo <sunny.luo@amlogic.com>
|
||||
F: Documentation/devicetree/bindings/input/touchscreen/amlogic-ts.txt
|
||||
F: drivers/amlogic/input/touchscreen/*
|
||||
F: drivers/amlogic/input/touchscreen/focaltech_touch/*
|
||||
|
||||
@@ -234,6 +234,8 @@ CONFIG_AMLOGIC_ADC_KEYPADS=y
|
||||
CONFIG_AMLOGIC_GPIO_KEY=y
|
||||
CONFIG_AMLOGIC_REMOTE=y
|
||||
CONFIG_AMLOGIC_MESON_REMOTE=y
|
||||
CONFIG_AMLOGIC_TOUCHSCREEN=y
|
||||
CONFIG_AMLOGIC_TOUCHSCREEN_FTS=y
|
||||
CONFIG_AMLOGIC_EFUSE=y
|
||||
CONFIG_AMLOGIC_REBOOT=y
|
||||
CONFIG_AMLOGIC_GX_REBOOT=y
|
||||
|
||||
@@ -13,5 +13,7 @@ if AMLOGIC_INPUT
|
||||
source "drivers/amlogic/input/keyboard/Kconfig"
|
||||
|
||||
source "drivers/amlogic/input/remote/Kconfig"
|
||||
|
||||
source "drivers/amlogic/input/touchscreen/Kconfig"
|
||||
endif
|
||||
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
obj-$(CONFIG_AMLOGIC_INPUT_KEYBOARD) += keyboard/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_REMOTE) += remote/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN) += touchscreen/
|
||||
|
||||
22
drivers/amlogic/input/touchscreen/Kconfig
Executable file
22
drivers/amlogic/input/touchscreen/Kconfig
Executable file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# touchscreen drivers
|
||||
#
|
||||
|
||||
menuconfig AMLOGIC_TOUCHSCREEN
|
||||
bool "amlogic touchscreen"
|
||||
default n
|
||||
help
|
||||
Say Y here, and a list of supported touchscreen driver will be displayed.
|
||||
This option doesn't affect the kernel.
|
||||
|
||||
if AMLOGIC_TOUCHSCREEN
|
||||
|
||||
config AMLOGIC_TOUCHSCREEN_FTS
|
||||
tristate "facaltech FT_xx touch driver support"
|
||||
depends on I2C
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to use facaltech FT_xx.
|
||||
|
||||
|
||||
endif
|
||||
7
drivers/amlogic/input/touchscreen/Makefile
Executable file
7
drivers/amlogic/input/touchscreen/Makefile
Executable file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for touchscreen drivers.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_touch/
|
||||
17
drivers/amlogic/input/touchscreen/focaltech_touch/Kconfig
Executable file
17
drivers/amlogic/input/touchscreen/focaltech_touch/Kconfig
Executable file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Focaltech Touchscreen driver configuration
|
||||
#
|
||||
|
||||
config AMLOGIC_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 AMLOGIC_TOUCHSCREEN_FTS_DIRECTORY
|
||||
string "Focaltech ts directory name"
|
||||
default "focaltech_touch"
|
||||
depends on AMLOGIC_TOUCHSCREEN_FTS
|
||||
|
||||
17
drivers/amlogic/input/touchscreen/focaltech_touch/Makefile
Executable file
17
drivers/amlogic/input/touchscreen/focaltech_touch/Makefile
Executable file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Makefile for the focaltech touchscreen drivers.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_core.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_ex_fun.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_ex_mode.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_flash.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_gesture.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_esdcheck.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_i2c.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_sensor.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_point_report_check.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_flash/
|
||||
|
||||
196
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_common.h
Executable file
196
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_common.h
Executable file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech fts TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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.4 20170630"
|
||||
|
||||
#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 {{0x07,0x80, 0x06, 0x80, 0x06, 0x80, 0xC6, 0x80, 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
|
||||
|
||||
/* 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__ */
|
||||
|
||||
228
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_config.h
Executable file
228
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_config.h
Executable file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
/************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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 _FT7250 0x72500807
|
||||
#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 _FT7250
|
||||
|
||||
/******************* Enables *********************/
|
||||
/*********** 1 to enable, 0 to disable ***********/
|
||||
|
||||
/*
|
||||
* show debug log info
|
||||
* enable it for debug, disable it for release
|
||||
*/
|
||||
#define FTS_DEBUG_EN 0
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Gesture function enable
|
||||
* default: disable
|
||||
*/
|
||||
#define FTS_GESTURE_EN 0
|
||||
|
||||
/*
|
||||
* ESD check & protection
|
||||
* default: disable
|
||||
*/
|
||||
#define FTS_ESDCHECK_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 1
|
||||
|
||||
/* auto cb check
|
||||
* default: disable
|
||||
*/
|
||||
#define FTS_AUTO_CLB_EN 0
|
||||
|
||||
/*
|
||||
* Check vendor_id number
|
||||
* 0:No check vendor_id (default)
|
||||
* 1/2/3: Check vendor_id for vendor compatibility
|
||||
*/
|
||||
#define FTS_GET_VENDOR_ID_NUM 0
|
||||
|
||||
/*
|
||||
* vendor_id(s) for vendor(s) to be compatible with.
|
||||
* a confirmation of vendor_id(s) is recommended.
|
||||
* FTS_GET_VENDOR_ID_NUM == 0, no check vendor id, you may ignore them
|
||||
* FTS_GET_VENDOR_ID_NUM >= 1, compatible with FTS_VENDOR_1_ID
|
||||
* FTS_GET_VENDOR_ID_NUM >= 2, compatible with FTS_VENDOR_2_ID
|
||||
* FTS_GET_VENDOR_ID_NUM == 3, compatible with FTS_VENDOR_3_ID
|
||||
*/
|
||||
#define FTS_VENDOR_1_ID 0x00
|
||||
#define FTS_VENDOR_2_ID 0x00
|
||||
#define FTS_VENDOR_3_ID 0x00
|
||||
|
||||
/*
|
||||
* FW_APP.i file for auto upgrade, you must replace it with your own
|
||||
* define your own fw_app, the sample one to be replaced is invalid
|
||||
* NOTE: if FTS_GET_VENDOR_ID_NUM >= 1, it's the fw corresponding with FTS_VENDOR_1_ID
|
||||
*/
|
||||
#define FTS_UPGRADE_FW_APP "include/firmware/FT8716_app_sample.i"
|
||||
|
||||
/*
|
||||
* if FTS_GET_VENDOR_ID_NUM >= 2, fw corrsponding with FTS_VENDOR_2_ID
|
||||
* define your own fw_app, the sample one is invalid
|
||||
*/
|
||||
#define FTS_UPGRADE_FW2_APP "include/firmware/FT8716_app_sample.i"
|
||||
|
||||
/*
|
||||
* if FTS_GET_VENDOR_ID_NUM == 3, fw corrsponding with FTS_VENDOR_3_ID
|
||||
* define your own fw_app, the sample one is invalid
|
||||
*/
|
||||
#define FTS_UPGRADE_FW3_APP "include/firmware/FT8716_app_sample.i"
|
||||
|
||||
/*
|
||||
* upgrade stress test for debug
|
||||
* enable it for upgrade debug if needed
|
||||
* default: disable
|
||||
*/
|
||||
#define FTS_UPGRADE_STRESS_TEST 0
|
||||
/* stress test times, default: 1000 */
|
||||
#define FTS_UPGRADE_TEST_NUMBER 1000
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
#endif /* _LINUX_FOCLATECH_CONFIG_H_ */
|
||||
|
||||
1500
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_core.c
Executable file
1500
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_core.c
Executable file
File diff suppressed because it is too large
Load Diff
194
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_core.h
Executable file
194
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_core.h
Executable file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_core.h
|
||||
|
||||
* Author: Focaltech Driver Team
|
||||
*
|
||||
* Created: 2016-08-08
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
* Reference:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __LINUX_FOCALTECH_CORE_H__
|
||||
#define __LINUX_FOCALTECH_CORE_H__
|
||||
/*****************************************************************************
|
||||
* Included header files
|
||||
*****************************************************************************/
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include "focaltech_common.h"
|
||||
#include "focaltech_flash.h"
|
||||
#if FTS_PSENSOR_EN
|
||||
#include <linux/sensors.h>
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
* Private constant and macro definitions using #define
|
||||
*****************************************************************************/
|
||||
#define LEN_FLASH_ECC_MAX 0xFFFE
|
||||
|
||||
#define FTS_WORKQUEUE_NAME "fts_wq"
|
||||
|
||||
#define FTS_MAX_POINTS 10
|
||||
#define FTS_KEY_WIDTH 50
|
||||
#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) ((strncmp(buf, "1", 1) == 0) || \
|
||||
(strncmp(buf, "on", 2) == 0))
|
||||
#define FTS_SYSFS_ECHO_OFF(buf) ((strncmp(buf, "0", 1) == 0) || \
|
||||
(strncmp(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;
|
||||
};
|
||||
|
||||
struct ts_event
|
||||
{
|
||||
u16 au16_x[FTS_MAX_POINTS]; /*x coordinate */
|
||||
u16 au16_y[FTS_MAX_POINTS]; /*y coordinate */
|
||||
u16 pressure[FTS_MAX_POINTS];
|
||||
u8 au8_touch_event[FTS_MAX_POINTS]; /* touch event: 0 -- down; 1-- up; 2 -- contact */
|
||||
u8 au8_finger_id[FTS_MAX_POINTS]; /*touch ID */
|
||||
u8 area[FTS_MAX_POINTS];
|
||||
u8 touch_point;
|
||||
u8 point_num;
|
||||
};
|
||||
|
||||
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;
|
||||
struct mutex report_mutex;
|
||||
u16 addr;
|
||||
bool suspended;
|
||||
u8 fw_ver[3];
|
||||
u8 fw_vendor_id;
|
||||
int touchs;
|
||||
int irq_disable;
|
||||
|
||||
#if defined(CONFIG_FB)
|
||||
struct notifier_block fb_notif;
|
||||
#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__ */
|
||||
491
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
Executable file
491
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_esdcheck.c
Executable file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_esdcheck.c
|
||||
*
|
||||
* Author: luoguojin
|
||||
*
|
||||
* Created: 2016-08-03
|
||||
*
|
||||
* Abstract: ESD check function
|
||||
*
|
||||
* Version: v1.0
|
||||
*
|
||||
* Revision History:
|
||||
* v1.0:
|
||||
* First release. By luougojin 2016-08-03
|
||||
* v1.1: By luougojin 2017-02-15
|
||||
* 1. Add LCD_ESD_PATCH to control idc_esdcheck_lcderror
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Included header files
|
||||
*****************************************************************************/
|
||||
#include "focaltech_core.h"
|
||||
|
||||
#if FTS_ESDCHECK_EN
|
||||
/*****************************************************************************
|
||||
* Private constant and macro definitions using #define
|
||||
*****************************************************************************/
|
||||
#define ESDCHECK_WAIT_TIME 1000 //ms
|
||||
#define LCD_ESD_PATCH 0
|
||||
|
||||
/*****************************************************************************
|
||||
* Private enumerations, structures and unions using typedef
|
||||
*****************************************************************************/
|
||||
struct fts_esdcheck_st
|
||||
{
|
||||
u8 active : 1; /* 1- esd check active, need check esd 0- no esd check */
|
||||
u8 suspend : 1;
|
||||
u8 proc_debug : 1; /* apk or adb is accessing I2C */
|
||||
u8 intr : 1; /* 1- Interrupt trigger */
|
||||
u8 unused : 4;
|
||||
u8 flow_work_hold_cnt; /* Flow Work Cnt(reg0x91) keep a same value for x times. >=5 times is ESD, need reset */
|
||||
u8 flow_work_cnt_last; /* Save Flow Work Cnt(reg0x91) value */
|
||||
u32 hardware_reset_cnt;
|
||||
u32 i2c_nack_cnt;
|
||||
u32 i2c_dataerror_cnt;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
static struct delayed_work fts_esdcheck_work;
|
||||
static struct workqueue_struct *fts_esdcheck_workqueue = NULL;
|
||||
static struct fts_esdcheck_st fts_esdcheck_data;
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* functions body
|
||||
*****************************************************************************/
|
||||
#if LCD_ESD_PATCH
|
||||
/*****************************************************************************
|
||||
* Name: lcd_esdcheck
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
int lcd_need_reset;
|
||||
static int tp_need_recovery; /* LCD reset cause Tp reset */
|
||||
int idc_esdcheck_lcderror(void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* 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
|
||||
{
|
||||
if ( (reg_value == chip_types.chip_idh) || (reg_value == 0xEF) ) /* Upgrade sometimes can't detect */
|
||||
{
|
||||
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. IDC esd check lcd default:close */
|
||||
#if LCD_ESD_PATCH
|
||||
idc_esdcheck_lcderror();
|
||||
#endif
|
||||
|
||||
/* 6. Get Chip ID */
|
||||
hardware_reset = get_chip_id();
|
||||
|
||||
/* 7. get Flow work cnt: 0x91 If no change for 5 times, then ESD and reset */
|
||||
if (!hardware_reset)
|
||||
{
|
||||
hardware_reset = get_flow_cnt();
|
||||
}
|
||||
|
||||
/* 8. 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();
|
||||
|
||||
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 destory 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 */
|
||||
|
||||
1351
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_ex_fun.c
Executable file
1351
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_ex_fun.c
Executable file
File diff suppressed because it is too large
Load Diff
376
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
Executable file
376
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_ex_mode.c
Executable file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech ftxxxx TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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; //glove control
|
||||
|
||||
if (mode)
|
||||
buf_value[0] = 0x01;
|
||||
else
|
||||
buf_value[0] = 0x00;
|
||||
|
||||
ret = fts_i2c_write_reg( client, buf_addr[0], buf_value[0]);
|
||||
if (ret<0)
|
||||
{
|
||||
FTS_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; //cover control
|
||||
|
||||
if (mode)
|
||||
buf_value[0] = 0x01;
|
||||
else
|
||||
buf_value[0] = 0x00;
|
||||
|
||||
ret = fts_i2c_write_reg( client,buf_addr[0], buf_value[0]);
|
||||
if (ret<0)
|
||||
{
|
||||
FTS_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; //charger control
|
||||
|
||||
if (mode)
|
||||
buf_value[0] = 0x01;
|
||||
else
|
||||
buf_value[0] = 0x00;
|
||||
|
||||
ret = fts_i2c_write_reg( client, buf_addr[0], buf_value[0]);
|
||||
if (ret<0)
|
||||
{
|
||||
FTS_DEBUG("[Mode]fts_enter_charger_mode write value fail");
|
||||
}
|
||||
|
||||
return ret ;
|
||||
|
||||
}
|
||||
|
||||
/* read and write charger mode
|
||||
* read example: cat fts_touch_charger_mode---read charger mode
|
||||
* write example:echo 01 > fts_touch_charger_mode ---write charger mode to 01
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
860
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash.c
Executable file
860
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash.c
Executable file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech fts TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_flash.c
|
||||
*
|
||||
* Author: fupeipei
|
||||
*
|
||||
* Created: 2016-08-08
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
* Reference:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* 1.Included header files
|
||||
*****************************************************************************/
|
||||
#include "focaltech_core.h"
|
||||
#include "focaltech_flash.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
struct ft_chip_t chip_types;
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
/* Upgrade FW/PRAMBOOT/LCD CFG */
|
||||
u8 CTPM_FW[] =
|
||||
{
|
||||
//#include FTS_UPGRADE_FW_APP
|
||||
"include/firmware/FT8716_app_sample.i"
|
||||
|
||||
};
|
||||
|
||||
#if (FTS_GET_VENDOR_ID_NUM >= 2)
|
||||
u8 CTPM_FW2[] =
|
||||
{
|
||||
#include FTS_UPGRADE_FW2_APP
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (FTS_GET_VENDOR_ID_NUM >= 3)
|
||||
u8 CTPM_FW3[] =
|
||||
{
|
||||
#include FTS_UPGRADE_FW3_APP
|
||||
};
|
||||
#endif
|
||||
|
||||
u8 aucFW_PRAM_BOOT[] =
|
||||
{
|
||||
#ifdef FTS_UPGRADE_PRAMBOOT
|
||||
#include FTS_UPGRADE_PRAMBOOT
|
||||
#endif
|
||||
};
|
||||
|
||||
struct fts_upgrade_fun fts_updatefun_curr;
|
||||
struct workqueue_struct *touch_wq;
|
||||
struct work_struct fw_update_work;
|
||||
u8 *g_fw_file;
|
||||
int g_fw_len;
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_upgrade_delay
|
||||
* Brief: 0
|
||||
* Input: 0
|
||||
* Output: 0
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
void fts_ctpm_upgrade_delay(u32 i)
|
||||
{
|
||||
do
|
||||
{
|
||||
i--;
|
||||
}
|
||||
while (i>0);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_i2c_hid2std
|
||||
* Brief: HID to I2C
|
||||
* Input: i2c info
|
||||
* Output: no
|
||||
* Return: fail =0
|
||||
***********************************************************************/
|
||||
int fts_ctpm_i2c_hid2std(struct i2c_client *client)
|
||||
{
|
||||
#if (FTS_CHIP_IDC)
|
||||
return 0;
|
||||
#else
|
||||
u8 buf[5] = {0};
|
||||
int bRet = 0;
|
||||
|
||||
buf[0] = 0xeb;
|
||||
buf[1] = 0xaa;
|
||||
buf[2] = 0x09;
|
||||
bRet =fts_i2c_write(client, buf, 3);
|
||||
msleep(10);
|
||||
buf[0] = buf[1] = buf[2] = 0;
|
||||
fts_i2c_read(client, buf, 0, buf, 3);
|
||||
|
||||
if ((0xeb == buf[0]) && (0xaa == buf[1]) && (0x08 == buf[2]))
|
||||
{
|
||||
FTS_DEBUG("hidi2c change to stdi2c successful!!");
|
||||
bRet = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FTS_ERROR("hidi2c change to stdi2c error!!");
|
||||
bRet = 0;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_get_chip_types
|
||||
* Brief: get correct chip information
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
void fts_get_chip_types(void)
|
||||
{
|
||||
struct ft_chip_t ctype[] = FTS_CHIP_TYPE_MAPPING;
|
||||
int ic_type = 0;
|
||||
|
||||
if (sizeof(ctype) != sizeof(struct ft_chip_t)) /* only one array */
|
||||
ic_type = IC_SERIALS - 1;
|
||||
|
||||
chip_types = ctype[ic_type];
|
||||
|
||||
FTS_INFO("CHIP TYPE ID = 0x%02x%02x", chip_types.chip_idh, chip_types.chip_idl);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_get_upgrade_array
|
||||
* Brief: decide which ic
|
||||
* Input: no
|
||||
* Output: get ic info in fts_updateinfo_curr
|
||||
* Return: no
|
||||
***********************************************************************/
|
||||
void fts_ctpm_get_upgrade_array(void)
|
||||
{
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
fts_get_chip_types();
|
||||
|
||||
fts_ctpm_i2c_hid2std(fts_i2c_client);
|
||||
|
||||
/* Get functin pointer */
|
||||
memcpy(&fts_updatefun_curr, &fts_updatefun, sizeof(struct fts_upgrade_fun));
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_rom_or_pram_reset
|
||||
* Brief: RST CMD(07), reset to romboot(maybe->bootloader)
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
void fts_ctpm_rom_or_pram_reset(struct i2c_client *client)
|
||||
{
|
||||
u8 rst_cmd = FTS_REG_RESET_FW;
|
||||
|
||||
FTS_INFO("[UPGRADE]******Reset to romboot/bootloader******");
|
||||
fts_i2c_write(client, &rst_cmd, 1);
|
||||
/* The delay can't be changed */
|
||||
msleep(300);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_auto_clb
|
||||
* Brief: auto calibration
|
||||
* Input: i2c info
|
||||
* Output: no
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
int fts_ctpm_auto_clb(struct i2c_client *client)
|
||||
{
|
||||
#if FTS_AUTO_CLB_EN
|
||||
u8 uc_temp = 0x00;
|
||||
u8 i = 0;
|
||||
|
||||
/*start auto CLB */
|
||||
msleep(200);
|
||||
|
||||
fts_i2c_write_reg(client, 0, FTS_REG_WORKMODE_FACTORY_VALUE);
|
||||
/*make sure already enter factory mode */
|
||||
msleep(100);
|
||||
/*write command to start calibration */
|
||||
fts_i2c_write_reg(client, 2, 0x4);
|
||||
msleep(300);
|
||||
if ((chip_types.chip_idh==0x11) ||(chip_types.chip_idh==0x12) ||(chip_types.chip_idh==0x13) ||(chip_types.chip_idh==0x14)) //5x36,5x36i
|
||||
{
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
fts_i2c_read_reg(client, 0x02, &uc_temp);
|
||||
if (0x02 == uc_temp ||
|
||||
0xFF == uc_temp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
msleep(20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
fts_i2c_read_reg(client, 0, &uc_temp);
|
||||
if (0x0 == ((uc_temp&0x70)>>4))
|
||||
{
|
||||
break;
|
||||
}
|
||||
msleep(20);
|
||||
}
|
||||
}
|
||||
fts_i2c_write_reg(client, 0, 0x40);
|
||||
msleep(200);
|
||||
fts_i2c_write_reg(client, 2, 0x5);
|
||||
msleep(300);
|
||||
fts_i2c_write_reg(client, 0, FTS_REG_WORKMODE_WORK_VALUE);
|
||||
msleep(300);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_GetFirmwareSize
|
||||
* Brief: get file size
|
||||
* Input: file name
|
||||
* Output: no
|
||||
* Return: file size
|
||||
***********************************************************************/
|
||||
int fts_GetFirmwareSize(char *firmware_name)
|
||||
{
|
||||
struct file *pfile = NULL;
|
||||
struct inode *inode;
|
||||
unsigned long magic;
|
||||
off_t fsize = 0;
|
||||
char filepath[FILE_NAME_LENGTH];
|
||||
|
||||
memset(filepath, 0, sizeof(filepath));
|
||||
sprintf(filepath, "%s%s", FTXXXX_INI_FILEPATH_CONFIG, firmware_name);
|
||||
if (NULL == pfile)
|
||||
{
|
||||
pfile = filp_open(filepath, O_RDONLY, 0);
|
||||
}
|
||||
if (IS_ERR(pfile))
|
||||
{
|
||||
FTS_ERROR("error occured while opening file %s", filepath);
|
||||
return -EIO;
|
||||
}
|
||||
inode = pfile->f_path.dentry->d_inode;
|
||||
magic = inode->i_sb->s_magic;
|
||||
fsize = inode->i_size;
|
||||
filp_close(pfile, NULL);
|
||||
return fsize;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ReadFirmware
|
||||
* Brief: read firmware buf for .bin file.
|
||||
* Input: file name, data buf
|
||||
* Output: data buf
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
int fts_ReadFirmware(char *firmware_name,u8 *firmware_buf)
|
||||
{
|
||||
struct file *pfile = NULL;
|
||||
struct inode *inode;
|
||||
unsigned long magic;
|
||||
off_t fsize;
|
||||
char filepath[FILE_NAME_LENGTH];
|
||||
loff_t pos;
|
||||
mm_segment_t old_fs;
|
||||
|
||||
memset(filepath, 0, sizeof(filepath));
|
||||
sprintf(filepath, "%s%s", FTXXXX_INI_FILEPATH_CONFIG, firmware_name);
|
||||
if (NULL == pfile)
|
||||
{
|
||||
pfile = filp_open(filepath, O_RDONLY, 0);
|
||||
}
|
||||
if (IS_ERR(pfile))
|
||||
{
|
||||
FTS_ERROR("[UPGRADE] Error occured while opening file %s.\n", filepath);
|
||||
return -EIO;
|
||||
}
|
||||
inode = pfile->f_path.dentry->d_inode;
|
||||
magic = inode->i_sb->s_magic;
|
||||
fsize = inode->i_size;
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
pos = 0;
|
||||
vfs_read(pfile, firmware_buf, fsize, &pos);
|
||||
filp_close(pfile, NULL);
|
||||
set_fs(old_fs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_getsize
|
||||
* Brief: Get different file's size
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: file's size
|
||||
***********************************************************************/
|
||||
u32 fts_getsize(u8 fw_type)
|
||||
{
|
||||
int fw_len = 0;
|
||||
|
||||
if (fw_type == FW_SIZE)
|
||||
fw_len = sizeof(CTPM_FW);
|
||||
#if (FTS_GET_VENDOR_ID_NUM >= 2)
|
||||
else if (fw_type == FW2_SIZE)
|
||||
fw_len = sizeof(CTPM_FW2);
|
||||
#endif
|
||||
#if (FTS_GET_VENDOR_ID_NUM >= 3)
|
||||
else if (fw_type == FW3_SIZE)
|
||||
fw_len = sizeof(CTPM_FW3);
|
||||
#endif
|
||||
#if FTS_CHIP_IDC
|
||||
else if (fw_type == PRAMBOOT_SIZE)
|
||||
fw_len = sizeof(aucFW_PRAM_BOOT);
|
||||
#endif
|
||||
|
||||
return fw_len;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_get_pram_or_rom_id
|
||||
* Brief: 0
|
||||
* Input: 0
|
||||
* Output: 0
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
enum FW_STATUS fts_ctpm_get_pram_or_rom_id(struct i2c_client *client)
|
||||
{
|
||||
u8 buf[4];
|
||||
u8 reg_val[2] = {0};
|
||||
enum FW_STATUS inRomBoot = FTS_RUN_IN_ERROR;
|
||||
|
||||
fts_ctpm_i2c_hid2std(client);
|
||||
|
||||
/*Enter upgrade mode*/
|
||||
/*send 0x55 in time windows*/
|
||||
buf[0] = FTS_UPGRADE_55;
|
||||
buf[1] = FTS_UPGRADE_AA;
|
||||
fts_i2c_write(client, buf, 2);
|
||||
|
||||
msleep(20);
|
||||
|
||||
buf[0] = 0x90;
|
||||
buf[1] = buf[2] = buf[3] =0x00;
|
||||
fts_i2c_read(client, buf, 4, reg_val, 2);
|
||||
|
||||
FTS_DEBUG("[UPGRADE] Read ROM/PRAM/Bootloader id:0x%02x%02x", reg_val[0], reg_val[1]);
|
||||
if ((reg_val[0] == 0x00) || (reg_val[0] == 0xFF))
|
||||
{
|
||||
inRomBoot = FTS_RUN_IN_ERROR;
|
||||
}
|
||||
else if (reg_val[0] == chip_types.pramboot_idh && reg_val[1] == chip_types.pramboot_idl)
|
||||
{
|
||||
inRomBoot = FTS_RUN_IN_PRAM;
|
||||
}
|
||||
else if (reg_val[0] == chip_types.rom_idh && reg_val[1] == chip_types.rom_idl)
|
||||
{
|
||||
inRomBoot = FTS_RUN_IN_ROM;
|
||||
}
|
||||
else if (reg_val[0] == chip_types.bootloader_idh && reg_val[1] == chip_types.bootloader_idl)
|
||||
{
|
||||
inRomBoot = FTS_RUN_IN_BOOTLOADER;
|
||||
}
|
||||
|
||||
return inRomBoot;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_get_app_file
|
||||
* Brief: get app file by Vendor ID
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: <0: vendor id not correct,not upgrade
|
||||
***********************************************************************/
|
||||
int fts_ctpm_get_i_file(struct i2c_client *client, int fw_valid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (fts_updatefun_curr.get_i_file)
|
||||
ret = fts_updatefun_curr.get_i_file(client, fw_valid);
|
||||
else
|
||||
ret = -EIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_get_app_ver
|
||||
* Brief: get app file version
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: fw version
|
||||
***********************************************************************/
|
||||
int fts_ctpm_get_app_ver(void)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
if (fts_updatefun_curr.get_app_i_file_ver)
|
||||
i_ret = fts_updatefun_curr.get_app_i_file_ver();
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_fw_upgrade
|
||||
* Brief: fw upgrade entry funciotn
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 0 - upgrade successfully
|
||||
* <0 - upgrade failed
|
||||
***********************************************************************/
|
||||
int fts_ctpm_fw_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
if (fts_updatefun_curr.upgrade_with_app_i_file)
|
||||
i_ret = fts_updatefun_curr.upgrade_with_app_i_file(client);
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_fw_upgrade
|
||||
* Brief: fw upgrade entry funciotn
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 0 - upgrade successfully
|
||||
* <0 - upgrade failed
|
||||
***********************************************************************/
|
||||
int fts_ctpm_lcd_cfg_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
if (fts_updatefun_curr.upgrade_with_lcd_cfg_i_file)
|
||||
i_ret = fts_updatefun_curr.upgrade_with_lcd_cfg_i_file(client);
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
bool fts_check_fw_valid(struct i2c_client *client)
|
||||
{
|
||||
int i = 0;
|
||||
u8 chip_id = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &chip_id);
|
||||
if(chip_id == chip_types.chip_idh)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (!(FTS_UPGRADE_STRESS_TEST))
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_check_fw_status
|
||||
* Brief: Check App is valid or not
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: -EIO - I2C communication error
|
||||
* FTS_RUN_IN_APP - APP valid
|
||||
* 0 - APP invalid
|
||||
***********************************************************************/
|
||||
static int fts_ctpm_check_fw_status(struct i2c_client *client)
|
||||
{
|
||||
u8 chip_id1 = 0;
|
||||
u8 chip_id2 = 0;
|
||||
int fw_status = FTS_RUN_IN_ERROR;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int i2c_noack_retry = 0;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &chip_id1);
|
||||
if (ret < 0)
|
||||
{
|
||||
i2c_noack_retry++;
|
||||
continue;
|
||||
}
|
||||
ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID2, &chip_id2);
|
||||
if (ret < 0)
|
||||
{
|
||||
i2c_noack_retry++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((chip_id1 == chip_types.chip_idh)
|
||||
#if FTS_CHIP_IDC
|
||||
&& (chip_id2 == chip_types.chip_idl)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
fw_status = FTS_RUN_IN_APP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FTS_DEBUG("[UPGRADE]: chip_id = %02x%02x, chip_types.chip_idh = %02x%02x",
|
||||
chip_id1, chip_id2, chip_types.chip_idh, chip_types.chip_idl);
|
||||
|
||||
/* I2C No ACK 5 times, then return -EIO */
|
||||
if (i2c_noack_retry >= 5)
|
||||
return -EIO;
|
||||
|
||||
/* I2C communication ok, but not get correct ID, need check pram/rom/bootloader */
|
||||
if (i >= 5)
|
||||
{
|
||||
fw_status = fts_ctpm_get_pram_or_rom_id(client);
|
||||
}
|
||||
|
||||
return fw_status;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_check_fw_ver
|
||||
* Brief: Check vendor id is valid or not
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 1 - vendor id valid
|
||||
* 0 - vendor id invalid
|
||||
***********************************************************************/
|
||||
static int fts_ctpm_check_fw_ver(struct i2c_client *client)
|
||||
{
|
||||
u8 uc_tp_fm_ver;
|
||||
u8 uc_host_fm_ver = 0;
|
||||
|
||||
fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
|
||||
uc_host_fm_ver = fts_ctpm_get_app_ver();
|
||||
|
||||
FTS_DEBUG("[UPGRADE]: uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x!!", uc_tp_fm_ver, uc_host_fm_ver);
|
||||
if (uc_tp_fm_ver < uc_host_fm_ver )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_check_need_upgrade
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 1 - Need upgrade
|
||||
* 0 - No upgrade
|
||||
***********************************************************************/
|
||||
static int fts_ctpm_check_need_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int fw_status = 0;
|
||||
int bUpgradeFlag = false;
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
/* 1. veriry FW APP is valid or not */
|
||||
fw_status = fts_ctpm_check_fw_status(client);
|
||||
FTS_DEBUG( "[UPGRADE]: fw_status = %d!!", fw_status);
|
||||
if (fw_status < 0)
|
||||
{
|
||||
/* I2C no ACK, return immediately */
|
||||
FTS_ERROR("[UPGRADE]******I2C NO ACK,exit upgrade******");
|
||||
return -EIO;
|
||||
}
|
||||
else if (fw_status == FTS_RUN_IN_ERROR)
|
||||
{
|
||||
FTS_ERROR("[UPGRADE]******IC Type Fail******");
|
||||
}
|
||||
else if (fw_status == FTS_RUN_IN_APP)
|
||||
{
|
||||
FTS_INFO("[UPGRADE]**********FW APP valid**********");
|
||||
|
||||
if (fts_ctpm_get_i_file(client, 1) != 0)
|
||||
{
|
||||
FTS_DEBUG("[UPGRADE]******Get upgrade file(fw) fail******");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (fts_ctpm_check_fw_ver(client) == 1)
|
||||
{
|
||||
FTS_DEBUG("[UPGRADE]**********need upgrade fw**********");
|
||||
bUpgradeFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FTS_DEBUG("[UPGRADE]**********Don't need upgrade fw**********");
|
||||
bUpgradeFlag = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if app is invalid, reset to run ROM */
|
||||
FTS_INFO("[UPGRADE]**********FW APP invalid**********");
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
if (fts_ctpm_get_i_file(client, 0) != 0)
|
||||
{
|
||||
FTS_DEBUG("[UPGRADE]******Get upgrade file(flash) fail******");
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
return -EIO;
|
||||
}
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
bUpgradeFlag = true;
|
||||
}
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
|
||||
return bUpgradeFlag;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_auto_upgrade
|
||||
* Brief: auto upgrade
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 0 - no upgrade
|
||||
***********************************************************************/
|
||||
int fts_ctpm_auto_upgrade(struct i2c_client *client)
|
||||
{
|
||||
u8 uc_tp_fm_ver;
|
||||
int i_ret = 0;
|
||||
int bUpgradeFlag = false;
|
||||
u8 uc_upgrade_times = 0;
|
||||
|
||||
FTS_DEBUG("[UPGRADE]********************check upgrade need or not********************");
|
||||
bUpgradeFlag = fts_ctpm_check_need_upgrade(client);
|
||||
FTS_DEBUG("[UPGRADE]**********bUpgradeFlag = 0x%x**********", bUpgradeFlag);
|
||||
|
||||
if (bUpgradeFlag <= 0)
|
||||
{
|
||||
FTS_DEBUG("[UPGRADE]**********No Upgrade, exit**********");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FW Upgrade */
|
||||
do
|
||||
{
|
||||
uc_upgrade_times++;
|
||||
FTS_DEBUG("[UPGRADE]********************star upgrade(%d)********************", uc_upgrade_times);
|
||||
|
||||
i_ret = fts_ctpm_fw_upgrade(client);
|
||||
if (i_ret == 0)
|
||||
{
|
||||
/* upgrade success */
|
||||
fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
|
||||
FTS_DEBUG("[UPGRADE]********************Success upgrade to new fw version 0x%x********************", uc_tp_fm_ver);
|
||||
|
||||
fts_ctpm_auto_clb(client);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* upgrade fail, reset to run ROM BOOT..
|
||||
* if app in flash is ok, TP will work success
|
||||
*/
|
||||
FTS_ERROR("[UPGRADE]********************upgrade fail, reset now********************");
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
}
|
||||
}
|
||||
while (uc_upgrade_times < 2); /* if upgrade fail, upgrade again. then return */
|
||||
}
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN
|
||||
int fts_get_host_lic_ver(u8* ver)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
if (fts_updatefun_curr.get_hlic_ver)
|
||||
i_ret = fts_updatefun_curr.get_hlic_ver();
|
||||
|
||||
if (i_ret > 0)
|
||||
*ver = i_ret;
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/* check if lcd init code need upgrade
|
||||
* true-need false-no need
|
||||
*/
|
||||
static bool fts_lic_need_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 initcode_ver_in_tp = 0;
|
||||
u8 initcode_ver_in_host = 0;
|
||||
bool fwvalid = false;
|
||||
|
||||
fwvalid = fts_check_fw_valid(client);
|
||||
if( !fwvalid) {
|
||||
FTS_INFO("fw is invalid, no upgrade lcd init code");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = fts_get_host_lic_ver(&initcode_ver_in_host);
|
||||
if(ret < 0)
|
||||
{
|
||||
FTS_ERROR("init code in host invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = fts_i2c_read_reg(client, 0xE4, &initcode_ver_in_tp);
|
||||
if (ret < 0) {
|
||||
FTS_ERROR("read reg0xE4 fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
FTS_DEBUG("tp init ver:%x, fw init ver:%x", initcode_ver_in_tp, initcode_ver_in_host);
|
||||
if(0xA5 == initcode_ver_in_tp) {
|
||||
FTS_INFO("lcd init code ver is 0xA5, don't upgade init code");
|
||||
return false;
|
||||
}
|
||||
else if(0xFF == initcode_ver_in_tp) {
|
||||
FTS_DEBUG("lcd init code in tp is invalid, need upgrade init code");
|
||||
return true;
|
||||
}
|
||||
else if(initcode_ver_in_tp < initcode_ver_in_host)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int fts_lic_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int ret = 0;
|
||||
bool hlic_upgrade = false;
|
||||
int upgrade_count = 0;
|
||||
|
||||
hlic_upgrade = fts_lic_need_upgrade(client);
|
||||
FTS_INFO("lcd init code upgrade flag:%d", hlic_upgrade);
|
||||
if(hlic_upgrade) {
|
||||
FTS_INFO("lcd init code upgrade...");
|
||||
do {
|
||||
upgrade_count++;
|
||||
ret = fts_ctpm_lcd_cfg_upgrade(client);
|
||||
if(0 == ret) {
|
||||
FTS_INFO("lcd init code upgrade succussfully");
|
||||
break;
|
||||
}
|
||||
else {
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
}
|
||||
}while (upgrade_count < 2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN */
|
||||
|
||||
#if FTS_AUTO_UPGRADE_EN
|
||||
static void fts_ctpm_update_work_func(struct work_struct *work)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
FTS_DEBUG( "[UPGRADE]******************************FTS enter upgrade******************************");
|
||||
fts_irq_disable();
|
||||
|
||||
/* esd check */
|
||||
#if FTS_ESDCHECK_EN
|
||||
fts_esdcheck_switch(DISABLE);
|
||||
#endif
|
||||
|
||||
i_ret = fts_ctpm_auto_upgrade(fts_i2c_client);
|
||||
if (i_ret < 0)
|
||||
FTS_ERROR("[UPGRADE]**********TP FW upgrade failed**********");
|
||||
|
||||
#if FTS_AUTO_UPGRADE_FOR_LCD_CFG_EN
|
||||
i_ret = fts_lic_upgrade(fts_i2c_client);
|
||||
if (i_ret < 0)
|
||||
FTS_ERROR("**********lcd init code upgrade failed**********");
|
||||
#endif
|
||||
|
||||
#if FTS_ESDCHECK_EN
|
||||
fts_esdcheck_switch(ENABLE);
|
||||
#endif
|
||||
fts_irq_enable();
|
||||
|
||||
FTS_DEBUG( "[UPGRADE]******************************FTS exit upgrade******************************");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_ctpm_upgrade_init
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
void fts_ctpm_upgrade_init(void)
|
||||
{
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
touch_wq = create_singlethread_workqueue("touch_wq");
|
||||
if (touch_wq)
|
||||
{
|
||||
INIT_WORK(&fw_update_work, fts_ctpm_update_work_func);
|
||||
queue_work(touch_wq, &fw_update_work);
|
||||
}
|
||||
else
|
||||
{
|
||||
FTS_ERROR("[UPGRADE]create_singlethread_workqueue failed\n");
|
||||
}
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_ctpm_upgrade_exit
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
void fts_ctpm_upgrade_exit(void)
|
||||
{
|
||||
FTS_FUNC_ENTER();
|
||||
destroy_workqueue(touch_wq);
|
||||
FTS_FUNC_EXIT();
|
||||
}
|
||||
|
||||
#endif /* #if FTS_AUTO_UPGRADE_EN */
|
||||
120
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash.h
Executable file
120
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash.h
Executable file
@@ -0,0 +1,120 @@
|
||||
/************************************************************************
|
||||
* Copyright (C) 2010-2017, Focaltech Systems (R)£¬All Rights Reserved.
|
||||
*
|
||||
* File Name: focaltech_flash.h
|
||||
*
|
||||
* Author: fupeipei
|
||||
*
|
||||
* Created: 2016-08-07
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
************************************************************************/
|
||||
#ifndef __LINUX_FOCALTECH_FLASH_H__
|
||||
#define __LINUX_FOCALTECH_FLASH_H__
|
||||
|
||||
/*****************************************************************************
|
||||
* 1.Included header files
|
||||
*****************************************************************************/
|
||||
#include "focaltech_flash/focaltech_upgrade_common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private constant and macro definitions using #define
|
||||
*****************************************************************************/
|
||||
#define FTS_REG_ECC 0xCC
|
||||
#define FTS_RST_CMD_REG2 0xBC
|
||||
#define FTS_READ_ID_REG 0x90
|
||||
#define FTS_ERASE_APP_REG 0x61
|
||||
#define FTS_ERASE_PARAMS_CMD 0x63
|
||||
#define FTS_FW_WRITE_CMD 0xBF
|
||||
#define FTS_REG_RESET_FW 0x07
|
||||
#define FTS_RST_CMD_REG1 0xFC
|
||||
#define LEN_FLASH_ECC_MAX 0xFFFE
|
||||
|
||||
#define FTS_PACKET_LENGTH 128
|
||||
#define FTS_SETTING_BUF_LEN 128
|
||||
|
||||
#define FTS_UPGRADE_LOOP 30
|
||||
#define AUTO_CLB_NEED 1
|
||||
#define AUTO_CLB_NONEED 0
|
||||
#define FTS_UPGRADE_AA 0xAA
|
||||
#define FTS_UPGRADE_55 0x55
|
||||
#define FTXXXX_INI_FILEPATH_CONFIG "/sdcard/"
|
||||
|
||||
enum FW_STATUS
|
||||
{
|
||||
FTS_RUN_IN_ERROR,
|
||||
FTS_RUN_IN_APP,
|
||||
FTS_RUN_IN_ROM,
|
||||
FTS_RUN_IN_PRAM,
|
||||
FTS_RUN_IN_BOOTLOADER
|
||||
};
|
||||
|
||||
enum FILE_SIZE_TYPE
|
||||
{
|
||||
FW_SIZE,
|
||||
FW2_SIZE,
|
||||
FW3_SIZE,
|
||||
PRAMBOOT_SIZE,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Private enumerations, structures and unions using typedef
|
||||
*****************************************************************************/
|
||||
/* IC info */
|
||||
|
||||
struct fts_upgrade_fun
|
||||
{
|
||||
int (*get_i_file)(struct i2c_client *, int);
|
||||
int (*get_app_bin_file_ver)(char *);
|
||||
int (*get_app_i_file_ver)(void);
|
||||
int (*upgrade_with_app_i_file)(struct i2c_client *);
|
||||
int (*upgrade_with_app_bin_file)(struct i2c_client *, char *);
|
||||
int (*get_hlic_ver)(void);
|
||||
int (*upgrade_with_lcd_cfg_i_file)(struct i2c_client *);
|
||||
int (*upgrade_with_lcd_cfg_bin_file)(struct i2c_client *, char *);
|
||||
};
|
||||
extern struct fts_upgrade_fun fts_updatefun;
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
extern u8 CTPM_FW[];
|
||||
extern u8 CTPM_FW2[];
|
||||
extern u8 CTPM_FW3[];
|
||||
extern u8 aucFW_PRAM_BOOT[];
|
||||
extern u8 CTPM_LCD_CFG[];
|
||||
extern u8 *g_fw_file;
|
||||
extern int g_fw_len;
|
||||
extern struct fts_upgrade_fun fts_updatefun_curr;
|
||||
extern struct ft_chip_t chip_types;
|
||||
|
||||
#if FTS_AUTO_UPGRADE_EN
|
||||
extern struct workqueue_struct *touch_wq;
|
||||
extern struct work_struct fw_update_work;
|
||||
#endif
|
||||
|
||||
void fts_ctpm_upgrade_init(void);
|
||||
void fts_ctpm_upgrade_exit(void);
|
||||
void fts_ctpm_upgrade_delay(u32 i);
|
||||
void fts_ctpm_get_upgrade_array(void);
|
||||
int fts_ctpm_auto_upgrade(struct i2c_client *client);
|
||||
int fts_fw_upgrade(struct device *dev, bool force);
|
||||
int fts_ctpm_auto_clb(struct i2c_client *client);
|
||||
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
u32 fts_getsize(u8 fw_type);
|
||||
int fts_GetFirmwareSize(char *firmware_name);
|
||||
int fts_ctpm_i2c_hid2std(struct i2c_client *client);
|
||||
int fts_ReadFirmware(char *firmware_name,u8 *firmware_buf);
|
||||
void fts_ctpm_rom_or_pram_reset(struct i2c_client *client);
|
||||
enum FW_STATUS fts_ctpm_get_pram_or_rom_id(struct i2c_client *client);
|
||||
#endif
|
||||
|
||||
|
||||
10
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash/Makefile
Executable file
10
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_flash/Makefile
Executable file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# Makefile for the focaltech touchscreen drivers.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_upgrade_idc.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_upgrade_ft7250.o
|
||||
obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_upgrade_test.o
|
||||
@@ -0,0 +1,56 @@
|
||||
/************************************************************************
|
||||
* Copyright (C) 2010-2017, Focaltech Systems (R)£¬All Rights Reserved.
|
||||
*
|
||||
* File Name: focaltech_upgrade_common.h
|
||||
*
|
||||
* Author: fupeipei
|
||||
*
|
||||
* Created: 2016-08-16
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
************************************************************************/
|
||||
#ifndef __LINUX_FOCALTECH_UPGRADE_COMMON_H__
|
||||
#define __LINUX_FOCALTECH_UPGRADE_COMMON_H__
|
||||
|
||||
/*****************************************************************************
|
||||
* 1.Included header files
|
||||
*****************************************************************************/
|
||||
#include "../focaltech_flash.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private constant and macro definitions using #define
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private enumerations, structures and unions using typedef
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
int fts_ctpm_erase_flash(struct i2c_client *client);
|
||||
int fts_ctpm_pramboot_ecc(struct i2c_client *client);
|
||||
bool fts_ctpm_check_run_state(struct i2c_client *client, int state);
|
||||
void fts_ctpm_start_pramboot(struct i2c_client *client);
|
||||
int fts_ctpm_start_fw_upgrade(struct i2c_client *client);
|
||||
bool fts_ctpm_check_in_pramboot(struct i2c_client *client);
|
||||
int fts_ctpm_upgrade_idc_init(struct i2c_client *client);
|
||||
int fts_ctpm_write_app_for_idc(struct i2c_client *client, u32 length, u8 *readbuf);
|
||||
int fts_ctpm_upgrade_ecc(struct i2c_client *client, u32 startaddr, u32 length);
|
||||
int fts_ctpm_write_pramboot_for_idc(struct i2c_client *client, u32 length, u8 *readbuf);
|
||||
int fts_writeflash(struct i2c_client *client, u32 writeaddr, u32 length, u8 *readbuf, u32 cnt);
|
||||
|
||||
int fts_ctpm_get_app_ver(void);
|
||||
int fts_ctpm_fw_upgrade(struct i2c_client *client);
|
||||
int fts_ctpm_lcd_cfg_upgrade(struct i2c_client *client);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech fts TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_upgrade_idc.c
|
||||
*
|
||||
* Author: fupeipei
|
||||
*
|
||||
* Created: 2016-08-22
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
* Reference:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* 1.Included header files
|
||||
*****************************************************************************/
|
||||
#include "../focaltech_core.h"
|
||||
|
||||
#if (FTS_CHIP_IDC == 1)
|
||||
#include "../focaltech_flash.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
u8 upgrade_ecc;
|
||||
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_upgrade_idc_init
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_upgrade_idc_init(struct i2c_client *client)
|
||||
{
|
||||
int i_ret = 0;
|
||||
u8 reg_val_id[4] = {0};
|
||||
u8 auc_i2c_write_buf[10];
|
||||
|
||||
FTS_INFO("[UPGRADE]**********Upgrade setting Init**********");
|
||||
|
||||
/*read flash ID*/
|
||||
auc_i2c_write_buf[0] = 0x05;
|
||||
reg_val_id[0] = 0x00;
|
||||
i_ret =fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val_id, 1);
|
||||
if (i_ret < 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*set flash clk*/
|
||||
auc_i2c_write_buf[0] = 0x05;
|
||||
auc_i2c_write_buf[1] = reg_val_id[0];//0x80;
|
||||
auc_i2c_write_buf[2] = 0x00;
|
||||
fts_i2c_write(client, auc_i2c_write_buf, 3);
|
||||
|
||||
/*send upgrade type to reg 0x09: 0x0B: upgrade; 0x0A: download*/
|
||||
auc_i2c_write_buf[0] = 0x09;
|
||||
auc_i2c_write_buf[1] = 0x0B;
|
||||
fts_i2c_write(client, auc_i2c_write_buf, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_start_pramboot
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
void fts_ctpm_start_pramboot(struct i2c_client *client)
|
||||
{
|
||||
u8 auc_i2c_write_buf[10];
|
||||
|
||||
FTS_INFO("[UPGRADE]**********start pramboot**********");
|
||||
auc_i2c_write_buf[0] = 0x08;
|
||||
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_start_fw_upgrade
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_start_fw_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int i_ret = 0;
|
||||
|
||||
/*send the soft upgrade commond to FW, and start upgrade*/
|
||||
FTS_INFO("[UPGRADE]**********send 0xAA and 0x55 to FW, start upgrade**********");
|
||||
|
||||
i_ret = fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
|
||||
msleep(10);
|
||||
i_ret = fts_i2c_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
|
||||
msleep(200);
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_check_run_state
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
bool fts_ctpm_check_run_state(struct i2c_client *client, int rstate)
|
||||
{
|
||||
int i = 0;
|
||||
enum FW_STATUS cstate = FTS_RUN_IN_ERROR;
|
||||
|
||||
for (i = 0; i < FTS_UPGRADE_LOOP; i++)
|
||||
{
|
||||
cstate = fts_ctpm_get_pram_or_rom_id(client);
|
||||
FTS_DEBUG( "[UPGRADE]: run state = %d", cstate);
|
||||
|
||||
if (cstate == rstate)
|
||||
return true;
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_pramboot_ecc
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_pramboot_ecc(struct i2c_client *client)
|
||||
{
|
||||
u8 auc_i2c_write_buf[10];
|
||||
u8 reg_val[4] = {0};
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
/*read out checksum, if pramboot checksum != host checksum, upgrade fail*/
|
||||
FTS_INFO("[UPGRADE]******read out pramboot checksum******");
|
||||
auc_i2c_write_buf[0] = 0xcc;
|
||||
msleep(2);
|
||||
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
||||
if (reg_val[0] != upgrade_ecc) /*pramboot checksum != host checksum, upgrade fail*/
|
||||
{
|
||||
FTS_ERROR("[UPGRADE]: checksum fail : pramboot_ecc = %X, host_ecc = %X!!",reg_val[0],upgrade_ecc);
|
||||
return -EIO;
|
||||
}
|
||||
FTS_DEBUG("[UPGRADE]: checksum success : pramboot_ecc = %X, host_ecc = %X!!",reg_val[0],upgrade_ecc);
|
||||
msleep(100);
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_upgrade_ecc
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_upgrade_ecc(struct i2c_client *client, u32 startaddr, u32 length)
|
||||
{
|
||||
u32 i = 0;
|
||||
u8 auc_i2c_write_buf[10];
|
||||
u32 temp;
|
||||
u8 reg_val[4] = {0};
|
||||
int i_ret = 0;
|
||||
|
||||
FTS_INFO( "[UPGRADE]**********read out checksum**********");
|
||||
|
||||
/*check sum init*/
|
||||
auc_i2c_write_buf[0] = 0x64;
|
||||
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
||||
msleep(300);
|
||||
|
||||
/*send commond to pramboot to start checksum*/
|
||||
auc_i2c_write_buf[0] = 0x65;
|
||||
auc_i2c_write_buf[1] = (u8)(startaddr >> 16);
|
||||
auc_i2c_write_buf[2] = (u8)(startaddr >> 8);
|
||||
auc_i2c_write_buf[3] = (u8)(startaddr);
|
||||
|
||||
if (length > LEN_FLASH_ECC_MAX)
|
||||
{
|
||||
temp = LEN_FLASH_ECC_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = length;
|
||||
}
|
||||
|
||||
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
||||
auc_i2c_write_buf[5] = (u8)(temp);
|
||||
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
||||
msleep(length/256);
|
||||
|
||||
/*read status : if check sum is finished?*/
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
auc_i2c_write_buf[0] = 0x6a;
|
||||
reg_val[0] = reg_val[1] = 0x00;
|
||||
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
||||
|
||||
if (0xF0==reg_val[0] && 0x55==reg_val[1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
msleep(1);
|
||||
|
||||
}
|
||||
|
||||
if (length > LEN_FLASH_ECC_MAX)
|
||||
{
|
||||
temp = LEN_FLASH_ECC_MAX;
|
||||
auc_i2c_write_buf[0] = 0x65;
|
||||
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
||||
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
||||
auc_i2c_write_buf[3] = (u8)(temp);
|
||||
temp = length-LEN_FLASH_ECC_MAX;
|
||||
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
||||
auc_i2c_write_buf[5] = (u8)(temp);
|
||||
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
||||
|
||||
msleep(length/256);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
auc_i2c_write_buf[0] = 0x6a;
|
||||
reg_val[0] = reg_val[1] = 0x00;
|
||||
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
||||
|
||||
if (0xF0==reg_val[0] && 0x55==reg_val[1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*read out check sum*/
|
||||
auc_i2c_write_buf[0] = 0x66;
|
||||
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
||||
if (reg_val[0] != upgrade_ecc) /*if check sum fail, upgrade fail*/
|
||||
{
|
||||
FTS_ERROR( "[UPGRADE]: ecc error! FW=%02x upgrade_ecc=%02x!!", reg_val[0], upgrade_ecc);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
FTS_DEBUG( "[UPGRADE]: ecc success : FW=%02x upgrade_ecc=%02x!!", reg_val[0], upgrade_ecc);
|
||||
|
||||
upgrade_ecc = 0;
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_erase_flash
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_erase_flash(struct i2c_client *client)
|
||||
{
|
||||
u32 i = 0;
|
||||
u8 auc_i2c_write_buf[10];
|
||||
u8 reg_val[4] = {0};
|
||||
|
||||
FTS_INFO("[UPGRADE]**********erase app now**********");
|
||||
|
||||
/*send to erase flash*/
|
||||
auc_i2c_write_buf[0] = 0x61;
|
||||
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
||||
msleep(1350);
|
||||
|
||||
for (i = 0; i < 15; i++)
|
||||
{
|
||||
/*get the erase app status, if get 0xF0AA£¬erase flash success*/
|
||||
auc_i2c_write_buf[0] = 0x6a;
|
||||
reg_val[0] = reg_val[1] = 0x00;
|
||||
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
||||
|
||||
if (0xF0==reg_val[0] && 0xAA==reg_val[1]) /*erase flash success*/
|
||||
{
|
||||
break;
|
||||
}
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
if ((0xF0!=reg_val[0] || 0xAA!=reg_val[1]) && (i >= 15)) /*erase flash fail*/
|
||||
{
|
||||
FTS_ERROR("[UPGRADE]: erase app error.reset tp and reload FW!!");
|
||||
return -EIO;
|
||||
}
|
||||
FTS_DEBUG("[UPGRADE]: erase app ok!!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_write_pramboot_for_idc
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_write_pramboot_for_idc(struct i2c_client *client, u32 length, u8 *readbuf)
|
||||
{
|
||||
u32 i = 0;
|
||||
u32 j;
|
||||
u32 temp;
|
||||
u32 packet_number;
|
||||
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
||||
|
||||
upgrade_ecc = 0;
|
||||
FTS_INFO("[UPGRADE]**********write pramboot to pram**********");
|
||||
|
||||
temp = 0;
|
||||
packet_number = (length) / FTS_PACKET_LENGTH;
|
||||
if ((length) % FTS_PACKET_LENGTH > 0)
|
||||
{
|
||||
packet_number++;
|
||||
}
|
||||
packet_buf[0] = 0xae;
|
||||
packet_buf[1] = 0x00;
|
||||
|
||||
for (j = 0; j < packet_number; j++)
|
||||
{
|
||||
temp = j * FTS_PACKET_LENGTH;
|
||||
packet_buf[2] = (u8) (temp >> 8);
|
||||
packet_buf[3] = (u8) temp;
|
||||
if (j < (packet_number-1))
|
||||
{
|
||||
temp = FTS_PACKET_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (length) % FTS_PACKET_LENGTH;
|
||||
}
|
||||
packet_buf[4] = (u8) (temp >> 8);
|
||||
packet_buf[5] = (u8) temp;
|
||||
|
||||
for (i = 0; i < temp; i++)
|
||||
{
|
||||
packet_buf[6 + i] = readbuf[j * FTS_PACKET_LENGTH + i];
|
||||
upgrade_ecc ^= packet_buf[6 + i];
|
||||
}
|
||||
fts_i2c_write(client, packet_buf, temp + 6);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_write_app_for_idc
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_ctpm_write_app_for_idc(struct i2c_client *client, u32 length, u8 *readbuf)
|
||||
{
|
||||
u32 j;
|
||||
u32 i = 0;
|
||||
u32 packet_number;
|
||||
u32 temp;
|
||||
u32 writelenght;
|
||||
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
||||
u8 auc_i2c_write_buf[10];
|
||||
u8 reg_val[4] = {0};
|
||||
|
||||
FTS_INFO( "[UPGRADE]**********write app to flash**********");
|
||||
|
||||
upgrade_ecc = 0;
|
||||
|
||||
packet_number = (length) / FTS_PACKET_LENGTH;
|
||||
if (((length) % FTS_PACKET_LENGTH) > 0)
|
||||
{
|
||||
packet_number++;
|
||||
}
|
||||
|
||||
packet_buf[0] = 0xbf;
|
||||
|
||||
for (j = 0; j < packet_number; j++)
|
||||
{
|
||||
temp = 0x1000+j * FTS_PACKET_LENGTH;
|
||||
|
||||
if (j<(packet_number-1))
|
||||
{
|
||||
writelenght = FTS_PACKET_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
writelenght = ((length) % FTS_PACKET_LENGTH);
|
||||
}
|
||||
packet_buf[1] = (u8) (temp >> 16);
|
||||
packet_buf[2] = (u8) (temp >> 8);
|
||||
packet_buf[3] = (u8) temp;
|
||||
packet_buf[4] = (u8) (writelenght >> 8);
|
||||
packet_buf[5] = (u8) writelenght;
|
||||
|
||||
for (i = 0; i < writelenght; i++)
|
||||
{
|
||||
packet_buf[6 + i] = readbuf[(temp - 0x1000+i)];
|
||||
upgrade_ecc ^= packet_buf[6 + i];
|
||||
}
|
||||
|
||||
fts_i2c_write(client, packet_buf, (writelenght + 6));
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
{
|
||||
/*read status and check if the app writting is finished*/
|
||||
auc_i2c_write_buf[0] = 0x6a;
|
||||
reg_val[0] = reg_val[1] = 0x00;
|
||||
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
||||
|
||||
if ((j + 0x20+0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
//msleep(1);
|
||||
fts_ctpm_upgrade_delay(1000);
|
||||
}
|
||||
}
|
||||
msleep(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* IDC */
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech fts TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_upgrade_test.c
|
||||
*
|
||||
* Author: fupeipei
|
||||
*
|
||||
* Created: 2016-08-22
|
||||
*
|
||||
* Abstract:
|
||||
*
|
||||
* Reference:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* 1.Included header files
|
||||
*****************************************************************************/
|
||||
#include "../focaltech_core.h"
|
||||
#include "../focaltech_flash.h"
|
||||
//#include <linux/wakelock.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
#define FTS_GET_UPGRADE_TIME 0
|
||||
|
||||
/*****************************************************************************
|
||||
* Global variable or extern global variabls/functions
|
||||
*****************************************************************************/
|
||||
//struct wake_lock ps_lock;
|
||||
|
||||
#define FTS_DEBUG_UPGRADE(fmt, args...) do{\
|
||||
printk(KERN_ERR "[FTS][UPGRADE]:##############################################################################\n");\
|
||||
printk(KERN_ERR "[FTS][UPGRADE]: "fmt"\n", ##args);\
|
||||
printk(KERN_ERR "[FTS][UPGRADE]:##############################################################################\n");\
|
||||
}while(0)\
|
||||
|
||||
/*****************************************************************************
|
||||
* Static function prototypes
|
||||
*****************************************************************************/
|
||||
#if (FTS_UPGRADE_STRESS_TEST)
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_auto_upgrade_pingpong
|
||||
* Brief: 0
|
||||
* Input: 0
|
||||
* Output: 0
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
static int fts_ctpm_auto_upgrade_pingpong(struct i2c_client *client)
|
||||
{
|
||||
u8 uc_tp_fm_ver;
|
||||
int i_ret = 0;
|
||||
u8 uc_upgrade_times = 0;
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
/* pingpong test mode, need upgrade */
|
||||
FTS_INFO("[UPGRADE]: pingpong test mode, need upgrade!!");
|
||||
do
|
||||
{
|
||||
uc_upgrade_times++;
|
||||
|
||||
/* fw upgrade */
|
||||
i_ret = fts_ctpm_fw_upgrade(client);
|
||||
|
||||
if (i_ret == 0) /* upgrade success */
|
||||
{
|
||||
fts_i2c_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
|
||||
FTS_DEBUG("[UPGRADE]: upgrade to new version 0x%x", uc_tp_fm_ver);
|
||||
}
|
||||
else /* upgrade fail */
|
||||
{
|
||||
/* if upgrade fail, reset to run ROM. if app in flash is ok. TP will work success */
|
||||
FTS_INFO("[UPGRADE]: upgrade fail, reset now!!");
|
||||
fts_ctpm_rom_or_pram_reset(client);
|
||||
}
|
||||
}
|
||||
while ((i_ret != 0) && (uc_upgrade_times < 2)); /* if upgrade fail, upgrade again. then return */
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_auto_upgrade
|
||||
* Brief: 0
|
||||
* Input: 0
|
||||
* Output: 0
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
void fts_ctpm_display_upgrade_time(bool start_time)
|
||||
{
|
||||
#if FTS_GET_UPGRADE_TIME
|
||||
static struct timeval tpend;
|
||||
static struct timeval tpstart;
|
||||
static int timeuse;
|
||||
|
||||
if (start_time)
|
||||
{
|
||||
do_gettimeofday(&tpstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_gettimeofday(&tpend);
|
||||
timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec;
|
||||
timeuse/=1000000;
|
||||
FTS_DEBUG( "[UPGRADE]: upgrade success : Use time: %d Seconds!!", timeuse);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_ctpm_auto_upgrade
|
||||
* Brief: 0
|
||||
* Input: 0
|
||||
* Output: 0
|
||||
* Return: 0
|
||||
***********************************************************************/
|
||||
int fts_ctpm_auto_upgrade(struct i2c_client *client)
|
||||
{
|
||||
int i_ret = 0;
|
||||
static int uc_ErrorTimes = 0;
|
||||
static int uc_UpgradeTimes = 0;
|
||||
|
||||
// wake_lock_init(&ps_lock, WAKE_LOCK_SUSPEND, "tp_wakelock");
|
||||
|
||||
// wake_lock(&ps_lock);
|
||||
|
||||
/* (FTS_GET_VENDOR_ID_NUM == 0) */
|
||||
g_fw_file = CTPM_FW;
|
||||
g_fw_len = fts_getsize(FW_SIZE);
|
||||
FTS_DEBUG("[UPGRADE]FW FILE:CTPM_FW, SIZE:%x", g_fw_len);
|
||||
|
||||
do
|
||||
{
|
||||
uc_UpgradeTimes++;
|
||||
|
||||
FTS_DEBUG_UPGRADE("start to upgrade %d times !!", uc_UpgradeTimes);
|
||||
|
||||
fts_ctpm_display_upgrade_time(true);
|
||||
|
||||
i_ret = fts_ctpm_auto_upgrade_pingpong(client);
|
||||
if (i_ret == 0)
|
||||
{
|
||||
fts_ctpm_display_upgrade_time(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
uc_ErrorTimes++;
|
||||
}
|
||||
|
||||
FTS_DEBUG_UPGRADE("upgrade %d times, error %d times!!", uc_UpgradeTimes, uc_ErrorTimes);
|
||||
}
|
||||
while (uc_UpgradeTimes < (FTS_UPGRADE_TEST_NUMBER));
|
||||
|
||||
// wake_unlock(&ps_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
670
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_gesture.c
Executable file
670
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_gesture.c
Executable file
@@ -0,0 +1,670 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, Focaltech Ltd. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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
|
||||
|
||||
/*****************************************************************************
|
||||
* Private enumerations, structures and unions using typedef
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* header - byte0:gesture id
|
||||
* byte1:pointnum
|
||||
* byte2~7:reserved
|
||||
* coordinate_x - All gesture point x coordinate
|
||||
* coordinate_y - All gesture point y coordinate
|
||||
* mode - 1:enable gesture function(default)
|
||||
* - 0:disable
|
||||
* active - 1:enter into gesture(suspend)
|
||||
* 0:gesture disable or resume
|
||||
*/
|
||||
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;
|
||||
|
||||
/*****************************************************************************
|
||||
* 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:
|
||||
* Input: device, device attribute, char buf
|
||||
* Output:
|
||||
* 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:
|
||||
* Input: device, device attribute, char buf, char count
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
static ssize_t fts_gesture_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
mutex_lock(&fts_input_dev->mutex);
|
||||
|
||||
if (FTS_SYSFS_ECHO_ON(buf))
|
||||
{
|
||||
FTS_INFO("[GESTURE]enable gesture");
|
||||
fts_gesture_data.mode = ENABLE;
|
||||
}
|
||||
else if (FTS_SYSFS_ECHO_OFF(buf))
|
||||
{
|
||||
FTS_INFO("[GESTURE]disable gesture");
|
||||
fts_gesture_data.mode = DISABLE;
|
||||
}
|
||||
|
||||
mutex_unlock(&fts_input_dev->mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_buf_show
|
||||
* Brief:
|
||||
* Input: device, device attribute, char buf
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
static ssize_t fts_gesture_buf_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int count;
|
||||
int i = 0;
|
||||
|
||||
mutex_lock(&fts_input_dev->mutex);
|
||||
count = snprintf(buf, PAGE_SIZE, "Gesture ID: 0x%x\n", fts_gesture_data.header[0]);
|
||||
count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum: %d\n", fts_gesture_data.header[1]);
|
||||
count += snprintf(buf + count, PAGE_SIZE, "Gesture Point Buf:\n");
|
||||
for (i = 0; i < fts_gesture_data.header[1]; i++)
|
||||
{
|
||||
count += snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i, fts_gesture_data.coordinate_x[i], fts_gesture_data.coordinate_y[i]);
|
||||
if ((i + 1)%4 == 0)
|
||||
count += snprintf(buf + count, PAGE_SIZE, "\n");
|
||||
}
|
||||
count += snprintf(buf + count, PAGE_SIZE, "\n");
|
||||
mutex_unlock(&fts_input_dev->mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_buf_store
|
||||
* Brief:
|
||||
* Input: device, device attribute, char buf, char count
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
static ssize_t fts_gesture_buf_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
/* place holder for future use */
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_create_gesture_sysfs
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 0-success or others-error
|
||||
*****************************************************************************/
|
||||
int fts_create_gesture_sysfs(struct i2c_client *client)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sysfs_create_group(&client->dev.kobj, &fts_gesture_group);
|
||||
if ( ret != 0)
|
||||
{
|
||||
FTS_ERROR( "[GESTURE]fts_gesture_mode_group(sysfs) create failed!");
|
||||
sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_gesture_report
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
static void fts_gesture_report(struct input_dev *input_dev,int gesture_id)
|
||||
{
|
||||
int gesture;
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
FTS_DEBUG("fts gesture_id==0x%x ",gesture_id);
|
||||
switch (gesture_id)
|
||||
{
|
||||
case GESTURE_LEFT:
|
||||
gesture = KEY_GESTURE_LEFT;
|
||||
break;
|
||||
case GESTURE_RIGHT:
|
||||
gesture = KEY_GESTURE_RIGHT;
|
||||
break;
|
||||
case GESTURE_UP:
|
||||
gesture = KEY_GESTURE_UP;
|
||||
break;
|
||||
case GESTURE_DOWN:
|
||||
gesture = KEY_GESTURE_DOWN;
|
||||
break;
|
||||
case GESTURE_DOUBLECLICK:
|
||||
gesture = KEY_GESTURE_U;
|
||||
break;
|
||||
case GESTURE_O:
|
||||
gesture = KEY_GESTURE_O;
|
||||
break;
|
||||
case GESTURE_W:
|
||||
gesture = KEY_GESTURE_W;
|
||||
break;
|
||||
case GESTURE_M:
|
||||
gesture = KEY_GESTURE_M;
|
||||
break;
|
||||
case GESTURE_E:
|
||||
gesture = KEY_GESTURE_E;
|
||||
break;
|
||||
case GESTURE_L:
|
||||
gesture = KEY_GESTURE_L;
|
||||
break;
|
||||
case GESTURE_S:
|
||||
gesture = KEY_GESTURE_S;
|
||||
break;
|
||||
case GESTURE_V:
|
||||
gesture = KEY_GESTURE_V;
|
||||
break;
|
||||
case GESTURE_Z:
|
||||
gesture = KEY_GESTURE_Z;
|
||||
break;
|
||||
case GESTURE_C:
|
||||
gesture = KEY_GESTURE_C;
|
||||
break;
|
||||
default:
|
||||
gesture = -1;
|
||||
break;
|
||||
}
|
||||
/* report event key */
|
||||
if (gesture != -1)
|
||||
{
|
||||
FTS_DEBUG("Gesture Code=%d", gesture);
|
||||
input_report_key(input_dev, gesture, 1);
|
||||
input_sync(input_dev);
|
||||
input_report_key(input_dev, gesture, 0);
|
||||
input_sync(input_dev);
|
||||
}
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_readdata
|
||||
* Brief: read data from TP register
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: fail <0
|
||||
***********************************************************************/
|
||||
static int fts_gesture_read_buffer(struct i2c_client *client, u8 *buf, int read_bytes)
|
||||
{
|
||||
int remain_bytes;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (read_bytes <= I2C_BUFFER_LENGTH_MAXINUM)
|
||||
{
|
||||
ret = fts_i2c_read(client, buf, 1, buf, read_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = fts_i2c_read(client, buf, 1, buf, I2C_BUFFER_LENGTH_MAXINUM);
|
||||
remain_bytes = read_bytes - I2C_BUFFER_LENGTH_MAXINUM;
|
||||
for (i = 1; remain_bytes > 0; i++)
|
||||
{
|
||||
if (remain_bytes <= I2C_BUFFER_LENGTH_MAXINUM)
|
||||
ret = fts_i2c_read(client, buf, 0, buf + I2C_BUFFER_LENGTH_MAXINUM * i, remain_bytes);
|
||||
else
|
||||
ret = fts_i2c_read(client, buf, 0, buf + I2C_BUFFER_LENGTH_MAXINUM * i, I2C_BUFFER_LENGTH_MAXINUM);
|
||||
remain_bytes -= I2C_BUFFER_LENGTH_MAXINUM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_fw
|
||||
* Brief: Check IC's gesture recognise by FW or not
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: 1- FW 0- Driver
|
||||
***********************************************************************/
|
||||
static int fts_gesture_fw(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (chip_types.chip_idh)
|
||||
{
|
||||
case 0x54:
|
||||
case 0x58:
|
||||
case 0x64:
|
||||
case 0x87:
|
||||
case 0x86:
|
||||
case 0x80:
|
||||
case 0xE7:
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_readdata
|
||||
* Brief: read data from TP register
|
||||
* Input:
|
||||
* Output:
|
||||
* Return: fail <0
|
||||
***********************************************************************/
|
||||
int fts_gesture_readdata(struct i2c_client *client)
|
||||
{
|
||||
u8 buf[FTS_GESTRUE_POINTS * 4] = { 0 };
|
||||
int ret = -1;
|
||||
int i = 0;
|
||||
int gestrue_id = 0;
|
||||
int read_bytes = 0;
|
||||
u8 pointnum;
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
/* init variable before read gesture point */
|
||||
memset(fts_gesture_data.header, 0, FTS_GESTRUE_POINTS_HEADER);
|
||||
memset(fts_gesture_data.coordinate_x, 0, FTS_GESTRUE_POINTS * sizeof(u16));
|
||||
memset(fts_gesture_data.coordinate_y, 0, FTS_GESTRUE_POINTS * sizeof(u16));
|
||||
|
||||
buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
|
||||
ret = fts_i2c_read(client, buf, 1, buf, FTS_GESTRUE_POINTS_HEADER);
|
||||
if (ret < 0)
|
||||
{
|
||||
FTS_ERROR("[GESTURE]Read gesture header data failed!!");
|
||||
FTS_FUNC_EXIT();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FW recognize gesture */
|
||||
if (fts_gesture_fw())
|
||||
{
|
||||
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_gesture_report(fts_input_dev,gestrue_id);
|
||||
for (i = 0; i < pointnum; i++)
|
||||
{
|
||||
fts_gesture_data.coordinate_x[i] = (((s16) buf[0 + (4 * i + 2)]) & 0x0F) << 8
|
||||
| (((s16) buf[1 + (4 * i + 2)]) & 0xFF);
|
||||
fts_gesture_data.coordinate_y[i] = (((s16) buf[2 + (4 * i + 2)]) & 0x0F) << 8
|
||||
| (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
|
||||
}
|
||||
FTS_FUNC_EXIT();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
FTS_ERROR("[GESTURE]IC 0x%x need gesture lib to support gestures.", chip_types.chip_idh);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
/* other IC's gestrue in driver, need gesture library */
|
||||
if (0x24 == buf[0])
|
||||
{
|
||||
gestrue_id = 0x24;
|
||||
fts_gesture_report(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);
|
||||
fts_gesture_report(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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_gesture_recovery
|
||||
* Brief: recovery gesture state when reset or power on
|
||||
* Input:
|
||||
* Output:
|
||||
* 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_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;
|
||||
}
|
||||
|
||||
if (fts_gesture_data.active == 0)
|
||||
{
|
||||
FTS_DEBUG("gesture is unactive");
|
||||
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;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 = 1;
|
||||
fts_gesture_data.active = 0;
|
||||
FTS_FUNC_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Name: fts_gesture_exit
|
||||
* Brief: call when driver removed
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
***********************************************************************/
|
||||
int fts_gesture_exit(struct i2c_client *client)
|
||||
{
|
||||
FTS_FUNC_ENTER();
|
||||
sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
|
||||
FTS_FUNC_EXIT();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
216
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_i2c.c
Executable file
216
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_i2c.c
Executable file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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;
|
||||
}
|
||||
|
||||
153
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
Executable file
153
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_point_report_check.c
Executable file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_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 //ms
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 = NULL;
|
||||
|
||||
/*****************************************************************************
|
||||
* 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;
|
||||
#endif
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
mutex_lock(&fts_wq_data->report_mutex);
|
||||
|
||||
#if FTS_MT_PROTOCOL_B_EN
|
||||
for (finger_count = 0; finger_count < fts_wq_data->pdata->max_touch_number; finger_count++)
|
||||
{
|
||||
input_mt_slot(fts_input_dev, finger_count);
|
||||
input_mt_report_slot_state(fts_input_dev, MT_TOOL_FINGER, false);
|
||||
}
|
||||
#else
|
||||
input_mt_sync(fts_input_dev);
|
||||
#endif
|
||||
input_report_key(fts_input_dev, BTN_TOUCH, 0);
|
||||
input_sync(fts_input_dev);
|
||||
|
||||
mutex_unlock(&fts_wq_data->report_mutex);
|
||||
|
||||
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 */
|
||||
|
||||
329
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_sensor.c
Executable file
329
drivers/amlogic/input/touchscreen/focaltech_touch/focaltech_sensor.c
Executable file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
*
|
||||
* FocalTech TouchScreen driver.
|
||||
*
|
||||
* Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name: focaltech_esdcheck.c
|
||||
*
|
||||
* Author: Focaltech Driver Team
|
||||
*
|
||||
* Created: 2016-08-03
|
||||
*
|
||||
* Abstract: Sensor
|
||||
*
|
||||
* Version: v1.0
|
||||
*
|
||||
* Revision History:
|
||||
* v1.0:
|
||||
* First release. By luougojin 2016-08-03
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Included header files
|
||||
*****************************************************************************/
|
||||
#include "focaltech_core.h"
|
||||
|
||||
#if FTS_PSENSOR_EN
|
||||
/*****************************************************************************
|
||||
* Private constant and macro definitions using #define
|
||||
*****************************************************************************/
|
||||
/* psensor register address*/
|
||||
#define FTS_REG_PSENSOR_ENABLE 0xB0
|
||||
#define FTS_REG_PSENSOR_STATUS 0x01
|
||||
|
||||
/* psensor register bits*/
|
||||
#define FTS_PSENSOR_ENABLE_MASK 0x01
|
||||
#define FTS_PSENSOR_STATUS_NEAR 0xC0
|
||||
#define FTS_PSENSOR_STATUS_FAR 0xE0
|
||||
#define FTS_PSENSOR_FAR_TO_NEAR 0
|
||||
#define FTS_PSENSOR_NEAR_TO_FAR 1
|
||||
#define FTS_PSENSOR_ORIGINAL_STATE_FAR 1
|
||||
#define FTS_PSENSOR_WAKEUP_TIMEOUT 500
|
||||
|
||||
/*****************************************************************************
|
||||
* Static variables
|
||||
*****************************************************************************/
|
||||
static struct sensors_classdev __maybe_unused sensors_proximity_cdev =
|
||||
{
|
||||
.name = "fts-proximity",
|
||||
.vendor = "FocalTech",
|
||||
.version = 1,
|
||||
.handle = SENSORS_PROXIMITY_HANDLE,
|
||||
.type = SENSOR_TYPE_PROXIMITY,
|
||||
.max_range = "5.0",
|
||||
.resolution = "5.0",
|
||||
.sensor_power = "0.1",
|
||||
.min_delay = 0,
|
||||
.fifo_reserved_event_count = 0,
|
||||
.fifo_max_event_count = 0,
|
||||
.enabled = 0,
|
||||
.delay_msec = 200,
|
||||
.sensors_enable = NULL,
|
||||
.sensors_poll_delay = NULL,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* functions body
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
* Name: fts_psensor_support_enabled
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
static inline bool fts_psensor_support_enabled(void)
|
||||
{
|
||||
/*return config_enabled(CONFIG_TOUCHSCREEN_FTS_PSENSOR);*/
|
||||
return FTS_PSENSOR_EN;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: fts_psensor_enable
|
||||
* Brief:
|
||||
* Input:
|
||||
* Output:
|
||||
* Return:
|
||||
*****************************************************************************/
|
||||
static void fts_psensor_enable(struct fts_ts_data *data, int enable)
|
||||
{
|
||||
u8 state;
|
||||
int ret = -1;
|
||||
|
||||
if (data->client == NULL)
|
||||
return;
|
||||
|
||||
fts_i2c_read_reg(data->client, FTS_REG_PSENSOR_ENABLE, &state);
|
||||
if (enable)
|
||||
state |= FTS_PSENSOR_ENABLE_MASK;
|
||||
else
|
||||
state &= ~FTS_PSENSOR_ENABLE_MASK;
|
||||
|
||||
ret = fts_i2c_write_reg(data->client, FTS_REG_PSENSOR_ENABLE, state);
|
||||
if (ret < 0)
|
||||
FTS_ERROR("write psensor switch command failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 */
|
||||
Reference in New Issue
Block a user