From 871480933a1c28f8a9fed4c4d34d06c439a7a422 Mon Sep 17 00:00:00 2001 From: Srikant Patnaik Date: Sun, 11 Jan 2015 12:28:04 +0530 Subject: Moved, renamed, and deleted files The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure. --- drivers/input/touchscreen/ft5x0x/Kconfig | 11 + drivers/input/touchscreen/ft5x0x/Makefile | 34 + drivers/input/touchscreen/ft5x0x/ft5402_config.c | 2295 ++++++++++++++++++++ drivers/input/touchscreen/ft5x0x/ft5402_config.h | 71 + .../input/touchscreen/ft5x0x/ft5402_ini_config.h | 411 ++++ drivers/input/touchscreen/ft5x0x/ft5x0x.c | 937 ++++++++ drivers/input/touchscreen/ft5x0x/ft5x0x.h | 207 ++ drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c | 506 +++++ drivers/input/touchscreen/ft5x0x/ini.c | 406 ++++ drivers/input/touchscreen/ft5x0x/ini.h | 43 + 10 files changed, 4921 insertions(+) create mode 100755 drivers/input/touchscreen/ft5x0x/Kconfig create mode 100755 drivers/input/touchscreen/ft5x0x/Makefile create mode 100755 drivers/input/touchscreen/ft5x0x/ft5402_config.c create mode 100755 drivers/input/touchscreen/ft5x0x/ft5402_config.h create mode 100755 drivers/input/touchscreen/ft5x0x/ft5402_ini_config.h create mode 100755 drivers/input/touchscreen/ft5x0x/ft5x0x.c create mode 100755 drivers/input/touchscreen/ft5x0x/ft5x0x.h create mode 100755 drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c create mode 100755 drivers/input/touchscreen/ft5x0x/ini.c create mode 100755 drivers/input/touchscreen/ft5x0x/ini.h (limited to 'drivers/input/touchscreen/ft5x0x') diff --git a/drivers/input/touchscreen/ft5x0x/Kconfig b/drivers/input/touchscreen/ft5x0x/Kconfig new file mode 100755 index 00000000..7dadb37f --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/Kconfig @@ -0,0 +1,11 @@ +config TOUCHSCREEN_FT5X0X + tristate "FT5X0X Capacity Touchscreen Device Support" + default y + depends on ARCH_WMT + ---help--- + Say Y here if you have an WMT based board with touchscreen + attached to it. + If unsure, say N. + To compile this driver as a module, choose M here: the + module will be called ft5x0x. + diff --git a/drivers/input/touchscreen/ft5x0x/Makefile b/drivers/input/touchscreen/ft5x0x/Makefile new file mode 100755 index 00000000..0283c3ec --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/Makefile @@ -0,0 +1,34 @@ +KERNELDIR=../../../../ +CROSS = arm_1103_le- +CC= $(CROSS)gcc +LD= $(CROSS)ld +STRIP = $(CROSS)strip + +DEBUG = n + +# Add your debugging flag (or not) to EXTRA_CFLAGS +ifeq ($(DEBUG),y) +# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines +DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines + +else + DEBFLAGS = -O2 -Wall +endif + +EXTRA_CFLAGS += $(DEBFLAGS) + + +MY_MODULE_NAME=s_wmt_ts_ft5x0x + +#obj-$(CONFIG_TOUCHSCREEN_FT5X0X) := $(MY_MODULE_NAME).o +obj-m := $(MY_MODULE_NAME).o +$(MY_MODULE_NAME)-objs := ft5x0x.o ft5x0x_upg.o ft5402_config.o ini.o + +default: + $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules + $(STRIP) --strip-debug $(MY_MODULE_NAME).ko + @rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions *.order *.symvers + +clean: + @rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers + diff --git a/drivers/input/touchscreen/ft5x0x/ft5402_config.c b/drivers/input/touchscreen/ft5x0x/ft5402_config.c new file mode 100755 index 00000000..58683ebd --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5402_config.c @@ -0,0 +1,2295 @@ +#include "ft5402_config.h" +//#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ini.h" +#include "ft5402_ini_config.h" +#include "ft5x0x.h" + + +extern int ft5x0x_i2c_txdata(char *txdata, int length); + +int ft5402_write_reg(struct i2c_client * client, u8 regaddr, u8 regvalue) +{ + unsigned char buf[2] = {0}; + buf[0] = regaddr; + buf[1] = regvalue; + + return ft5x0x_i2c_txdata(buf, 2); +} + +int ft5402_read_reg(struct i2c_client * client, u8 regaddr, u8 * regvalue) +{ + int ret; + + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = ®addr, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = regvalue, + }, + }; + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret < 0) + pr_err("function:%s. i2c read error: %d\n", __func__, ret); + return ret; +} + +/*set tx order +*@txNO: offset from tx order start +*@txNO1: tx NO. +*/ +static int ft5402_set_tx_order(struct i2c_client * client, u8 txNO, u8 txNO1) +{ + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) + ReCode = ft5402_write_reg(client, FT5402_REG_TX_ORDER_START + txNO, + txNO1); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_ORDER_START + txNO - FT5402_TX_TEST_MODE_1, + txNO1); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + return ReCode; +} + +/*set tx order +*@txNO: offset from tx order start +*@pTxNo: return value of tx NO. +*/ +static int ft5402_get_tx_order(struct i2c_client * client, u8 txNO, u8 *pTxNo) +{ + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) + ReCode = ft5402_read_reg(client, FT5402_REG_TX_ORDER_START + txNO, + pTxNo); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if(ReCode >= 0) + ReCode = ft5402_read_reg(client, + FT5402_REG_TX_ORDER_START + txNO - FT5402_TX_TEST_MODE_1, + pTxNo); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + return ReCode; +} + +/*set tx cap +*@txNO: tx NO. +*@cap_value: value of cap +*/ +static int ft5402_set_tx_cap(struct i2c_client * client, u8 txNO, u8 cap_value) +{ + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) + ReCode = ft5402_write_reg(client, FT5402_REG_TX_CAP_START + txNO, + cap_value); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_CAP_START + txNO - FT5402_TX_TEST_MODE_1, + cap_value); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + return ReCode; +} + +/*get tx cap*/ +static int ft5402_get_tx_cap(struct i2c_client * client, u8 txNO, u8 *pCap) +{ + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) + ReCode = ft5402_read_reg(client, FT5402_REG_TX_CAP_START + txNO, + pCap); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) + ReCode = ft5402_read_reg(client, + FT5402_REG_TX_CAP_START + txNO - FT5402_TX_TEST_MODE_1, + pCap); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + return ReCode; +} + +/*set tx offset*/ +static int ft5402_set_tx_offset(struct i2c_client * client, u8 txNO, u8 offset_value) +{ + unsigned char temp=0; + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) { + ReCode = ft5402_read_reg(client, + FT5402_REG_TX_OFFSET_START + (txNO>>1), &temp); + if (ReCode >= 0) { + if (txNO%2 == 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_OFFSET_START + (txNO>>1), + (temp&0xf0) + (offset_value&0x0f)); + else + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_OFFSET_START + (txNO>>1), + (temp&0x0f) + (offset_value<<4)); + } + } else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) { + ReCode = ft5402_read_reg(client, + FT5402_REG_DEVICE_MODE+((txNO-FT5402_TX_TEST_MODE_1)>>1), + &temp); /*enter Test mode 2*/ + if (ReCode >= 0) { + if(txNO%2 == 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_OFFSET_START+((txNO-FT5402_TX_TEST_MODE_1)>>1), + (temp&0xf0)+(offset_value&0x0f)); + else + ReCode = ft5402_write_reg(client, + FT5402_REG_TX_OFFSET_START+((txNO-FT5402_TX_TEST_MODE_1)>>1), + (temp&0xf0)+(offset_value<<4)); + } + } + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + return ReCode; +} + +/*get tx offset*/ +static int ft5402_get_tx_offset(struct i2c_client * client, u8 txNO, u8 *pOffset) +{ + unsigned char temp=0; + unsigned char ReCode = 0; + if (txNO < FT5402_TX_TEST_MODE_1) + ReCode = ft5402_read_reg(client, + FT5402_REG_TX_OFFSET_START + (txNO>>1), &temp); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) + ReCode = ft5402_read_reg(client, + FT5402_REG_TX_OFFSET_START+((txNO-FT5402_TX_TEST_MODE_1)>>1), + &temp); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + if (ReCode >= 0) + (txNO%2 == 0) ? (*pOffset = (temp&0x0f)) : (*pOffset = (temp>>4)); + return ReCode; +} + +/*set rx order*/ +static int ft5402_set_rx_order(struct i2c_client * client, u8 rxNO, u8 rxNO1) +{ + unsigned char ReCode = 0; + ReCode = ft5402_write_reg(client, FT5402_REG_RX_ORDER_START + rxNO, + rxNO1); + return ReCode; +} + +/*get rx order*/ +static int ft5402_get_rx_order(struct i2c_client * client, u8 rxNO, u8 *prxNO1) +{ + unsigned char ReCode = 0; + ReCode = ft5402_read_reg(client, FT5402_REG_RX_ORDER_START + rxNO, + prxNO1); + return ReCode; +} + +/*set rx cap*/ +static int ft5402_set_rx_cap(struct i2c_client * client, u8 rxNO, u8 cap_value) +{ + unsigned char ReCode = 0; + if (rxNO < FT5402_RX_TEST_MODE_1) + ReCode = ft5402_write_reg(client, FT5402_REG_RX_CAP_START + rxNO, + cap_value); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if(ReCode >= 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_RX_CAP_START + rxNO - FT5402_RX_TEST_MODE_1, + cap_value); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + return ReCode; +} + +/*get rx cap*/ +static int ft5402_get_rx_cap(struct i2c_client * client, u8 rxNO, u8 *pCap) +{ + unsigned char ReCode = 0; + if (rxNO < FT5402_RX_TEST_MODE_1) + ReCode = ft5402_read_reg(client, FT5402_REG_RX_CAP_START + rxNO, + pCap); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if(ReCode >= 0) + ReCode = ft5402_read_reg(client, + FT5402_REG_RX_CAP_START + rxNO - FT5402_RX_TEST_MODE_1, + pCap); + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + return ReCode; +} + +/*set rx offset*/ +static int ft5402_set_rx_offset(struct i2c_client * client, u8 rxNO, u8 offset_value) +{ + unsigned char temp=0; + unsigned char ReCode = 0; + if (rxNO < FT5402_RX_TEST_MODE_1) { + ReCode = ft5402_read_reg(client, + FT5402_REG_RX_OFFSET_START + (rxNO>>1), &temp); + if (ReCode >= 0) { + if (rxNO%2 == 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_RX_OFFSET_START + (rxNO>>1), + (temp&0xf0) + (offset_value&0x0f)); + else + ReCode = ft5402_write_reg(client, + FT5402_REG_RX_OFFSET_START + (rxNO>>1), + (temp&0x0f) + (offset_value<<4)); + } + } + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) { + ReCode = ft5402_read_reg(client, + FT5402_REG_DEVICE_MODE+((rxNO-FT5402_RX_TEST_MODE_1)>>1), + &temp); /*enter Test mode 2*/ + if (ReCode >= 0) { + if (rxNO%2 == 0) + ReCode = ft5402_write_reg(client, + FT5402_REG_RX_OFFSET_START+((rxNO-FT5402_RX_TEST_MODE_1)>>1), + (temp&0xf0)+(offset_value&0x0f)); + else + ReCode = ft5402_write_reg(client, + FT5402_REG_RX_OFFSET_START+((rxNO-FT5402_RX_TEST_MODE_1)>>1), + (temp&0xf0)+(offset_value<<4)); + } + } + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + return ReCode; +} + +/*get rx offset*/ +static int ft5402_get_rx_offset(struct i2c_client * client, u8 rxNO, u8 *pOffset) +{ + unsigned char temp = 0; + unsigned char ReCode = 0; + if (rxNO < FT5402_RX_TEST_MODE_1) + ReCode = ft5402_read_reg(client, + FT5402_REG_RX_OFFSET_START + (rxNO>>1), &temp); + else { + ReCode = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE_2<<4); /*enter Test mode 2*/ + if (ReCode >= 0) + ReCode = ft5402_read_reg(client, + FT5402_REG_RX_OFFSET_START+((rxNO-FT5402_RX_TEST_MODE_1)>>1), + &temp); + + ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, + FT5402_REG_TEST_MODE<<4); /*enter Test mode*/ + } + + if (ReCode >= 0) { + if (0 == (rxNO%2)) + *pOffset = (temp&0x0f); + else + *pOffset = (temp>>4); + } + + return ReCode; +} + +/*set tx num*/ +static int ft5402_set_tx_num(struct i2c_client *client, u8 txnum) +{ + return ft5402_write_reg(client, FT5402_REG_TX_NUM, txnum); +} + +/*get tx num*/ +static int ft5402_get_tx_num(struct i2c_client *client, u8 *ptxnum) +{ + return ft5402_read_reg(client, FT5402_REG_TX_NUM, ptxnum); +} + +/*set rx num*/ +static int ft5402_set_rx_num(struct i2c_client *client, u8 rxnum) +{ + return ft5402_write_reg(client, FT5402_REG_RX_NUM, rxnum); +} + +/*get rx num*/ +static int ft5402_get_rx_num(struct i2c_client *client, u8 *prxnum) +{ + return ft5402_read_reg(client, FT5402_REG_RX_NUM, prxnum); +} + +/*set resolution*/ +static int ft5402_set_Resolution(struct i2c_client *client, u16 x, u16 y) +{ + unsigned char cRet = 0; + cRet &= ft5402_write_reg(client, + FT5402_REG_RESOLUTION_X_H, ((unsigned char)(x>>8))); + cRet &= ft5402_write_reg(client, + FT5402_REG_RESOLUTION_X_L, ((unsigned char)(x&0x00ff))); + + cRet &= ft5402_write_reg(client, + FT5402_REG_RESOLUTION_Y_H, ((unsigned char)(y>>8))); + cRet &= ft5402_write_reg(client, + FT5402_REG_RESOLUTION_Y_L, ((unsigned char)(y&0x00ff))); + + return cRet; +} + +/*get resolution*/ +static int ft5402_get_Resolution(struct i2c_client *client, + u16 *px, u16 *py) +{ + unsigned char cRet = 0, temp1 = 0, temp2 = 0; + cRet &= ft5402_read_reg(client, + FT5402_REG_RESOLUTION_X_H, &temp1); + cRet &= ft5402_read_reg(client, + FT5402_REG_RESOLUTION_X_L, &temp2); + (*px) = (((u16)temp1) << 8) | ((u16)temp2); + + cRet &= ft5402_read_reg(client, + FT5402_REG_RESOLUTION_Y_H, &temp1); + cRet &= ft5402_read_reg(client, + FT5402_REG_RESOLUTION_Y_L, &temp2); + (*py) = (((u16)temp1) << 8) | ((u16)temp2); + + return cRet; +} + + +/*set voltage*/ +static int ft5402_set_vol(struct i2c_client *client, u8 Vol) +{ + return ft5402_write_reg(client, FT5402_REG_VOLTAGE, Vol); +} + +/*get voltage*/ +static int ft5402_get_vol(struct i2c_client *client, u8 *pVol) +{ + return ft5402_read_reg(client, FT5402_REG_VOLTAGE, pVol); +} + +/*set gain*/ +static int ft5402_set_gain(struct i2c_client *client, u8 Gain) +{ + return ft5402_write_reg(client, FT5402_REG_GAIN, Gain); +} + +/*get gain*/ +static int ft5402_get_gain(struct i2c_client *client, u8 *pGain) +{ + return ft5402_read_reg(client, FT5402_REG_GAIN, pGain); +} + +/*get start rx*/ +static int ft5402_get_start_rx(struct i2c_client *client, u8 *pRx) +{ + return ft5402_read_reg(client, FT5402_REG_START_RX, pRx); +} + + +/*get adc target*/ +static int ft5402_get_adc_target(struct i2c_client *client, u16 *pvalue) +{ + int err = 0; + u8 tmp1, tmp2; + err = ft5402_read_reg(client, FT5402_REG_ADC_TARGET_HIGH, + &tmp1); + if (err < 0) + dev_err(&client->dev, "%s:get adc target high failed\n", + __func__); + err = ft5402_read_reg(client, FT5402_REG_ADC_TARGET_LOW, + &tmp2); + if (err < 0) + dev_err(&client->dev, "%s:get adc target low failed\n", + __func__); + + *pvalue = ((u16)tmp1<<8) + (u16)tmp2; + return err; +} + +static int ft5402_set_face_detect_statistics_tx_num(struct i2c_client *client, u8 prevalue) +{ + return ft5402_write_reg(client, FT5402_REG_FACE_DETECT_STATISTICS_TX_NUM, + prevalue); +} + +static int ft5402_get_face_detect_statistics_tx_num(struct i2c_client *client, u8 *pprevalue) +{ + return ft5402_read_reg(client, FT5402_REG_FACE_DETECT_STATISTICS_TX_NUM, + pprevalue); +} + +static int ft5402_set_face_detect_pre_value(struct i2c_client *client, u8 prevalue) +{ + return ft5402_write_reg(client, FT5402_REG_FACE_DETECT_PRE_VALUE, + prevalue); +} + +static int ft5402_get_face_detect_pre_value(struct i2c_client *client, u8 *pprevalue) +{ + return ft5402_read_reg(client, FT5402_REG_FACE_DETECT_PRE_VALUE, + pprevalue); +} + +static int ft5402_set_face_detect_num(struct i2c_client *client, u8 num) +{ + return ft5402_write_reg(client, FT5402_REG_FACE_DETECT_NUM, + num); +} + +static int ft5402_get_face_detect_num(struct i2c_client *client, u8 *pnum) +{ + return ft5402_read_reg(client, FT5402_REG_FACE_DETECT_NUM, + pnum); +} + + +static int ft5402_set_peak_value_min(struct i2c_client *client, u8 min) +{ + return ft5402_write_reg(client, FT5402_REG_BIGAREA_PEAK_VALUE_MIN, + min); +} + +static int ft5402_get_peak_value_min(struct i2c_client *client, u8 *pmin) +{ + return ft5402_read_reg(client, FT5402_REG_BIGAREA_PEAK_VALUE_MIN, + pmin); +} + +static int ft5402_set_diff_value_over_num(struct i2c_client *client, u8 num) +{ + return ft5402_write_reg(client, FT5402_REG_BIGAREA_DIFF_VALUE_OVER_NUM, + num); +} +static int ft5402_get_diff_value_over_num(struct i2c_client *client, u8 *pnum) +{ + return ft5402_read_reg(client, FT5402_REG_BIGAREA_DIFF_VALUE_OVER_NUM, + pnum); +} + + +static int ft5402_set_customer_id(struct i2c_client *client, u8 num) +{ + return ft5402_write_reg(client, FT5402_REG_CUSTOMER_ID, + num); +} +static int ft5402_get_customer_id(struct i2c_client *client, u8 *pnum) +{ + return ft5402_read_reg(client, FT5402_REG_CUSTOMER_ID, + pnum); +} + +static int ft5402_set_kx(struct i2c_client *client, u16 value) +{ + int err = 0; + err = ft5402_write_reg(client, FT5402_REG_KX_H, + value >> 8); + if (err < 0) + dev_err(&client->dev, "%s:set kx high failed\n", + __func__); + err = ft5402_write_reg(client, FT5402_REG_KX_L, + value); + if (err < 0) + dev_err(&client->dev, "%s:set kx low failed\n", + __func__); + + return err; +} + +static int ft5402_get_kx(struct i2c_client *client, u16 *pvalue) +{ + int err = 0; + u8 tmp1, tmp2; + err = ft5402_read_reg(client, FT5402_REG_KX_H, + &tmp1); + if (err < 0) + dev_err(&client->dev, "%s:get kx high failed\n", + __func__); + err = ft5402_read_reg(client, FT5402_REG_KX_L, + &tmp2); + if (err < 0) + dev_err(&client->dev, "%s:get kx low failed\n", + __func__); + + *pvalue = ((u16)tmp1<<8) + (u16)tmp2; + return err; +} +static int ft5402_set_ky(struct i2c_client *client, u16 value) +{ + int err = 0; + err = ft5402_write_reg(client, FT5402_REG_KY_H, + value >> 8); + if (err < 0) + dev_err(&client->dev, "%s:set ky high failed\n", + __func__); + err = ft5402_write_reg(client, FT5402_REG_KY_L, + value); + if (err < 0) + dev_err(&client->dev, "%s:set ky low failed\n", + __func__); + + return err; +} + +static int ft5402_get_ky(struct i2c_client *client, u16 *pvalue) +{ + int err = 0; + u8 tmp1, tmp2; + err = ft5402_read_reg(client, FT5402_REG_KY_H, + &tmp1); + if (err < 0) + dev_err(&client->dev, "%s:get ky high failed\n", + __func__); + err = ft5402_read_reg(client, FT5402_REG_KY_L, + &tmp2); + if (err < 0) + dev_err(&client->dev, "%s:get ky low failed\n", + __func__); + + *pvalue = ((u16)tmp1<<8) + (u16)tmp2; + return err; +} +static int ft5402_set_lemda_x(struct i2c_client *client, u8 value) +{ + return ft5402_write_reg(client, FT5402_REG_LEMDA_X, + value); +} + +static int ft5402_get_lemda_x(struct i2c_client *client, u8 *pvalue) +{ + return ft5402_read_reg(client, FT5402_REG_LEMDA_X, + pvalue); +} +static int ft5402_set_lemda_y(struct i2c_client *client, u8 value) +{ + return ft5402_write_reg(client, FT5402_REG_LEMDA_Y, + value); +} + +static int ft5402_get_lemda_y(struct i2c_client *client, u8 *pvalue) +{ + return ft5402_read_reg(client, FT5402_REG_LEMDA_Y, + pvalue); +} +static int ft5402_set_pos_x(struct i2c_client *client, u8 value) +{ + return ft5402_write_reg(client, FT5402_REG_DIRECTION, + value); +} + +static int ft5402_get_pos_x(struct i2c_client *client, u8 *pvalue) +{ + return ft5402_read_reg(client, FT5402_REG_DIRECTION, + pvalue); +} + +static int ft5402_set_scan_select(struct i2c_client *client, u8 value) +{ + return ft5402_write_reg(client, FT5402_REG_SCAN_SELECT, + value); +} + +static int ft5402_get_scan_select(struct i2c_client *client, u8 *pvalue) +{ + return ft5402_read_reg(client, FT5402_REG_SCAN_SELECT, + pvalue); +} + +static int ft5402_set_other_param(struct i2c_client *client) +{ + int err = 0; + err = ft5402_write_reg(client, FT5402_REG_THGROUP, (u8)(g_param_ft5402.ft5402_THGROUP)); + if (err < 0) { + dev_err(&client->dev, "%s:write THGROUP failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_THPEAK, g_param_ft5402.ft5402_THPEAK); + if (err < 0) { + dev_err(&client->dev, "%s:write THPEAK failed.\n", + __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_PWMODE_CTRL, + g_param_ft5402.ft5402_PWMODE_CTRL); + if (err < 0) { + dev_err(&client->dev, "%s:write PERIOD_CTRL failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_PERIOD_ACTIVE, + g_param_ft5402.ft5402_PERIOD_ACTIVE); + if (err < 0) { + dev_err(&client->dev, "%s:write PERIOD_ACTIVE failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FACE_DETECT_STATISTICS_TX_NUM, + g_param_ft5402.ft5402_FACE_DETECT_STATISTICS_TX_NUM); + if (err < 0) { + dev_err(&client->dev, "%s:write FACE_DETECT_STATISTICS_TX_NUM failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_MAX_TOUCH_VALUE_HIGH, + g_param_ft5402.ft5402_MAX_TOUCH_VALUE>>8); + if (err < 0) { + dev_err(&client->dev, "%s:write MAX_TOUCH_VALUE_HIGH failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_MAX_TOUCH_VALUE_LOW, + g_param_ft5402.ft5402_MAX_TOUCH_VALUE); + if (err < 0) { + dev_err(&client->dev, "%s:write MAX_TOUCH_VALUE_LOW failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FACE_DETECT_MODE, + g_param_ft5402.ft5402_FACE_DETECT_MODE); + if (err < 0) { + dev_err(&client->dev, "%s:write FACE_DETECT_MODE failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_DRAW_LINE_TH, + g_param_ft5402.ft5402_DRAW_LINE_TH); + if (err < 0) { + dev_err(&client->dev, "%s:write DRAW_LINE_TH failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_POINTS_SUPPORTED, + g_param_ft5402.ft5402_POINTS_SUPPORTED); + if (err < 0) { + dev_err(&client->dev, "%s:write POINTS_SUPPORTED failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_ESD_FILTER_FRAME, + g_param_ft5402.ft5402_ESD_FILTER_FRAME); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_ESD_FILTER_FRAME failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_POINTS_STABLE_MACRO, + g_param_ft5402.ft5402_POINTS_STABLE_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_POINTS_STABLE_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_MIN_DELTA_X, + g_param_ft5402.ft5402_MIN_DELTA_X); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_MIN_DELTA_X failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_MIN_DELTA_Y, + g_param_ft5402.ft5402_MIN_DELTA_Y); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_MIN_DELTA_Y failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_MIN_DELTA_STEP, + g_param_ft5402.ft5402_MIN_DELTA_STEP); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_MIN_DELTA_STEP failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_ESD_NOISE_MACRO, + g_param_ft5402.ft5402_ESD_NOISE_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_ESD_NOISE_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_ESD_DIFF_VAL, + g_param_ft5402.ft5402_ESD_DIFF_VAL); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_ESD_DIFF_VAL failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_ESD_NEGTIVE, + g_param_ft5402.ft5402_ESD_NEGTIVE); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_ESD_NEGTIVE failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_ESD_FILTER_FRAMES, + g_param_ft5402.ft5402_ESD_FILTER_FRAMES); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_ESD_FILTER_FRAMES failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_IO_LEVEL_SELECT, + g_param_ft5402.ft5402_IO_LEVEL_SELECT); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_IO_LEVEL_SELECT failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_POINTID_DELAY_COUNT, + g_param_ft5402.ft5402_POINTID_DELAY_COUNT); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_POINTID_DELAY_COUNT failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_LIFTUP_FILTER_MACRO, + g_param_ft5402.ft5402_LIFTUP_FILTER_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_LIFTUP_FILTER_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_DIFF_HANDLE_MACRO, + g_param_ft5402.ft5402_DIFF_HANDLE_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_DIFF_HANDLE_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_MIN_WATER, + g_param_ft5402.ft5402_MIN_WATER); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_MIN_WATER failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_MAX_NOISE, + g_param_ft5402.ft5402_MAX_NOISE); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_MAX_NOISE failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_WATER_START_RX, + g_param_ft5402.ft5402_WATER_START_RX); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_WATER_START_RX failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_WATER_START_TX, + g_param_ft5402.ft5402_WATER_START_TX); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_WATER_START_TX failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_HOST_NUMBER_SUPPORTED_MACRO, + g_param_ft5402.ft5402_HOST_NUMBER_SUPPORTED_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_HOST_NUMBER_SUPPORTED_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_RAISE_THGROUP, + g_param_ft5402.ft5402_RAISE_THGROUP); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_RAISE_THGROUP failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_CHARGER_STATE, + g_param_ft5402.ft5402_CHARGER_STATE); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_CHARGER_STATE failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FILTERID_START, + g_param_ft5402.ft5402_FILTERID_START); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FILTERID_START failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_EN_MACRO, + g_param_ft5402.ft5402_FRAME_FILTER_EN_MACRO); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_EN_MACRO failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_SUB_MAX_TH, + g_param_ft5402.ft5402_FRAME_FILTER_SUB_MAX_TH); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_SUB_MAX_TH failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_ADD_MAX_TH, + g_param_ft5402.ft5402_FRAME_FILTER_ADD_MAX_TH); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_ADD_MAX_TH failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_SKIP_START_FRAME, + g_param_ft5402.ft5402_FRAME_FILTER_SKIP_START_FRAME); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_SKIP_START_FRAME failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_BAND_EN, + g_param_ft5402.ft5402_FRAME_FILTER_BAND_EN); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_BAND_EN failed.\n", __func__); + return err; + } + + err = ft5402_write_reg(client, FT5402_REG_FT5402_FRAME_FILTER_BAND_WIDTH, + g_param_ft5402.ft5402_FRAME_FILTER_BAND_WIDTH); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_FRAME_FILTER_BAND_WIDTH failed.\n", __func__); + return err; + } + + return err; +} + +static int ft5402_get_other_param(struct i2c_client *client) +{ + int err = 0; + u8 value = 0x00; + err = ft5402_read_reg(client, FT5402_REG_THGROUP, &value); + if (err < 0) { + dev_err(&client->dev, "%s:write THGROUP failed.\n", __func__); + return err; + } else + DBG("THGROUP=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_THPEAK, &value); + if (err < 0) { + dev_err(&client->dev, "%s:write THPEAK failed.\n", + __func__); + return err; + } else + DBG("THPEAK=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_PWMODE_CTRL, &value); + if (err < 0) { + dev_err(&client->dev, "%s:write PWMODE_CTRL failed.\n", __func__); + return err; + } else + DBG("CTRL=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_PERIOD_ACTIVE, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write PERIOD_ACTIVE failed.\n", __func__); + return err; + } else + DBG("PERIOD_ACTIVE=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_MAX_TOUCH_VALUE_HIGH, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write MAX_TOUCH_VALUE_HIGH failed.\n", __func__); + return err; + } else + DBG("MAX_TOUCH_VALUE_HIGH=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_MAX_TOUCH_VALUE_LOW, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write MAX_TOUCH_VALUE_LOW failed.\n", __func__); + return err; + } else + DBG("MAX_TOUCH_VALUE_LOW=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_FACE_DETECT_MODE, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FACE_DETECT_MODE failed.\n", __func__); + return err; + } else + DBG("FACE_DEC_MODE=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_DRAW_LINE_TH, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write DRAW_LINE_TH failed.\n", __func__); + return err; + } else + DBG("DRAW_LINE_TH=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_POINTS_SUPPORTED, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write ft5402_POINTS_SUPPORTED failed.\n", __func__); + return err; + } else + DBG("ft5402_POINTS_SUPPORTED=%02x\n", value); + err = ft5402_read_reg(client, FT5402_REG_ESD_FILTER_FRAME, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_ESD_FILTER_FRAME failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_ESD_FILTER_FRAME=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_POINTS_STABLE_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_POINTS_STABLE_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_POINTS_STABLE_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_MIN_DELTA_X, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_MIN_DELTA_X failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_MIN_DELTA_X=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_MIN_DELTA_Y, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_MIN_DELTA_Y failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_MIN_DELTA_Y=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_MIN_DELTA_STEP, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_MIN_DELTA_STEP failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_MIN_DELTA_STEP=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_ESD_NOISE_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_ESD_NOISE_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_ESD_NOISE_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_ESD_DIFF_VAL, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_ESD_DIFF_VAL failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_ESD_DIFF_VAL=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_ESD_NEGTIVE, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_ESD_NEGTIVE failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_ESD_NEGTIVE=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_ESD_FILTER_FRAMES, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_ESD_FILTER_FRAMES failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_ESD_FILTER_FRAMES=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_IO_LEVEL_SELECT, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_IO_LEVEL_SELECT failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_IO_LEVEL_SELECT=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_POINTID_DELAY_COUNT, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_POINTID_DELAY_COUNT failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_POINTID_DELAY_COUNT=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_LIFTUP_FILTER_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_LIFTUP_FILTER_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_LIFTUP_FILTER_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_DIFF_HANDLE_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_DIFF_HANDLE_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_DIFF_HANDLE_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_MIN_WATER, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_MIN_WATER failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_MIN_WATER=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_MAX_NOISE, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_MAX_NOISE failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_MAX_NOISE=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_WATER_START_RX, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_WATER_START_RX failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_WATER_START_RX=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_WATER_START_TX, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_WATER_START_TX failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_WATER_START_TX=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_HOST_NUMBER_SUPPORTED_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_HOST_NUMBER_SUPPORTED_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_HOST_NUMBER_SUPPORTED_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_RAISE_THGROUP, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_RAISE_THGROUP failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_RAISE_THGROUP=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_CHARGER_STATE, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_CHARGER_STATE failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_CHARGER_STATE=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FILTERID_START, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FILTERID_START failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FILTERID_START=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_EN_MACRO, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_EN_MACRO failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_EN_MACRO=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_SUB_MAX_TH, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_SUB_MAX_TH failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_SUB_MAX_TH=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_ADD_MAX_TH, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_ADD_MAX_TH failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_ADD_MAX_TH=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_SKIP_START_FRAME, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_SKIP_START_FRAME failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_SKIP_START_FRAME=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_BAND_EN, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_BAND_EN failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_BAND_EN=%02x\n", value); + + err = ft5402_read_reg(client, FT5402_REG_FT5402_FRAME_FILTER_BAND_WIDTH, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:write FT5402_REG_FT5402_FRAME_FILTER_BAND_WIDTH failed.\n", __func__); + return err; + } else + DBG("FT5402_REG_FT5402_FRAME_FILTER_BAND_WIDTH=%02x\n", value); + + return err; +} +int ft5402_get_ic_param(struct i2c_client *client) +{ + int err = 0; + int i = 0; + u8 value = 0x00; + u16 xvalue = 0x0000, yvalue = 0x0000; + + /*enter factory mode*/ + err = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, FT5402_FACTORYMODE_VALUE); + if (err < 0) { + dev_err(&client->dev, "%s:enter factory mode failed.\n", __func__); + goto RETURN_WORK; + } + + for (i = 0; i < g_ft5402_tx_num; i++) { + DBG("tx%d:", i); + /*get tx order*/ + err = ft5402_get_tx_order(client, i, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get tx%d order.\n", + __func__, i); + goto RETURN_WORK; + } + DBG("order=%d ", value); + /*get tx cap*/ + err = ft5402_get_tx_cap(client, i, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get tx%d cap.\n", + __func__, i); + goto RETURN_WORK; + } + DBG("cap=%02x\n", value); + } + /*get tx offset*/ + err = ft5402_get_tx_offset(client, 0, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get tx 0 offset.\n", + __func__); + goto RETURN_WORK; + } else + DBG("tx offset = %02x\n", value); + + /*get rx offset and cap*/ + for (i = 0; i < g_ft5402_rx_num; i++) { + /*get rx order*/ + DBG("rx%d:", i); + err = ft5402_get_rx_order(client, i, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get rx%d order.\n", + __func__, i); + goto RETURN_WORK; + } + DBG("order=%d ", value); + /*get rx cap*/ + err = ft5402_get_rx_cap(client, i, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get rx%d cap.\n", + __func__, i); + goto RETURN_WORK; + } + DBG("cap=%02x ", value); + err = ft5402_get_rx_offset(client, i, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get rx offset.\n", + __func__); + goto RETURN_WORK; + } + DBG("offset=%02x\n", value); + } + + /*get scan select*/ + err = ft5402_get_scan_select(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get scan select.\n", + __func__); + goto RETURN_WORK; + } else + DBG("scan select = %02x\n", value); + + /*get tx number*/ + err = ft5402_get_tx_num(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get tx num.\n", + __func__); + goto RETURN_WORK; + } else + DBG("tx num = %02x\n", value); + /*get rx number*/ + err = ft5402_get_rx_num(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get rx num.\n", + __func__); + goto RETURN_WORK; + } else + DBG("rx num = %02x\n", value); + + /*get gain*/ + err = ft5402_get_gain(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get gain.\n", + __func__); + goto RETURN_WORK; + } else + DBG("gain = %02x\n", value); + /*get voltage*/ + err = ft5402_get_vol(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get voltage.\n", + __func__); + goto RETURN_WORK; + } else + DBG("voltage = %02x\n", value); + /*get start rx*/ + err = ft5402_get_start_rx(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get start rx.\n", + __func__); + goto RETURN_WORK; + } else + DBG("start rx = %02x\n", value); + /*get adc target*/ + err = ft5402_get_adc_target(client, &xvalue); + if (err < 0) { + dev_err(&client->dev, "%s:could not get adc target.\n", + __func__); + goto ERR_EXIT; + } else + DBG("ADC target = %02x\n", xvalue); + + +RETURN_WORK: + /*enter work mode*/ + err = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, FT5402_WORKMODE_VALUE); + if (err < 0) { + dev_err(&client->dev, "%s:enter work mode failed.\n", __func__); + goto ERR_EXIT; + } + + /*get resolution*/ + err = ft5402_get_Resolution(client, &xvalue, &yvalue); + if (err < 0) { + dev_err(&client->dev, "%s:could not get resolution.\n", + __func__); + goto ERR_EXIT; + } else + DBG("resolution X = %d Y = %d\n", xvalue, yvalue); + + + /*get face detect statistics tx num*/ + err = ft5402_get_face_detect_statistics_tx_num(client, + &value); + if (err < 0) { + dev_err(&client->dev, + "%s:could not get face detect statistics tx num.\n", + __func__); + goto ERR_EXIT; + } else + DBG("FT5402_FACE_DETECT_STATISTICS_TX_NUM = %02x\n", value); + /*get face detect pre value*/ + err = ft5402_get_face_detect_pre_value(client, + &value); + if (err < 0) { + dev_err(&client->dev, + "%s:could not get face detect pre value.\n", + __func__); + goto ERR_EXIT; + } else + DBG("FT5402_FACE_DETECT_PRE_VALUE = %02x\n", value); + /*get face detect num*/ + err = ft5402_get_face_detect_num(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get face detect num.\n", + __func__); + goto ERR_EXIT; + } else + DBG("face detect num = %02x\n", value); + + /*get min peak value*/ + err = ft5402_get_peak_value_min(client, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get min peak value.\n", + __func__); + goto ERR_EXIT; + } else + DBG("FT5402_BIGAREA_PEAK_VALUE_MIN = %02x\n", value); + /*get diff value over num*/ + err = ft5402_get_diff_value_over_num(client, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get diff value over num.\n", + __func__); + goto ERR_EXIT; + } else + DBG("FT5402_BIGAREA_DIFF_VALUE_OVER_NUM = %02x\n", value); + /*get customer id*/ + err = ft5402_get_customer_id(client, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get customer id.\n", + __func__); + goto ERR_EXIT; + } else + DBG("FT5402_CUSTOMER_ID = %02x\n", value); + /*get kx*/ + err = ft5402_get_kx(client, &xvalue); + if (err < 0) { + dev_err(&client->dev, "%s:could not get kx.\n", + __func__); + goto ERR_EXIT; + } else + DBG("kx = %02x\n", xvalue); + /*get ky*/ + err = ft5402_get_ky(client, &xvalue); + if (err < 0) { + dev_err(&client->dev, "%s:could not get ky.\n", + __func__); + goto ERR_EXIT; + } else + DBG("ky = %02x\n", xvalue); + /*get lemda x*/ + err = ft5402_get_lemda_x(client, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get lemda x.\n", + __func__); + goto ERR_EXIT; + } else + DBG("lemda x = %02x\n", value); + /*get lemda y*/ + err = ft5402_get_lemda_y(client, + &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get lemda y.\n", + __func__); + goto ERR_EXIT; + } else + DBG("lemda y = %02x\n", value); + /*get pos x*/ + err = ft5402_get_pos_x(client, &value); + if (err < 0) { + dev_err(&client->dev, "%s:could not get pos x.\n", + __func__); + goto ERR_EXIT; + } else + DBG("pos x = %02x\n", value); + + err = ft5402_get_other_param(client); + +ERR_EXIT: + return err; +} + +int ft5402_Init_IC_Param(struct i2c_client *client) +{ + int err = 0; + int i = 0; + + /*enter factory mode*/ + err = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, FT5402_FACTORYMODE_VALUE); + if (err < 0) { + dev_err(&client->dev, "%s:enter factory mode failed.\n", __func__); + goto RETURN_WORK; + } + + for (i = 0; i < g_ft5402_tx_num; i++) { + if (g_ft5402_tx_order[i] != 0xFF) { + /*set tx order*/ + err = ft5402_set_tx_order(client, i, g_ft5402_tx_order[i]); + if (err < 0) { + dev_err(&client->dev, "%s:could not set tx%d order.\n", + __func__, i); + goto RETURN_WORK; + } + } + /*set tx cap*/ + err = ft5402_set_tx_cap(client, i, g_ft5402_tx_cap[i]); + if (err < 0) { + dev_err(&client->dev, "%s:could not set tx%d cap.\n", + __func__, i); + goto RETURN_WORK; + } + } + /*set tx offset*/ + err = ft5402_set_tx_offset(client, 0, g_ft5402_tx_offset); + if (err < 0) { + dev_err(&client->dev, "%s:could not set tx 0 offset.\n", + __func__); + goto RETURN_WORK; + } + + /*set rx offset and cap*/ + for (i = 0; i < g_ft5402_rx_num; i++) { + /*set rx order*/ + err = ft5402_set_rx_order(client, i, g_ft5402_rx_order[i]); + if (err < 0) { + dev_err(&client->dev, "%s:could not set rx%d order.\n", + __func__, i); + goto RETURN_WORK; + } + /*set rx cap*/ + err = ft5402_set_rx_cap(client, i, g_ft5402_rx_cap[i]); + if (err < 0) { + dev_err(&client->dev, "%s:could not set rx%d cap.\n", + __func__, i); + goto RETURN_WORK; + } + } + for (i = 0; i < g_ft5402_rx_num/2; i++) { + err = ft5402_set_rx_offset(client, i*2, g_ft5402_rx_offset[i]>>4); + if (err < 0) { + dev_err(&client->dev, "%s:could not set rx offset.\n", + __func__); + goto RETURN_WORK; + } + err = ft5402_set_rx_offset(client, i*2+1, g_ft5402_rx_offset[i]&0x0F); + if (err < 0) { + dev_err(&client->dev, "%s:could not set rx offset.\n", + __func__); + goto RETURN_WORK; + } + } + + /*set scan select*/ + err = ft5402_set_scan_select(client, g_ft5402_scanselect); + if (err < 0) { + dev_err(&client->dev, "%s:could not set scan select.\n", + __func__); + goto RETURN_WORK; + } + + /*set tx number*/ + err = ft5402_set_tx_num(client, g_ft5402_tx_num); + if (err < 0) { + dev_err(&client->dev, "%s:could not set tx num.\n", + __func__); + goto RETURN_WORK; + } + /*set rx number*/ + err = ft5402_set_rx_num(client, g_ft5402_rx_num); + if (err < 0) { + dev_err(&client->dev, "%s:could not set rx num.\n", + __func__); + goto RETURN_WORK; + } + + /*set gain*/ + err = ft5402_set_gain(client, g_ft5402_gain); + if (err < 0) { + dev_err(&client->dev, "%s:could not set gain.\n", + __func__); + goto RETURN_WORK; + } + /*set voltage*/ + err = ft5402_set_vol(client, g_ft5402_voltage); + if (err < 0) { + dev_err(&client->dev, "%s:could not set voltage.\n", + __func__); + goto RETURN_WORK; + } + + err = ft5402_write_reg(client, FT5402_REG_ADC_TARGET_HIGH, + g_param_ft5402.ft5402_ADC_TARGET>>8); + if (err < 0) { + dev_err(&client->dev, "%s:write ADC_TARGET_HIGH failed.\n", __func__); + return err; + } + err = ft5402_write_reg(client, FT5402_REG_ADC_TARGET_LOW, + g_param_ft5402.ft5402_ADC_TARGET); + if (err < 0) { + dev_err(&client->dev, "%s:write ADC_TARGET_LOW failed.\n", __func__); + return err; + } + +RETURN_WORK: + /*enter work mode*/ + err = ft5402_write_reg(client, FT5402_REG_DEVICE_MODE, FT5402_WORKMODE_VALUE); + if (err < 0) { + dev_err(&client->dev, "%s:enter work mode failed.\n", __func__); + goto ERR_EXIT; + } + + /*set resolution*/ + err = ft5402_set_Resolution(client, g_param_ft5402.ft5402_RESOLUTION_X, + g_param_ft5402.ft5402_RESOLUTION_Y); + if (err < 0) { + dev_err(&client->dev, "%s:could not set resolution.\n", + __func__); + goto ERR_EXIT; + } + + /*set face detect statistics tx num*/ + err = ft5402_set_face_detect_statistics_tx_num(client, + g_param_ft5402.ft5402_FACE_DETECT_STATISTICS_TX_NUM); + if (err < 0) { + dev_err(&client->dev, + "%s:could not set face detect statistics tx num.\n", + __func__); + goto ERR_EXIT; + } + /*set face detect pre value*/ + err = ft5402_set_face_detect_pre_value(client, + g_param_ft5402.ft5402_FACE_DETECT_PRE_VALUE); + if (err < 0) { + dev_err(&client->dev, + "%s:could not set face detect pre value.\n", + __func__); + goto ERR_EXIT; + } + /*set face detect num*/ + err = ft5402_set_face_detect_num(client, + g_param_ft5402.ft5402_FACE_DETECT_NUM); + if (err < 0) { + dev_err(&client->dev, "%s:could not set face detect num.\n", + __func__); + goto ERR_EXIT; + } + + /*set min peak value*/ + err = ft5402_set_peak_value_min(client, + g_param_ft5402.ft5402_BIGAREA_PEAK_VALUE_MIN); + if (err < 0) { + dev_err(&client->dev, "%s:could not set min peak value.\n", + __func__); + goto ERR_EXIT; + } + /*set diff value over num*/ + err = ft5402_set_diff_value_over_num(client, + g_param_ft5402.ft5402_BIGAREA_DIFF_VALUE_OVER_NUM); + if (err < 0) { + dev_err(&client->dev, "%s:could not set diff value over num.\n", + __func__); + goto ERR_EXIT; + } + /*set customer id*/ + err = ft5402_set_customer_id(client, + g_param_ft5402.ft5402_CUSTOMER_ID); + if (err < 0) { + dev_err(&client->dev, "%s:could not set customer id.\n", + __func__); + goto ERR_EXIT; + } + /*set kx*/ + err = ft5402_set_kx(client, g_param_ft5402.ft5402_KX); + if (err < 0) { + dev_err(&client->dev, "%s:could not set kx.\n", + __func__); + goto ERR_EXIT; + } + /*set ky*/ + err = ft5402_set_ky(client, g_param_ft5402.ft5402_KY); + if (err < 0) { + dev_err(&client->dev, "%s:could not set ky.\n", + __func__); + goto ERR_EXIT; + } + /*set lemda x*/ + err = ft5402_set_lemda_x(client, + g_param_ft5402.ft5402_LEMDA_X); + if (err < 0) { + dev_err(&client->dev, "%s:could not set lemda x.\n", + __func__); + goto ERR_EXIT; + } + /*set lemda y*/ + err = ft5402_set_lemda_y(client, + g_param_ft5402.ft5402_LEMDA_Y); + if (err < 0) { + dev_err(&client->dev, "%s:could not set lemda y.\n", + __func__); + goto ERR_EXIT; + } + /*set pos x*/ + err = ft5402_set_pos_x(client, g_param_ft5402.ft5402_DIRECTION); + if (err < 0) { + dev_err(&client->dev, "%s:could not set pos x.\n", + __func__); + goto ERR_EXIT; + } + + err = ft5402_set_other_param(client); + +ERR_EXIT: + return err; +} + + +char dst[512]; +static char * ft5402_sub_str(char * src, int n) +{ + char *p = src; + int i; + int m = 0; + int len = strlen(src); + + while (n >= 1 && m <= len) { + i = 0; + dst[10] = ' '; + n--; + while ( *p != ',' && *p != ' ') { + dst[i++] = *(p++); + m++; + if (i >= len) + break; + } + dst[i++] = '\0'; + p++; + } + return dst; +} +static int ft5402_GetInISize(char *config_name) +{ + struct file *pfile = NULL; + struct inode *inode; + unsigned long magic; + off_t fsize = 0; + char filepath[128]; + memset(filepath, 0, sizeof(filepath)); + + sprintf(filepath, "%s%s", FT5402_INI_FILEPATH, config_name); + + if (NULL == pfile) + pfile = filp_open(filepath, O_RDONLY, 0); + + if (IS_ERR(pfile)) { + pr_err("error occured while opening file %s.\n", filepath); + return -EIO; + } + + inode = pfile->f_dentry->d_inode; + magic = inode->i_sb->s_magic; + fsize = inode->i_size; + filp_close(pfile, NULL); + return fsize; +} + +static int ft5x0x_ReadInIData(char *config_name, + char *config_buf) +{ + struct file *pfile = NULL; + struct inode *inode; + unsigned long magic; + off_t fsize; + char filepath[128]; + loff_t pos; + mm_segment_t old_fs; + + memset(filepath, 0, sizeof(filepath)); + sprintf(filepath, "%s%s", FT5402_INI_FILEPATH, config_name); + if (NULL == pfile) + pfile = filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(pfile)) { + pr_err("error occured while opening file %s.\n", filepath); + return -EIO; + } + + inode = pfile->f_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, config_buf, fsize, &pos); + filp_close(pfile, NULL); + set_fs(old_fs); + + return 0; +} + +int ft5402_Get_Param_From_Ini(char *config_name) +{ + char key[64]; + char value[512]; + char section[64]; + int i = 0;//,ret=0; + int j = 0; + char *filedata = NULL; + unsigned char legal_byte1 = 0x00; + unsigned char legal_byte2 = 0x00; + + int inisize = ft5402_GetInISize(config_name); + + if (inisize <= 0) { + pr_err("%s ERROR:Get firmware size failed\n", + __func__); + return -EIO; + } + + filedata = kmalloc(inisize + 1, GFP_ATOMIC); + + if (ft5x0x_ReadInIData(config_name, filedata)) { + pr_err("%s() - ERROR: request_firmware failed\n", + __func__); + kfree(filedata); + return -EIO; + } + + /*check ini if it is illegal*/ + sprintf(section, "%s", FT5402_APP_LEGAL); + sprintf(key, "%s", FT5402_APP_LEGAL_BYTE_1_STR); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + legal_byte1 = atoi(value); + DBG("legal_byte1=%s\n", value); + sprintf(key, "%s", FT5402_APP_LEGAL_BYTE_2_STR); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + legal_byte2 = atoi(value); + DBG("lega2_byte1=%s\n", value); + if(FT5402_APP_LEGAL_BYTE_1_VALUE == legal_byte1 && + FT5402_APP_LEGAL_BYTE_2_VALUE == legal_byte2) + DBG("the ini file is valid\n"); + else { + pr_err("[FTS]-----the ini file is invalid!please check it.\n"); + goto ERROR_RETURN; + } + + /*get ini param*/ + sprintf(section, "%s", FT5402_APP_NAME); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_KX = atoi(value); + DBG("ft5402_KX=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_KY = atoi(value); + DBG("ft5402_KY=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_LEMDA_X = atoi(value); + DBG("ft5402_LEMDA_X=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_LEMDA_Y = atoi(value); + DBG("ft5402_LEMDA_Y=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_RESOLUTION_X = atoi(value); + DBG("ft5402_RESOLUTION_X=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_RESOLUTION_Y = atoi(value); + DBG("ft5402_RESOLUTION_Y=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_DIRECTION= atoi(value); + DBG("ft5402_DIRECTION=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FACE_DETECT_PRE_VALUE = atoi(value); + DBG("ft5402_FACE_DETECT_PRE_VALUE=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FACE_DETECT_NUM = atoi(value); + DBG("ft5402_FACE_DETECT_NUM=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_BIGAREA_PEAK_VALUE_MIN = atoi(value);/*The min value to be decided as the big point*/ + DBG("ft5402_BIGAREA_PEAK_VALUE_MIN=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_BIGAREA_DIFF_VALUE_OVER_NUM = atoi(value);/*The min big points of the big area*/ + DBG("ft5402_BIGAREA_DIFF_VALUE_OVER_NUM=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_CUSTOMER_ID = atoi(value); + DBG("ft5402_CUSTOM_ID=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_PERIOD_ACTIVE = atoi(value); + DBG("ft5402_PERIOD_ACTIVE=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FACE_DETECT_STATISTICS_TX_NUM = atoi(value); + DBG("ft5402_FACE_DETECT_STATISTICS_TX_NUM=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_THGROUP = atoi(value); + DBG("ft5402_THGROUP=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_THPEAK = atoi(value); + DBG("ft5402_THPEAK=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FACE_DETECT_MODE = atoi(value); + DBG("ft5402_FACE_DETECT_MODE=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MAX_TOUCH_VALUE = atoi(value); + DBG("ft5402_MAX_TOUCH_VALUE=%s\n", value); + + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_PWMODE_CTRL= atoi(value); + DBG("ft5402_PWMODE_CTRL=%s\n", value); + + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + + i++; + g_param_ft5402.ft5402_DRAW_LINE_TH = atoi(value); + DBG("ft5402_DRAW_LINE_TH=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_POINTS_SUPPORTED= atoi(value); + DBG("ft5402_POINTS_SUPPORTED=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_START_RX = atoi(value); + DBG("ft5402_START_RX=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + + g_param_ft5402.ft5402_ADC_TARGET = atoi(value); + DBG("ft5402_ADC_TARGET=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + + g_param_ft5402.ft5402_ESD_FILTER_FRAME = atoi(value); + DBG("ft5402_ESD_FILTER_FRAME=%s\n", value); + +/*********************************************************************/ + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_tx_num = atoi(value); + DBG("ft5402_tx_num=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_rx_num = atoi(value); + DBG("ft5402_rx_num=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_gain = atoi(value); + DBG("ft5402_gain=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_voltage = atoi(value); + DBG("ft5402_voltage=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_scanselect = atoi(value); + DBG("ft5402_scanselect=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + for(j = 0; j < g_ft5402_tx_num; j++) + { + char * psrc = value; + g_ft5402_tx_order[j] = atoi(ft5402_sub_str(psrc, j+1)); + } + DBG("ft5402_tx_order=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_ft5402_tx_offset = atoi(value); + DBG("ft5402_tx_offset=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + for(j = 0; j < g_ft5402_tx_num; j++) + { + char * psrc = value; + g_ft5402_tx_cap[j] = atoi(ft5402_sub_str(psrc, j+1)); + } + DBG("ft5402_tx_cap=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + for(j = 0; j < g_ft5402_rx_num; j++) + { + char * psrc = value; + g_ft5402_rx_order[j] = atoi(ft5402_sub_str(psrc, j+1)); + } + DBG("ft5402_rx_order=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + for(j = 0; j < g_ft5402_rx_num/2; j++) + { + char * psrc = value; + g_ft5402_rx_offset[j] = atoi(ft5402_sub_str(psrc, j+1)); + } + DBG("ft5402_rx_offset=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + for(j = 0; j < g_ft5402_rx_num; j++) + { + char * psrc = value; + g_ft5402_rx_cap[j] = atoi(ft5402_sub_str(psrc, j+1)); + } + DBG("ft5402_rx_cap=%s\n", value); + + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_POINTS_STABLE_MACRO = atoi(value); + DBG("ft5402_POINTS_STABLE_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MIN_DELTA_X = atoi(value); + DBG("ft5402_MIN_DELTA_X=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MIN_DELTA_Y = atoi(value); + DBG("ft5402_MIN_DELTA_Y=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MIN_DELTA_STEP = atoi(value); + DBG("ft5402_MIN_DELTA_STEP=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_ESD_NOISE_MACRO = atoi(value); + DBG("ft5402_ESD_NOISE_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_ESD_DIFF_VAL = atoi(value); + DBG("ft5402_ESD_DIFF_VAL=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_ESD_NEGTIVE = atoi(value); + DBG("ft5402_ESD_NEGTIVE=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_ESD_FILTER_FRAMES = atoi(value); + DBG("ft5402_ESD_FILTER_FRAMES=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_IO_LEVEL_SELECT = atoi(value); + DBG("ft5402_IO_LEVEL_SELECT=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_POINTID_DELAY_COUNT = atoi(value); + DBG("ft5402_POINTID_DELAY_COUNT=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_LIFTUP_FILTER_MACRO = atoi(value); + DBG("ft5402_LIFTUP_FILTER_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_DIFF_HANDLE_MACRO = atoi(value); + DBG("ft5402_DIFF_HANDLE_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MIN_WATER = atoi(value); + DBG("ft5402_MIN_WATER=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_MAX_NOISE = atoi(value); + DBG("ft5402_MAX_NOISE=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_WATER_START_RX = atoi(value); + DBG("ft5402_WATER_START_RX=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_WATER_START_TX = atoi(value); + DBG("ft5402_WATER_START_TX=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_HOST_NUMBER_SUPPORTED_MACRO = atoi(value); + DBG("ft5402_HOST_NUMBER_SUPPORTED_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_RAISE_THGROUP = atoi(value); + DBG("ft5402_RAISE_THGROUP=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_CHARGER_STATE = atoi(value); + DBG("ft5402_CHARGER_STATE=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FILTERID_START = atoi(value); + DBG("ft5402_FILTERID_START=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_EN_MACRO = atoi(value); + DBG("ft5402_FRAME_FILTER_EN_MACRO=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_SUB_MAX_TH = atoi(value); + DBG("ft5402_FRAME_FILTER_SUB_MAX_TH=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_ADD_MAX_TH = atoi(value); + DBG("ft5402_FRAME_FILTER_ADD_MAX_TH=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_SKIP_START_FRAME = atoi(value); + DBG("ft5402_FRAME_FILTER_SKIP_START_FRAME=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_BAND_EN = atoi(value); + DBG("ft5402_FRAME_FILTER_BAND_EN=%s\n", value); + + sprintf(key, "%s", String_Param_FT5402[i]); + if (ini_get_key(filedata,section,key,value)<0) + goto ERROR_RETURN; + i++; + g_param_ft5402.ft5402_FRAME_FILTER_BAND_WIDTH = atoi(value); + DBG("ft5402_FRAME_FILTER_BAND_WIDTH=%s\n", value); + + + if (filedata) + kfree(filedata); + return 0; +ERROR_RETURN: + if (filedata) + kfree(filedata); + return -1; +} + diff --git a/drivers/input/touchscreen/ft5x0x/ft5402_config.h b/drivers/input/touchscreen/ft5x0x/ft5402_config.h new file mode 100755 index 00000000..b0c63889 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5402_config.h @@ -0,0 +1,71 @@ +#ifndef __FT5402_CONFIG_H__ +#define __FT5402_CONFIG_H__ +/*FT5402 config*/ + + +#define FT5402_START_RX 0 +#define FT5402_ADC_TARGET 8500 +#define FT5402_KX 120 +#define FT5402_KY 120 +#define FT5402_RESOLUTION_X 480 +#define FT5402_RESOLUTION_Y 800 +#define FT5402_LEMDA_X 0 +#define FT5402_LEMDA_Y 0 +#define FT5402_PWMODE_CTRL 1 +#define FT5402_POINTS_SUPPORTED 5 +#define FT5402_DRAW_LINE_TH 150 +#define FT5402_FACE_DETECT_MODE 0 +#define FT5402_FACE_DETECT_STATISTICS_TX_NUM 3 +#define FT5402_FACE_DETECT_PRE_VALUE 20 +#define FT5402_FACE_DETECT_NUM 10 +#define FT5402_THGROUP 25 +#define FT5402_THPEAK 60 +#define FT5402_BIGAREA_PEAK_VALUE_MIN 100 +#define FT5402_BIGAREA_DIFF_VALUE_OVER_NUM 50 +#define FT5402_MIN_DELTA_X 2 +#define FT5402_MIN_DELTA_Y 2 +#define FT5402_MIN_DELTA_STEP 2 +#define FT5402_ESD_DIFF_VAL 20 +#define FT5402_ESD_NEGTIVE -50 +#define FT5402_ESD_FILTER_FRAME 10 +#define FT5402_MAX_TOUCH_VALUE 600 +#define FT5402_CUSTOMER_ID 121 +#define FT5402_IO_LEVEL_SELECT 0 +#define FT5402_DIRECTION 1 +#define FT5402_POINTID_DELAY_COUNT 3 +#define FT5402_LIFTUP_FILTER_MACRO 1 +#define FT5402_POINTS_STABLE_MACRO 1 +#define FT5402_ESD_NOISE_MACRO 1 +#define FT5402_RV_G_PERIOD_ACTIVE 16 +#define FT5402_DIFFDATA_HANDLE 1 +#define FT5402_MIN_WATER_VAL -50 +#define FT5402_MAX_NOISE_VAL 10 +#define FT5402_WATER_HANDLE_START_RX 0 +#define FT5402_WATER_HANDLE_START_TX 0 +#define FT5402_HOST_NUMBER_SUPPORTED 1 +#define FT5402_RV_G_RAISE_THGROUP 30 +#define FT5402_RV_G_CHARGER_STATE 0 +#define FT5402_RV_G_FILTERID_START 2 +#define FT5402_FRAME_FILTER_EN 1 +#define FT5402_FRAME_FILTER_SUB_MAX_TH 2 +#define FT5402_FRAME_FILTER_ADD_MAX_TH 2 +#define FT5402_FRAME_FILTER_SKIP_START_FRAME 6 +#define FT5402_FRAME_FILTER_BAND_EN 1 +#define FT5402_FRAME_FILTER_BAND_WIDTH 128 +#define FT5402_OTP_PARAM_ID 0 + + +unsigned char g_ft5402_tx_num = 27; +unsigned char g_ft5402_rx_num = 16; +unsigned char g_ft5402_gain = 10; +unsigned char g_ft5402_voltage = 3; +unsigned char g_ft5402_scanselect = 12; +unsigned char g_ft5402_tx_order[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; +unsigned char g_ft5402_tx_offset = 2; +unsigned char g_ft5402_tx_cap[] = {42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42}; +unsigned char g_ft5402_rx_order[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +unsigned char g_ft5402_rx_offset[] = {68,68,68,68,68,68,68,68}; +unsigned char g_ft5402_rx_cap[] = {84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84}; + + +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/ft5x0x/ft5402_ini_config.h b/drivers/input/touchscreen/ft5x0x/ft5402_ini_config.h new file mode 100755 index 00000000..138f42e2 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5402_ini_config.h @@ -0,0 +1,411 @@ +#ifndef __LINUX_FT5402_INI_CONFIG_H__ +#define __LINUX_FT5402_INI_CONFIG_H + + +/*Init param register address*/ +/*factory mode register from 14-131*/ +#define FT5402_REG_TX_NUM 0x03 +#define FT5402_REG_RX_NUM 0x04 +#define FT5402_REG_VOLTAGE 0x05 +#define FT5402_REG_GAIN 0x07 +#define FT5402_REG_SCAN_SELECT 0x4E +#define FT5402_REG_TX_ORDER_START 0x50 +#define FT5402_REG_TX_CAP_START 0x78 +#define FT5402_REG_TX_OFFSET_START 0xBF +#define FT5402_REG_RX_ORDER_START 0xeb +#define FT5402_REG_RX_CAP_START 0xA0 +#define FT5402_REG_RX_OFFSET_START 0xD3 +#define FT5402_REG_START_RX 0x06 +#define FT5402_REG_ADC_TARGET_HIGH 0x08 +#define FT5402_REG_ADC_TARGET_LOW 0x09 + + +#define FT5402_REG_DEVICE_MODE 0x00 + + +/*work mode register from 0-13(0,1,12,13verify or Reserved)and 132-177(159 Reserved)*/ +#define FT5402_REG_THGROUP (0x00+0x80) +#define FT5402_REG_THPEAK (0x01+0x80) +#define FT5402_REG_PWMODE_CTRL (0x06+0x80) +#define FT5402_REG_PERIOD_ACTIVE (0x59+0x80) +#define FT5402_REG_POINTS_SUPPORTED (0x0A+0x80) +#define FT5402_REG_ESD_FILTER_FRAME (0x4F+0x80) + +#define FT5402_REG_RESOLUTION_X_H (0x18+0x80) +#define FT5402_REG_RESOLUTION_X_L (0x19+0x80) +#define FT5402_REG_RESOLUTION_Y_H (0x1a+0x80) +#define FT5402_REG_RESOLUTION_Y_L (0x1b+0x80) +#define FT5402_REG_KX_H (0x1c+0x80) +#define FT5402_REG_KX_L (0x9d) +#define FT5402_REG_KY_H (0x9e) +#define FT5402_REG_KY_L (0x1f+0x80) +#define FT5402_REG_CUSTOMER_ID (0xA8) +#define FT5402_REG_DRAW_LINE_TH (0xAe) +#define FT5402_REG_FACE_DETECT_MODE (0xB0) +#define FT5402_REG_MAX_TOUCH_VALUE_HIGH (0xD0) +#define FT5402_REG_MAX_TOUCH_VALUE_LOW (0xD1) + +#define FT5402_REG_DIRECTION (0x53+0x80) +#define FT5402_REG_LEMDA_X (0x41+0x80) +#define FT5402_REG_LEMDA_Y (0x42+0x80) +#define FT5402_REG_FACE_DETECT_STATISTICS_TX_NUM (0x43+0x80) +#define FT5402_REG_FACE_DETECT_PRE_VALUE (0x44+0x80) +#define FT5402_REG_FACE_DETECT_NUM (0x45+0x80) +#define FT5402_REG_BIGAREA_PEAK_VALUE_MIN (0x33+0x80) +#define FT5402_REG_BIGAREA_DIFF_VALUE_OVER_NUM (0x34+0x80) + +/**************************************************************************/ +#define FT5402_REG_FT5402_POINTS_STABLE_MACRO (0x57+0x80) +#define FT5402_REG_FT5402_MIN_DELTA_X (0x4a+0x80) +#define FT5402_REG_FT5402_MIN_DELTA_Y (0x4b+0x80) +#define FT5402_REG_FT5402_MIN_DELTA_STEP (0x4c+0x80) + +#define FT5402_REG_FT5402_ESD_NOISE_MACRO (0x58+0x80) +#define FT5402_REG_FT5402_ESD_DIFF_VAL (0x4d+0x80) +#define FT5402_REG_FT5402_ESD_NEGTIVE (0xCe) +#define FT5402_REG_FT5402_ESD_FILTER_FRAMES (0x4f+0x80) + +#define FT5402_REG_FT5402_IO_LEVEL_SELECT (0x52+0x80) + +#define FT5402_REG_FT5402_POINTID_DELAY_COUNT (0x54+0x80) + +#define FT5402_REG_FT5402_LIFTUP_FILTER_MACRO (0x55+0x80) + +#define FT5402_REG_FT5402_DIFF_HANDLE_MACRO (0x5A+0x80) +#define FT5402_REG_FT5402_MIN_WATER (0x5B+0x80) +#define FT5402_REG_FT5402_MAX_NOISE (0x5C+0x80) +#define FT5402_REG_FT5402_WATER_START_RX (0x5D+0x80) +#define FT5402_REG_FT5402_WATER_START_TX (0xDE) + +#define FT5402_REG_FT5402_HOST_NUMBER_SUPPORTED_MACRO (0x38+0x80) +#define FT5402_REG_FT5402_RAISE_THGROUP (0x36+0x80) +#define FT5402_REG_FT5402_CHARGER_STATE (0x35+0x80) + +#define FT5402_REG_FT5402_FILTERID_START (0x37+0x80) + +#define FT5402_REG_FT5402_FRAME_FILTER_EN_MACRO (0x5F+0x80) +#define FT5402_REG_FT5402_FRAME_FILTER_SUB_MAX_TH (0x60+0x80) +#define FT5402_REG_FT5402_FRAME_FILTER_ADD_MAX_TH (0x61+0x80) +#define FT5402_REG_FT5402_FRAME_FILTER_SKIP_START_FRAME (0x62+0x80) +#define FT5402_REG_FT5402_FRAME_FILTER_BAND_EN (0x63+0x80) +#define FT5402_REG_FT5402_FRAME_FILTER_BAND_WIDTH (0x64+0x80) +/**************************************************************************/ + +#define FT5402_REG_TEST_MODE 0x04 +#define FT5402_REG_TEST_MODE_2 0x05 +#define FT5402_TX_TEST_MODE_1 0x28 +#define FT5402_RX_TEST_MODE_1 0x1E +#define FT5402_FACTORYMODE_VALUE 0x40 +#define FT5402_WORKMODE_VALUE 0x00 + +/************************************************************************/ +/* string */ +/************************************************************************/ +#define STRING_FT5402_KX "FT5X02_KX" +#define STRING_FT5402_KY "FT5X02_KY" +#define STRING_FT5402_LEMDA_X "FT5X02_LEMDA_X" +#define STRING_FT5402_LEMDA_Y "FT5X02_LEMDA_Y" +#define STRING_FT5402_RESOLUTION_X "FT5X02_RESOLUTION_X" +#define STRING_FT5402_RESOLUTION_Y "FT5X02_RESOLUTION_Y" +#define STRING_FT5402_DIRECTION "FT5X02_DIRECTION" + + + +#define STRING_FT5402_FACE_DETECT_PRE_VALUE "FT5X02_FACE_DETECT_PRE_VALUE" +#define STRING_FT5402_FACE_DETECT_NUM "FT5X02_FACE_DETECT_NUM" +#define STRING_FT5402_BIGAREA_PEAK_VALUE_MIN "FT5X02_BIGAREA_PEAK_VALUE_MIN" +#define STRING_FT5402_BIGAREA_DIFF_VALUE_OVER_NUM "FT5X02_BIGAREA_DIFF_VALUE_OVER_NUM" +#define STRING_FT5402_CUSTOMER_ID "FT5X02_CUSTOMER_ID" +#define STRING_FT5402_PERIOD_ACTIVE "FT5X02_RV_G_PERIOD_ACTIVE" +#define STRING_FT5402_FACE_DETECT_STATISTICS_TX_NUM "FT5X02_FACE_DETECT_STATISTICS_TX_NUM" + +#define STRING_FT5402_THGROUP "FT5X02_THGROUP" +#define STRING_FT5402_THPEAK "FT5X02_THPEAK" +#define STRING_FT5402_FACE_DETECT_MODE "FT5X02_FACE_DETECT_MODE" +#define STRING_FT5402_MAX_TOUCH_VALUE "FT5X02_MAX_TOUCH_VALUE" + +#define STRING_FT5402_PWMODE_CTRL "FT5X02_PWMODE_CTRL" +#define STRING_FT5402_DRAW_LINE_TH "FT5X02_DRAW_LINE_TH" + +#define STRING_FT5402_POINTS_SUPPORTED "FT5X02_POINTS_SUPPORTED" + +#define STRING_FT5402_START_RX "FT5X02_START_RX" +#define STRING_FT5402_ADC_TARGET "FT5X02_ADC_TARGET" +#define STRING_FT5402_ESD_FILTER_FRAME "FT5X02_ESD_FILTER_FRAME" + +#define STRING_FT5402_POINTS_STABLE_MACRO "FT5X02_POINTS_STABLE_MACRO" +#define STRING_FT5402_MIN_DELTA_X "FT5X02_MIN_DELTA_X" +#define STRING_FT5402_MIN_DELTA_Y "FT5X02_MIN_DELTA_Y" +#define STRING_FT5402_MIN_DELTA_STEP "FT5X02_MIN_DELTA_STEP" + +#define STRING_FT5402_ESD_NOISE_MACRO "FT5X02_ESD_NOISE_MACRO" +#define STRING_FT5402_ESD_DIFF_VAL "FT5X02_ESD_DIFF_VAL" +#define STRING_FT5402_ESD_NEGTIVE "FT5X02_ESD_NEGTIVE" +#define STRING_FT5402_ESD_FILTER_FRAME "FT5X02_ESD_FILTER_FRAME" + +#define STRING_FT5402_IO_LEVEL_SELECT "FT5X02_IO_LEVEL_SELECT" +#define STRING_FT5402_POINTID_DELAY_COUNT "FT5X02_POINTID_DELAY_COUNT" + +#define STRING_FT5402_LIFTUP_FILTER_MACRO "FT5X02_LIFTUP_FILTER_MACRO" + +#define STRING_FT5402_DIFFDATA_HANDLE "FT5X02_DIFFDATA_HANDLE" //_MACRO +#define STRING_FT5402_MIN_WATER_VAL "FT5X02_MIN_WATER_VAL" +#define STRING_FT5402_MAX_NOISE_VAL "FT5X02_MAX_NOISE_VAL" +#define STRING_FT5402_WATER_HANDLE_START_RX "FT5X02_WATER_HANDLE_START_RX" +#define STRING_FT5402_WATER_HANDLE_START_TX "FT5X02_WATER_HANDLE_START_TX" + +#define STRING_FT5402_HOST_NUMBER_SUPPORTED "FT5X02_HOST_NUMBER_SUPPORTED" +#define STRING_FT5402_RV_G_RAISE_THGROUP "FT5X02_RV_G_RAISE_THGROUP" +#define STRING_FT5402_RV_G_CHARGER_STATE "FT5X02_RV_G_CHARGER_STATE" + +#define STRING_FT5402_RV_G_FILTERID_START "FT5X02_RV_G_FILTERID_START" + +#define STRING_FT5402_FRAME_FILTER_EN "FT5X02_FRAME_FILTER_EN" +#define STRING_FT5402_FRAME_FILTER_SUB_MAX_TH "FT5X02_FRAME_FILTER_SUB_MAX_TH" +#define STRING_FT5402_FRAME_FILTER_ADD_MAX_TH "FT5X02_FRAME_FILTER_ADD_MAX_TH" +#define STRING_FT5402_FRAME_FILTER_SKIP_START_FRAME "FT5X02_FRAME_FILTER_SKIP_START_FRAME" +#define STRING_FT5402_FRAME_FILTER_BAND_EN "FT5X02_FRAME_FILTER_BAND_EN" +#define STRING_FT5402_FRAME_FILTER_BAND_WIDTH "FT5X02_FRAME_FILTER_BAND_WIDTH" + + +#define STRING_ft5402_tx_num "FT5X02_tx_num" +#define STRING_ft5402_rx_num "FT5X02_rx_num" +#define STRING_ft5402_gain "FT5X02_gain" +#define STRING_ft5402_voltage "FT5X02_voltage" +#define STRING_ft5402_scanselect "FT5X02_scanselect" + +#define STRING_ft5402_tx_order "FT5X02_tx_order" +#define STRING_ft5402_tx_offset "FT5X02_tx_offset" +#define STRING_ft5402_tx_cap "FT5X02_tx_cap" + +#define STRING_ft5402_rx_order "FT5X02_rx_order" +#define STRING_ft5402_rx_offset "FT5X02_rx_offset" +#define STRING_ft5402_rx_cap "FT5X02_rx_cap" + +struct Struct_Param_FT5402 { + short ft5402_KX; + short ft5402_KY; + unsigned char ft5402_LEMDA_X; + unsigned char ft5402_LEMDA_Y; + short ft5402_RESOLUTION_X; + short ft5402_RESOLUTION_Y; + unsigned char ft5402_DIRECTION; + unsigned char ft5402_FACE_DETECT_PRE_VALUE; + unsigned char ft5402_FACE_DETECT_NUM; + + unsigned char ft5402_BIGAREA_PEAK_VALUE_MIN; + unsigned char ft5402_BIGAREA_DIFF_VALUE_OVER_NUM; + unsigned char ft5402_CUSTOMER_ID; + unsigned char ft5402_PERIOD_ACTIVE; + unsigned char ft5402_FACE_DETECT_STATISTICS_TX_NUM; + + short ft5402_THGROUP; + unsigned char ft5402_THPEAK; + unsigned char ft5402_FACE_DETECT_MODE; + short ft5402_MAX_TOUCH_VALUE; + + unsigned char ft5402_PWMODE_CTRL; + unsigned char ft5402_DRAW_LINE_TH; + unsigned char ft5402_POINTS_SUPPORTED; + + unsigned char ft5402_START_RX; + short ft5402_ADC_TARGET; + unsigned char ft5402_ESD_FILTER_FRAME; + + unsigned char ft5402_POINTS_STABLE_MACRO; + unsigned char ft5402_MIN_DELTA_X; + unsigned char ft5402_MIN_DELTA_Y; + unsigned char ft5402_MIN_DELTA_STEP; + + unsigned char ft5402_ESD_NOISE_MACRO; + unsigned char ft5402_ESD_DIFF_VAL; + char ft5402_ESD_NEGTIVE; //negtive + unsigned char ft5402_ESD_FILTER_FRAMES; + + unsigned char ft5402_IO_LEVEL_SELECT; + + unsigned char ft5402_POINTID_DELAY_COUNT; + + unsigned char ft5402_LIFTUP_FILTER_MACRO; + + unsigned char ft5402_DIFF_HANDLE_MACRO; + char ft5402_MIN_WATER; //negtive + unsigned char ft5402_MAX_NOISE; + unsigned char ft5402_WATER_START_RX; + unsigned char ft5402_WATER_START_TX; + + unsigned char ft5402_HOST_NUMBER_SUPPORTED_MACRO; + unsigned char ft5402_RAISE_THGROUP; + unsigned char ft5402_CHARGER_STATE; + + unsigned char ft5402_FILTERID_START; + + unsigned char ft5402_FRAME_FILTER_EN_MACRO; + unsigned char ft5402_FRAME_FILTER_SUB_MAX_TH; + unsigned char ft5402_FRAME_FILTER_ADD_MAX_TH; + unsigned char ft5402_FRAME_FILTER_SKIP_START_FRAME; + unsigned char ft5402_FRAME_FILTER_BAND_EN; + unsigned char ft5402_FRAME_FILTER_BAND_WIDTH; + +}; + +struct Struct_Param_FT5402 g_param_ft5402 = { + FT5402_KX, + FT5402_KY, + FT5402_LEMDA_X, + FT5402_LEMDA_Y, + FT5402_RESOLUTION_X, + FT5402_RESOLUTION_Y, + FT5402_DIRECTION, + + FT5402_FACE_DETECT_PRE_VALUE, + FT5402_FACE_DETECT_NUM, + FT5402_BIGAREA_PEAK_VALUE_MIN, + FT5402_BIGAREA_DIFF_VALUE_OVER_NUM, + FT5402_CUSTOMER_ID, + FT5402_RV_G_PERIOD_ACTIVE, + FT5402_FACE_DETECT_STATISTICS_TX_NUM, + + FT5402_THGROUP, + FT5402_THPEAK, + FT5402_FACE_DETECT_MODE, + FT5402_MAX_TOUCH_VALUE, + + FT5402_PWMODE_CTRL, + FT5402_DRAW_LINE_TH, + FT5402_POINTS_SUPPORTED, + + FT5402_START_RX, + FT5402_ADC_TARGET, + FT5402_ESD_FILTER_FRAME, + + FT5402_POINTS_STABLE_MACRO, + FT5402_MIN_DELTA_X, + FT5402_MIN_DELTA_Y, + FT5402_MIN_DELTA_STEP, + + FT5402_ESD_NOISE_MACRO, + FT5402_ESD_DIFF_VAL, + FT5402_ESD_NEGTIVE, + FT5402_ESD_FILTER_FRAME, + + FT5402_IO_LEVEL_SELECT, + + FT5402_POINTID_DELAY_COUNT, + + FT5402_LIFTUP_FILTER_MACRO, + + FT5402_DIFFDATA_HANDLE, + FT5402_MIN_WATER_VAL, + FT5402_MAX_NOISE_VAL, + FT5402_WATER_HANDLE_START_RX, + FT5402_WATER_HANDLE_START_TX, + + FT5402_HOST_NUMBER_SUPPORTED, + FT5402_RV_G_RAISE_THGROUP, + FT5402_RV_G_CHARGER_STATE, + + FT5402_RV_G_FILTERID_START, + + FT5402_FRAME_FILTER_EN, + FT5402_FRAME_FILTER_SUB_MAX_TH, + FT5402_FRAME_FILTER_ADD_MAX_TH, + FT5402_FRAME_FILTER_SKIP_START_FRAME, + FT5402_FRAME_FILTER_BAND_EN, + FT5402_FRAME_FILTER_BAND_WIDTH, +}; + +char String_Param_FT5402[][64] = { + STRING_FT5402_KX, + STRING_FT5402_KY, + STRING_FT5402_LEMDA_X, + STRING_FT5402_LEMDA_Y, + STRING_FT5402_RESOLUTION_X, + STRING_FT5402_RESOLUTION_Y, + STRING_FT5402_DIRECTION, + STRING_FT5402_FACE_DETECT_PRE_VALUE, + STRING_FT5402_FACE_DETECT_NUM, + STRING_FT5402_BIGAREA_PEAK_VALUE_MIN, + STRING_FT5402_BIGAREA_DIFF_VALUE_OVER_NUM, + STRING_FT5402_CUSTOMER_ID, + STRING_FT5402_PERIOD_ACTIVE, + STRING_FT5402_FACE_DETECT_STATISTICS_TX_NUM, + + STRING_FT5402_THGROUP, + STRING_FT5402_THPEAK, + STRING_FT5402_FACE_DETECT_MODE, + STRING_FT5402_MAX_TOUCH_VALUE, + + STRING_FT5402_PWMODE_CTRL, + STRING_FT5402_DRAW_LINE_TH, + STRING_FT5402_POINTS_SUPPORTED, + + STRING_FT5402_START_RX, + STRING_FT5402_ADC_TARGET, + STRING_FT5402_ESD_FILTER_FRAME, + + + STRING_ft5402_tx_num, + STRING_ft5402_rx_num, + STRING_ft5402_gain, + STRING_ft5402_voltage , + STRING_ft5402_scanselect, + + STRING_ft5402_tx_order, + STRING_ft5402_tx_offset, + STRING_ft5402_tx_cap, + + STRING_ft5402_rx_order, + STRING_ft5402_rx_offset, + STRING_ft5402_rx_cap, + + STRING_FT5402_POINTS_STABLE_MACRO, + STRING_FT5402_MIN_DELTA_X, + STRING_FT5402_MIN_DELTA_Y, + STRING_FT5402_MIN_DELTA_STEP, + + STRING_FT5402_ESD_NOISE_MACRO, + STRING_FT5402_ESD_DIFF_VAL, + STRING_FT5402_ESD_NEGTIVE, + STRING_FT5402_ESD_FILTER_FRAME, + + STRING_FT5402_IO_LEVEL_SELECT, + + STRING_FT5402_POINTID_DELAY_COUNT, + + STRING_FT5402_LIFTUP_FILTER_MACRO, + + STRING_FT5402_DIFFDATA_HANDLE, + STRING_FT5402_MIN_WATER_VAL, + STRING_FT5402_MAX_NOISE_VAL, + STRING_FT5402_WATER_HANDLE_START_RX, + STRING_FT5402_WATER_HANDLE_START_TX, + + STRING_FT5402_HOST_NUMBER_SUPPORTED, + STRING_FT5402_RV_G_RAISE_THGROUP, + STRING_FT5402_RV_G_CHARGER_STATE, + + STRING_FT5402_RV_G_FILTERID_START, + + STRING_FT5402_FRAME_FILTER_EN, + STRING_FT5402_FRAME_FILTER_SUB_MAX_TH, + STRING_FT5402_FRAME_FILTER_ADD_MAX_TH, + STRING_FT5402_FRAME_FILTER_SKIP_START_FRAME, + STRING_FT5402_FRAME_FILTER_BAND_EN, + STRING_FT5402_FRAME_FILTER_BAND_WIDTH, + +}; + +#define FT5402_APP_NAME "FT5X02_param" + +#define FT5402_APP_LEGAL "Legal_File" +#define FT5402_APP_LEGAL_BYTE_1_STR "BYTE_1" +#define FT5402_APP_LEGAL_BYTE_2_STR "BYTE_2" + +#define FT5402_APP_LEGAL_BYTE_1_VALUE 107 +#define FT5402_APP_LEGAL_BYTE_2_VALUE 201 + + +#define FT5402_INI_FILEPATH "/system/etc/firmware/" + +#endif diff --git a/drivers/input/touchscreen/ft5x0x/ft5x0x.c b/drivers/input/touchscreen/ft5x0x/ft5x0x.c new file mode 100755 index 00000000..9bb63b83 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5x0x.c @@ -0,0 +1,937 @@ +/* + * drivers/input/touchscreen/ft5x0x/ft5x0x.c + * + * FocalTech ft5x0x TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * note: only support mulititouch Wenfs 2010-10-01 + */ +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ft5x0x.h" +#include "../../../video/backlight/wmt_bl.h" + +struct ft5x0x_data *pContext=NULL; +static struct i2c_client *l_client=NULL; + +#ifdef TOUCH_KEY +static int keycodes[NUM_KEYS] ={ + KEY_MENU, + KEY_HOME, + KEY_BACK, + KEY_SEARCH +}; +#endif + +#define FT5402_CONFIG_NAME "fttpconfig_5402public.ini" +extern int ft5x0x_read_fw_ver(void); +extern int ft5x0x_auto_clb(void); +extern int ft5x0x_upg_fw_bin(struct ft5x0x_data *ft5x0x, int check_ver); +extern int ft5402_Get_Param_From_Ini(char *config_name); +extern int ft5402_Init_IC_Param(struct i2c_client *client); +extern int ft5402_get_ic_param(struct i2c_client *client); +extern int ft5402_read_reg(struct i2c_client * client, u8 regaddr, u8 * regvalue); + +extern int register_bl_notifier(struct notifier_block *nb); + +extern int unregister_bl_notifier(struct notifier_block *nb); + + +int ft5x0x_i2c_rxdata(char *rxdata, int length) +{ + int ret; + struct i2c_msg msg[2]; + + msg[0].addr = pContext->addr; + msg[0].flags = 0 | I2C_M_NOSTART; + msg[0].len = 1; + msg[0].buf = rxdata; + + msg[1].addr = pContext->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = length; + msg[1].buf = rxdata; + + ret = i2c_transfer(pContext->client->adapter, msg, 2); + if (ret <= 0) + dbg_err("msg i2c read error: %d\n", ret); + + return ret; +} + + +int ft5x0x_i2c_txdata(char *txdata, int length) +{ + int ret; + struct i2c_msg msg[1]; + + msg[0].addr = pContext->addr; + msg[0].flags = 0; + msg[0].len = length; + msg[0].buf = txdata; + + ret = i2c_transfer(pContext->client->adapter, msg, 1); + if (ret <= 0) + dbg_err("msg i2c read error: %d\n", ret); + + return ret; +} + +static void ft5x0x_penup(struct ft5x0x_data *ft5x0x) +{ + input_mt_sync(ft5x0x->input_dev); + input_sync(ft5x0x->input_dev); +#ifdef TOUCH_KEY + if(ft5x0x->tskey_used && ft5x0x->tkey_pressed && ft5x0x->tkey_idx < NUM_KEYS ){ + input_report_key(ft5x0x->input_dev, keycodes[ft5x0x->tkey_idx], 1); + input_sync(ft5x0x->input_dev); + input_report_key(ft5x0x->input_dev, keycodes[ft5x0x->tkey_idx], 0); + input_sync(ft5x0x->input_dev); + dbg("report as key event %d \n",ft5x0x->tkey_idx); + } +#endif + + dbg("pen up\n"); + return; +} + +#ifdef TOUCH_KEY +static int ft5x0x_read_tskey(struct ft5x0x_data *ft5x0x,int x,int y) +{ + int px,py; + + if(ft5x0x->tkey.axis){ + px = y; + py = x; + }else{ + px = x; + py = y; + } + + if(px >= ft5x0x->tkey.x_lower && px<=ft5x0x->tkey.x_upper){ + ft5x0x->tkey_pressed = 1; + if(py>= ft5x0x->tkey.ypos[0].y_lower && py<= ft5x0x->tkey.ypos[0].y_upper){ + ft5x0x->tkey_idx= 0; + }else if(py>= ft5x0x->tkey.ypos[1].y_lower && py<= ft5x0x->tkey.ypos[1].y_upper){ + ft5x0x->tkey_idx = 1; + }else if(py>= ft5x0x->tkey.ypos[2].y_lower && py<= ft5x0x->tkey.ypos[2].y_upper){ + ft5x0x->tkey_idx = 2; + }else if(py>= ft5x0x->tkey.ypos[3].y_lower && py<= ft5x0x->tkey.ypos[3].y_upper){ + ft5x0x->tkey_idx = 3; + }else{ + ft5x0x->tkey_idx = NUM_KEYS; + } + + return 1; + } + + ft5x0x->tkey_pressed = 0; + return 0; +} +#endif + +static int ft5x0x_read_data(struct ft5x0x_data *ft5x0x) +{ + int ret = -1; + int i = 0; + u16 x,y,px,py; + u8 buf[64] = {0}, id; + struct ts_event *event = &ft5x0x->event; + + if(ft5x0x->nt == 10) + ret = ft5x0x_i2c_rxdata(buf, 64); + else if(ft5x0x->nt == 5) + ret = ft5x0x_i2c_rxdata(buf, 31); + + if (ret <= 0) { + dbg_err("read_data i2c_rxdata failed: %d\n", ret); + return ret; + } + + memset(event, 0, sizeof(struct ts_event)); + //event->tpoint = buf[2] & 0x03;// 0000 0011 + //event->tpoint = buf[2] & 0x07;// 000 0111 + event->tpoint = buf[2]&0x0F; + if (event->tpoint == 0) { + ft5x0x_penup(ft5x0x); + return 1; + } + + if (event->tpoint > ft5x0x->nt){ + dbg_err("tounch pointnum=%d > max:%d\n", event->tpoint,ft5x0x->nt); + return -1; + } + + for (i = 0; i < event->tpoint; i++){ + id = (buf[5+i*6] >>4) & 0x0F;//get track id + if(ft5x0x->swap){ + px = (buf[3+i*6] & 0x0F)<<8 |buf[4+i*6]; + py = (buf[5+i*6] & 0x0F)<<8 |buf[6+i*6]; + }else{ + px = (buf[5+i*6] & 0x0F)<<8 |buf[6+i*6]; + py = (buf[3+i*6] & 0x0F)<<8 |buf[4+i*6]; + } + + x = px; + y = py; + + if(ft5x0x->xch) + x = ft5x0x->reslx - px; + + if(ft5x0x->ych) + y = ft5x0x->resly - py; + + if(ft5x0x->dbg) printk("F%d: Tid=%d,px=%d,py=%d; x=%d,y=%d\n", i, id, px, py, x, y); + +#ifdef TOUCH_KEY + if(ft5x0x->tskey_used && event->tpoint==1) { + if(ft5x0x_read_tskey(ft5x0x,px,py) > 0) return -1; + } +#endif + if (ft5x0x->lcd_exchg) { + int tmp; + tmp = x; + x = y; + y = ft5x0x->reslx - tmp; + } + event->x[i] = x; + event->y[i] = y; + event->tid[i] = id; + + } + + return 0; +} + +static void ft5x0x_report(struct ft5x0x_data *ft5x0x) +{ + int i = 0; + struct ts_event *event = &ft5x0x->event; + + for (i = 0; i < event->tpoint; i++){ + input_report_abs(ft5x0x->input_dev, ABS_MT_TRACKING_ID, event->tid[i]); + input_report_abs(ft5x0x->input_dev, ABS_MT_POSITION_X, event->x[i]); + input_report_abs(ft5x0x->input_dev, ABS_MT_POSITION_Y, event->y[i]); + input_mt_sync(ft5x0x->input_dev); + } + input_sync(ft5x0x->input_dev); + + return; +} + +static void ft5x0x_read_work(struct work_struct *work) +{ + int ret = -1; + struct ft5x0x_data *ft5x0x = container_of(work, struct ft5x0x_data, read_work); + + mutex_lock(&ft5x0x->ts_mutex); + ret = ft5x0x_read_data(ft5x0x); + + if (ret == 0) ft5x0x_report(ft5x0x); + + wmt_gpio_unmask_irq(ft5x0x->irqgpio); + mutex_unlock(&ft5x0x->ts_mutex); + + return; +} + +static irqreturn_t ft5x0x_interrupt(int irq, void *dev) +{ + struct ft5x0x_data *ft5x0x = dev; + + if (gpio_irqstatus(ft5x0x->irqgpio)) + { + wmt_gpio_ack_irq(ft5x0x->irqgpio); + if (is_gpio_irqenable(ft5x0x->irqgpio)) + { + wmt_gpio_mask_irq(ft5x0x->irqgpio); +#ifdef CONFIG_HAS_EARLYSUSPEND + if(!ft5x0x->earlysus) queue_work(ft5x0x->workqueue, &ft5x0x->read_work); +#else + queue_work(ft5x0x->workqueue, &ft5x0x->read_work); +#endif + + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static void ft5x0x_reset(struct ft5x0x_data *ft5x0x) +{ + gpio_set_value(ft5x0x->rstgpio, 1); + mdelay(5); + gpio_set_value(ft5x0x->rstgpio, 0); + mdelay(20); + gpio_set_value(ft5x0x->rstgpio, 1); + mdelay(5); + + return; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void ft5x0x_early_suspend(struct early_suspend *handler) +{ + struct ft5x0x_data *ft5x0x = container_of(handler, struct ft5x0x_data, early_suspend); + ft5x0x->earlysus = 1; + wmt_gpio_mask_irq(ft5x0x->irqgpio); + return; +} + +static void ft5x0x_late_resume(struct early_suspend *handler) +{ + struct ft5x0x_data *ft5x0x = container_of(handler, struct ft5x0x_data, early_suspend); + + ft5x0x_reset(ft5x0x); + ft5x0x->earlysus = 0; + + wmt_gpio_set_irq_type(ft5x0x->irqgpio, IRQ_TYPE_EDGE_FALLING); + wmt_gpio_unmask_irq(ft5x0x->irqgpio); + + return; +} +#endif //CONFIG_HAS_EARLYSUSPEND + +#ifdef CONFIG_PM +static int ft5x0x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ft5x0x_data *ft5x0x = dev_get_drvdata(&pdev->dev); + ft5x0x->earlysus = 1; + wmt_gpio_mask_irq(ft5x0x->irqgpio); + return 0; +} + +static int ft5x0x_resume(struct platform_device *pdev) +{ + struct ft5x0x_data *ft5x0x = dev_get_drvdata(&pdev->dev); + ft5x0x_reset(ft5x0x); + ft5x0x->earlysus = 0; + + if (ft5x0x->load_cfg) { + msleep(350); + ft5402_Init_IC_Param(ft5x0x->client); + //msleep(50); + ft5402_get_ic_param(ft5x0x->client); + } + wmt_gpio_set_irq_type(ft5x0x->irqgpio, IRQ_TYPE_EDGE_FALLING); + wmt_gpio_unmask_irq(ft5x0x->irqgpio); + return 0; +} + +#else +#define ft5x0x_suspend NULL +#define ft5x0x_resume NULL +#endif + +static ssize_t cat_dbg(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "dbg \n"); +} + +static ssize_t echo_dbg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int dbg = simple_strtoul(buf, NULL, 10); + struct ft5x0x_data *ft5x0x = pContext; + + if(dbg){ + ft5x0x->dbg = 1; + }else{ + ft5x0x->dbg = 0; + } + + return count; +} +static DEVICE_ATTR(dbg, S_IRUGO | S_IWUSR, cat_dbg, echo_dbg); + +static ssize_t cat_clb(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "calibrate \n"); +} + +static ssize_t echo_clb(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int cal = simple_strtoul(buf, NULL, 10); + + if(cal){ + if(ft5x0x_auto_clb()) printk("Calibrate Failed.\n"); + }else{ + printk("calibrate --echo 1 >clb.\n"); + } + + return count; +} + +static DEVICE_ATTR(clb, S_IRUGO | S_IWUSR, cat_clb, echo_clb); + +static ssize_t cat_fupg(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "fupg \n"); +} + +static ssize_t echo_fupg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct ft5x0x_data *ft5x0x = pContext; + unsigned int upg = simple_strtoul(buf, NULL, 10); + + wmt_gpio_mask_irq(ft5x0x->irqgpio); + if(upg){ + if(ft5x0x_upg_fw_bin(ft5x0x, 0)) printk("Upgrade Failed.\n"); + }else{ + printk("upgrade --echo 1 > fupg.\n"); + } + wmt_gpio_unmask_irq(ft5x0x->irqgpio); + + return count; +} +static DEVICE_ATTR(fupg, S_IRUGO | S_IWUSR, cat_fupg, echo_fupg); + + +static ssize_t cat_fver(struct device *dev, struct device_attribute *attr, char *buf) +{ + int fw_ver = ft5x0x_read_fw_ver(); + return sprintf(buf, "firmware version:0x%02x \n",fw_ver); +} + +static ssize_t echo_fver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + return count; +} +static DEVICE_ATTR(fver, S_IRUGO | S_IWUSR, cat_fver, echo_fver); + +static ssize_t cat_addr(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret; + u8 addrs[32]; + int cnt=0; + struct i2c_msg msg[2]; + struct ft5x0x_data *ft5x0x = pContext; + u8 ver[1]= {0xa6}; + + ft5x0x->addr = 1; + + msg[0].addr = ft5x0x->addr; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = ver; + + msg[1].addr = ft5x0x->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = 1; + msg[1].buf = ver; + + while(ft5x0x->addr < 0x80){ + ret = i2c_transfer(ft5x0x->client->adapter, msg, 2); + if(ret == 2) sprintf(&addrs[5*cnt++], " 0x%02x",ft5x0x->addr); + + ft5x0x->addr++; + msg[0].addr = msg[1].addr = ft5x0x->addr; + } + + return sprintf(buf, "i2c addr:%s\n",addrs); +} + +static ssize_t echo_addr(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int addr; + struct ft5x0x_data *ft5x0x = pContext; + + sscanf(buf,"%x", &addr); + ft5x0x->addr = addr; + + return count; +} +static DEVICE_ATTR(addr, S_IRUGO | S_IWUSR, cat_addr, echo_addr); + +static struct attribute *ft5x0x_attributes[] = { + &dev_attr_clb.attr, + &dev_attr_fupg.attr, + &dev_attr_fver.attr, + &dev_attr_dbg.attr, + &dev_attr_addr.attr, + NULL +}; + +static const struct attribute_group ft5x0x_group = { + .attrs = ft5x0x_attributes, +}; + +static int ft5x0x_sysfs_create_group(struct ft5x0x_data *ft5x0x, const struct attribute_group *group) +{ + int err; + + ft5x0x->kobj = kobject_create_and_add("wmtts", NULL) ; + if(!ft5x0x->kobj){ + dbg_err("kobj create failed.\n"); + return -ENOMEM; + } + + /* Register sysfs hooks */ + err = sysfs_create_group(ft5x0x->kobj, group); + if (err < 0){ + kobject_del(ft5x0x->kobj); + dbg_err("Create sysfs group failed!\n"); + return -ENOMEM; + } + + return 0; +} + +static void ft5x0x_sysfs_remove_group(struct ft5x0x_data *ft5x0x, const struct attribute_group *group) +{ + sysfs_remove_group(ft5x0x->kobj, group); + kobject_del(ft5x0x->kobj); + return; +} + +static int bl_notify_irqgpio = -1; +static int wmt_wakeup_bl_notify(struct notifier_block *nb, unsigned long event, + void *dummy) +{ + switch (event) { + case BL_CLOSE: + errlog("ft5x0x: BL_CLOSE, disable irq\n"); + wmt_gpio_mask_irq(bl_notify_irqgpio); + break; + case BL_OPEN: + errlog("ft5x0x: BL_OPEN, enable irq\n"); + wmt_gpio_unmask_irq(bl_notify_irqgpio); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block wmt_bl_notify = { + .notifier_call = wmt_wakeup_bl_notify, +}; + +static int ft5x0x_probe(struct platform_device *pdev) +{ + int i,err = 0; + u8 value = 0; + u8 cfg_name[32]; + struct ft5x0x_data *ft5x0x = platform_get_drvdata( pdev); + + ft5x0x->client = l_client; + INIT_WORK(&ft5x0x->read_work, ft5x0x_read_work); + mutex_init(&ft5x0x->ts_mutex); + + ft5x0x->workqueue = create_singlethread_workqueue(ft5x0x->name); + if (!ft5x0x->workqueue) { + err = -ESRCH; + goto exit_create_singlethread; + } + + err = ft5x0x_sysfs_create_group(ft5x0x, &ft5x0x_group); + if(err < 0){ + dbg("create sysfs group failed.\n"); + goto exit_create_group; + } + + ft5x0x->input_dev = input_allocate_device(); + if (!ft5x0x->input_dev) { + err = -ENOMEM; + dbg("failed to allocate input device\n"); + goto exit_input_dev_alloc_failed; + } + + ft5x0x->input_dev->name = ft5x0x->name; + ft5x0x->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + set_bit(INPUT_PROP_DIRECT, ft5x0x->input_dev->propbit); + + if (ft5x0x->lcd_exchg) { + input_set_abs_params(ft5x0x->input_dev, + ABS_MT_POSITION_X, 0, ft5x0x->resly, 0, 0); + input_set_abs_params(ft5x0x->input_dev, + ABS_MT_POSITION_Y, 0, ft5x0x->reslx, 0, 0); + } else { + input_set_abs_params(ft5x0x->input_dev, + ABS_MT_POSITION_X, 0, ft5x0x->reslx, 0, 0); + input_set_abs_params(ft5x0x->input_dev, + ABS_MT_POSITION_Y, 0, ft5x0x->resly, 0, 0); + } + input_set_abs_params(ft5x0x->input_dev, + ABS_MT_TRACKING_ID, 0, 20, 0, 0); +#ifdef TOUCH_KEY + if(ft5x0x->tskey_used){ + for (i = 0; i input_dev->keybit); + + ft5x0x->input_dev->keycode = keycodes; + ft5x0x->input_dev->keycodesize = sizeof(unsigned int); + ft5x0x->input_dev->keycodemax = NUM_KEYS; + } +#endif + + err = input_register_device(ft5x0x->input_dev); + if (err) { + dbg_err("ft5x0x_ts_probe: failed to register input device.\n"); + goto exit_input_register_device_failed; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + ft5x0x->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ft5x0x->early_suspend.suspend = ft5x0x_early_suspend; + ft5x0x->early_suspend.resume = ft5x0x_late_resume; + register_early_suspend(&ft5x0x->early_suspend); +#endif + + if(ft5x0x->upg){ + if(ft5x0x_upg_fw_bin(ft5x0x, 1)) printk("Upgrade Failed.\n"); + else wmt_setsyspara("wmt.io.ts.upg",""); + ft5x0x->upg = 0x00; + } + + if(request_irq(ft5x0x->irq, ft5x0x_interrupt, IRQF_SHARED, ft5x0x->name, ft5x0x) < 0){ + dbg_err("Could not allocate irq for ts_ft5x0x !\n"); + err = -1; + goto exit_register_irq; + } + + { // check if need to load config to IC or not + err = ft5402_read_reg(ft5x0x->client, 0xa3, &value); + if (err < 0) + dbg_err("Read reg 0xa3 failed.\n"); + else + printk("0xa3 reg = %d\n", value); + if (value == 3) + ft5x0x->load_cfg = 1; + else + ft5x0x->load_cfg = 0; + } + ft5x0x_reset(ft5x0x); + + if (ft5x0x->load_cfg) { + msleep(350); /*make sure CTP already finish startup process*/ + sprintf(cfg_name, "%s.ini", ft5x0x->cfg_name); + printk("Config file name: %s\n", cfg_name); + if (ft5402_Get_Param_From_Ini(cfg_name) >= 0) + ft5402_Init_IC_Param(ft5x0x->client); + else + dbg_err("[FTS]-------Get ft5402 param from INI file failed\n"); + ft5402_get_ic_param(ft5x0x->client); + } + + wmt_gpio_set_irq_type(ft5x0x->irqgpio, IRQ_TYPE_EDGE_FALLING); + wmt_gpio_unmask_irq(ft5x0x->irqgpio); + + if(bl_notify_irqgpio < 0){ + register_bl_notifier(&wmt_bl_notify); + bl_notify_irqgpio = ft5x0x->irqgpio; + } + + return 0; + +exit_register_irq: +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ft5x0x->early_suspend); +#endif +exit_input_register_device_failed: + input_free_device(ft5x0x->input_dev); +exit_input_dev_alloc_failed: + ft5x0x_sysfs_remove_group(ft5x0x, &ft5x0x_group); +exit_create_group: + cancel_work_sync(&ft5x0x->read_work); + destroy_workqueue(ft5x0x->workqueue); +exit_create_singlethread: + return err; +} + +static int ft5x0x_remove(struct platform_device *pdev) +{ + struct ft5x0x_data *ft5x0x = platform_get_drvdata( pdev); + + if( bl_notify_irqgpio > 0){ + unregister_bl_notifier(&wmt_bl_notify); + bl_notify_irqgpio = -1; + } + cancel_work_sync(&ft5x0x->read_work); + flush_workqueue(ft5x0x->workqueue); + destroy_workqueue(ft5x0x->workqueue); + + free_irq(ft5x0x->irq, ft5x0x); + wmt_gpio_mask_irq(ft5x0x->irqgpio); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ft5x0x->early_suspend); +#endif + input_unregister_device(ft5x0x->input_dev); + + ft5x0x_sysfs_remove_group(ft5x0x, &ft5x0x_group); + + mutex_destroy(&ft5x0x->ts_mutex); + dbg("remove...\n"); + return 0; +} + +static void ft5x0x_release(struct device *device) +{ + return; +} + +static struct platform_device ft5x0x_device = { + .name = DEV_FT5X0X, + .id = 0, + .dev = {.release = ft5x0x_release}, +}; + +static struct platform_driver ft5x0x_driver = { + .driver = { + .name = DEV_FT5X0X, + .owner = THIS_MODULE, + }, + .probe = ft5x0x_probe, + .remove = ft5x0x_remove, + .suspend = ft5x0x_suspend, + .resume = ft5x0x_resume, +}; + +static int check_touch_env(struct ft5x0x_data *ft5x0x) +{ + int i,ret = 0; + int len = 96; + int Enable; + char retval[96] = {0}; + char *p=NULL; + char *s=NULL; + + // Get u-boot parameter + ret = wmt_getsyspara("wmt.io.touch", retval, &len); + if(ret){ + //printk("MST FT5x0x:Read wmt.io.touch Failed.\n"); + return -EIO; + } + sscanf(retval,"%d:",&Enable); + //check touch enable + if(Enable == 0){ + //printk("FT5x0x Touch Screen Is Disabled.\n"); + return -ENODEV; + } + + p = strchr(retval,':'); + p++; + if(strncmp(p,"ft5301",6)==0){//check touch ID + ft5x0x->id = FT5301; + ft5x0x->name = DEV_FT5301; + }else if(strncmp(p,"ft5406",6)==0){ + ft5x0x->id = FT5406; + ft5x0x->name = DEV_FT5406; + }else if(strncmp(p,"ft5206",6)==0){ + ft5x0x->id = FT5206; + ft5x0x->name = DEV_FT5206; + }else if(strncmp(p,"ft5606",6)==0){ + ft5x0x->id = FT5606; + ft5x0x->name = DEV_FT5606; + }else if(strncmp(p,"ft5306",6)==0){ + ft5x0x->id = FT5306; + ft5x0x->name = DEV_FT5306; + }else if(strncmp(p,"ft5302",6)==0){ + ft5x0x->id = FT5302; + ft5x0x->name = DEV_FT5302; + }else if(strncmp(p,"ft5",3)==0) + { + ft5x0x->id = FT5X0X; + ft5x0x->name = DEV_FT5X0X; + }else{ + printk("FT5x0x touch disabled.\n"); + return -ENODEV; + } + + s = strchr(p,':'); + strncpy(ft5x0x->cfg_name, p, s-p); + + p = s + 1; + sscanf(p,"%d:%d:%d:%d:%d:%d:%d:%d:%x", &ft5x0x->irqgpio, &ft5x0x->reslx, &ft5x0x->resly, &ft5x0x->rstgpio, &ft5x0x->swap, &ft5x0x->xch, &ft5x0x->ych, &ft5x0x->nt, &ft5x0x->addr); + + ft5x0x->irq = IRQ_GPIO; + printk("%s irqgpio=%d, reslx=%d, resly=%d, rstgpio=%d, swap=%d, xch=%d, ych=%d, nt=%d, addr=%x\n", ft5x0x->name, ft5x0x->irqgpio, ft5x0x->reslx, ft5x0x->resly, ft5x0x->rstgpio, ft5x0x->swap, ft5x0x->xch, ft5x0x->ych, ft5x0x->nt, ft5x0x->addr); + + memset(retval,0x00,sizeof(retval)); + ret = wmt_getsyspara("wmt.io.ts.upg", retval, &len); + if(!ret){ + ft5x0x->upg = 1; + strncpy(ft5x0x->fw_name, retval, sizeof(ft5x0x->fw_name)); + } + +#ifdef TOUCH_KEY + memset(retval,0x00,sizeof(retval)); + ret = wmt_getsyspara("wmt.io.tskey", retval, &len); + if(!ret){ + sscanf(retval,"%d:", &ft5x0x->nkeys); + p = strchr(retval,':'); + p++; + for(i=0; i < ft5x0x->nkeys; i++ ){ + sscanf(p,"%d:%d", &ft5x0x->tkey.ypos[i].y_lower, &ft5x0x->tkey.ypos[i].y_upper); + p = strchr(p,':'); + p++; + p = strchr(p,':'); + p++; + } + sscanf(p,"%d:%d:%d", &ft5x0x->tkey.axis, &ft5x0x->tkey.x_lower, &ft5x0x->tkey.x_upper); + ft5x0x->tskey_used = 1; + } +#endif + + memset(retval,0x00,sizeof(retval)); + ret = wmt_getsyspara("wmt.display.fb0", retval, &len); + if (!ret) { + int tmp[6]; + p = retval; + sscanf(p, "%d:[%d:%d:%d:%d:%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + if (tmp[4] > tmp[5]) + ft5x0x->lcd_exchg = 1; + } + + return 0; +} + +struct i2c_board_info ts_i2c_board_info = { + .type = TS_I2C_NAME, + .flags = 0x00, + .addr = FT5406_I2C_ADDR, + .platform_data = NULL, + .archdata = NULL, + .irq = -1, +}; + +static int ts_i2c_register_device (void) +{ + struct i2c_board_info *ts_i2c_bi; + struct i2c_adapter *adapter = NULL; + //struct i2c_client *client = NULL; + + //ts_i2c_board_info.addr = FT5406_I2C_ADDR; + ts_i2c_bi = &ts_i2c_board_info; + adapter = i2c_get_adapter(FT5X0X_I2C_BUS);/*in bus 1*/ + + if (NULL == adapter) { + printk("can not get i2c adapter, client address error\n"); + return -1; + } + l_client = i2c_new_device(adapter, ts_i2c_bi); + if (l_client == NULL) { + printk("allocate i2c client failed\n"); + return -1; + } + i2c_put_adapter(adapter); + return 0; +} + +static void ts_i2c_unregister_device(void) +{ + if (l_client != NULL) + { + i2c_unregister_device(l_client); + l_client = NULL; + } +} + +static int __init ft5x0x_init(void) +{ + int ret = -ENOMEM; + struct ft5x0x_data *ft5x0x=NULL; + + if (ts_i2c_register_device()<0) + { + dbg("Error to run ts_i2c_register_device()!\n"); + return -1; + } + + ft5x0x = kzalloc(sizeof(struct ft5x0x_data), GFP_KERNEL); + if(!ft5x0x){ + dbg_err("mem alloc failed.\n"); + return -ENOMEM; + } + + pContext = ft5x0x; + ret = check_touch_env(ft5x0x); + if(ret < 0) + goto exit_free_mem; + + ret = gpio_request(ft5x0x->irqgpio, "ts_irq"); + if (ret < 0) { + printk("gpio(%d) touchscreen irq request fail\n", ft5x0x->irqgpio); + goto exit_free_mem; + } + wmt_gpio_setpull(ft5x0x->irqgpio, WMT_GPIO_PULL_UP); + gpio_direction_input(ft5x0x->irqgpio); + + ret = gpio_request(ft5x0x->rstgpio, "ts_rst"); + if (ret < 0) { + printk("gpio(%d) touchscreen reset request fail\n", ft5x0x->rstgpio); + goto exit_free_irqgpio; + } + gpio_direction_output(ft5x0x->rstgpio, 1); + + + ret = platform_device_register(&ft5x0x_device); + if(ret){ + dbg_err("register platform drivver failed!\n"); + goto exit_free_gpio; + } + platform_set_drvdata(&ft5x0x_device, ft5x0x); + + ret = platform_driver_register(&ft5x0x_driver); + if(ret){ + dbg_err("register platform device failed!\n"); + goto exit_unregister_pdev; + } + + return ret; + +exit_unregister_pdev: + platform_device_unregister(&ft5x0x_device); +exit_free_gpio: + gpio_free(ft5x0x->rstgpio); +exit_free_irqgpio: + gpio_free(ft5x0x->irqgpio); +exit_free_mem: + kfree(ft5x0x); + pContext = NULL; + return ret; +} + +static void ft5x0x_exit(void) +{ + if(!pContext) return; + + gpio_free(pContext->rstgpio); + gpio_free(pContext->irqgpio); + platform_driver_unregister(&ft5x0x_driver); + platform_device_unregister(&ft5x0x_device); + kfree(pContext); + ts_i2c_unregister_device(); + return; +} + +late_initcall(ft5x0x_init); +module_exit(ft5x0x_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("FocalTech.Touch"); diff --git a/drivers/input/touchscreen/ft5x0x/ft5x0x.h b/drivers/input/touchscreen/ft5x0x/ft5x0x.h new file mode 100755 index 00000000..03836b49 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5x0x.h @@ -0,0 +1,207 @@ +#ifndef __LINUX_FT5X0X_TS_H__ +#define __LINUX_FT5X0X_TS_H__ + +#define DEV_FT5206 "touch_ft5206" +#define DEV_FT5301 "touch_ft5301" +#define DEV_FT5302 "touch_ft5302" +#define DEV_FT5306 "touch_ft5306" +#define DEV_FT5406 "touch_ft5406" +#define DEV_FT5606 "touch_ft5606" + +#define DEV_FT5X0X "touch_ft5x0x" +#define TS_I2C_NAME "ft5x0x-ts" +#define FT5406_I2C_ADDR 0x38 +#define FT5X0X_I2C_BUS 0x01 + +enum FT5X0X_ID{ + FT5206 =1, + FT5301, + FT5302, + FT5306, + FT5406, + FT5606, + FT5X0X, +}; + +struct vt1603_ts_cal_info { + int a1; + int b1; + int c1; + int a2; + int b2; + int c2; + int delta; +}; + +#define SUPPORT_POINT_NUM 10 +struct ts_event { + int x[SUPPORT_POINT_NUM]; + int y[SUPPORT_POINT_NUM]; + int tid[SUPPORT_POINT_NUM]; + int tpoint; +}; + +#define TOUCH_KEY + +#ifdef TOUCH_KEY +#define NUM_KEYS 4 +struct key_pos{ + int y_lower; + int y_upper; +}; + +struct ts_key{ + int axis; + int x_lower; + int x_upper; + struct key_pos ypos[NUM_KEYS]; +}; +#endif + +struct ft5x0x_data { + int id; + unsigned int addr; + const char *name; + u8 fw_name[64]; + u8 cfg_name[32]; + + struct i2c_client *client; + struct input_dev *input_dev; + struct ts_event event; + struct work_struct read_work; + struct workqueue_struct *workqueue; + struct mutex ts_mutex; + struct kobject *kobj; + #ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + int earlysus; + + int reslx; + int resly; + + int tw; + int th; + + int irq; + int irqgpio; + int rstgpio; +/* + int igp_idx; + int igp_bit; + + int rgp_idx; + int rgp_bit; +*/ + + int nt; + int nb; + int xch; + int ych; + int swap; + int lcd_exchg; + + int upg; + int load_cfg; + int dbg; +#ifdef TOUCH_KEY + int tskey_used; + int tkey_pressed; + int nkeys; + int tkey_idx; + struct ts_key tkey; +#endif + +}; + +enum ft5x0x_ts_regs { + FT5X0X_REG_THGROUP = 0x80, /* touch threshold, related to sensitivity */ + FT5X0X_REG_THPEAK = 0x81, + FT5X0X_REG_THCAL = 0x82, + FT5X0X_REG_THWATER = 0x83, + FT5X0X_REG_THTEMP = 0x84, + FT5X0X_REG_THDIFF = 0x85, + FT5X0X_REG_CTRL = 0x86, + FT5X0X_REG_TIMEENTERMONITOR = 0x87, + FT5X0X_REG_PERIODACTIVE = 0x88, /* report rate */ + FT5X0X_REG_PERIODMONITOR = 0x89, + FT5X0X_REG_HEIGHT_B = 0x8a, + FT5X0X_REG_MAX_FRAME = 0x8b, + FT5X0X_REG_DIST_MOVE = 0x8c, + FT5X0X_REG_DIST_POINT = 0x8d, + FT5X0X_REG_FEG_FRAME = 0x8e, + FT5X0X_REG_SINGLE_CLICK_OFFSET = 0x8f, + FT5X0X_REG_DOUBLE_CLICK_TIME_MIN = 0x90, + FT5X0X_REG_SINGLE_CLICK_TIME = 0x91, + FT5X0X_REG_LEFT_RIGHT_OFFSET = 0x92, + FT5X0X_REG_UP_DOWN_OFFSET = 0x93, + FT5X0X_REG_DISTANCE_LEFT_RIGHT = 0x94, + FT5X0X_REG_DISTANCE_UP_DOWN = 0x95, + FT5X0X_REG_ZOOM_DIS_SQR = 0x96, + FT5X0X_REG_RADIAN_VALUE =0x97, + FT5X0X_REG_MAX_X_HIGH = 0x98, + FT5X0X_REG_MAX_X_LOW = 0x99, + FT5X0X_REG_MAX_Y_HIGH = 0x9a, + FT5X0X_REG_MAX_Y_LOW = 0x9b, + FT5X0X_REG_K_X_HIGH = 0x9c, + FT5X0X_REG_K_X_LOW = 0x9d, + FT5X0X_REG_K_Y_HIGH = 0x9e, + FT5X0X_REG_K_Y_LOW = 0x9f, + FT5X0X_REG_AUTO_CLB_MODE = 0xa0, + FT5X0X_REG_LIB_VERSION_H = 0xa1, + FT5X0X_REG_LIB_VERSION_L = 0xa2, + FT5X0X_REG_CIPHER = 0xa3, + FT5X0X_REG_MODE = 0xa4, + FT5X0X_REG_PMODE = 0xa5, /* Power Consume Mode */ + FT5X0X_REG_FIRMID = 0xa6, /* Firmware version */ + FT5X0X_REG_STATE = 0xa7, + FT5X0X_REG_FT5201ID = 0xa8, + FT5X0X_REG_ERR = 0xa9, + FT5X0X_REG_CLB = 0xaa, +}; + +//FT5X0X_REG_PMODE +#define PMODE_ACTIVE 0x00 +#define PMODE_MONITOR 0x01 +#define PMODE_STANDBY 0x02 +#define PMODE_HIBERNATE 0x03 + +#define DEV_NAME "wmtts" +#define DEV_MAJOR 11 + +#define TS_IOC_MAGIC 't' +#define TS_IOCTL_CAL_START _IO(TS_IOC_MAGIC, 1) +#define TS_IOCTL_CAL_DONE _IOW(TS_IOC_MAGIC, 2, int*) +#define TS_IOCTL_GET_RAWDATA _IOR(TS_IOC_MAGIC, 3, int*) +#define TS_IOCTL_CAL_QUIT _IOW(TS_IOC_MAGIC, 4, int*) +#define TS_IOCTL_CAL_CAP _IOW(TS_IOC_MAGIC, 5, int*) +#define TS_IOC_MAXNR 5 + +extern int wmt_setsyspara(char *varname, unsigned char *varval); +extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); +extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num,int bus_id); + +//#define FT_DEBUG + +#undef dbg +#ifdef FT_DEBUG + #define dbg(fmt,args...) printk("DBG:%s_%d:"fmt,__FUNCTION__,__LINE__,##args) +#else + #define dbg(fmt,args...) +#endif + +#undef dbg_err +#define dbg_err(fmt,args...) printk("ERR:%s_%d:"fmt,__FUNCTION__,__LINE__,##args) + +//#define FTS_DBG +#ifdef FTS_DBG +#define DBG(fmt, args...) printk("[FTS]" fmt, ## args) +#else +#define DBG(fmt, args...) do{}while(0) +#endif + +#ifndef errlog +#define errlog(fmt, args...) printk(KERN_ERR "[%s:%d]: " fmt, __FUNCTION__,__LINE__, ## args) +#endif + +#endif diff --git a/drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c b/drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c new file mode 100755 index 00000000..9db72130 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c @@ -0,0 +1,506 @@ +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include +#include +#include +#include +#include +#include "ft5x0x.h" + +typedef enum +{ + ERR_OK, + ERR_MODE, + ERR_READID, + ERR_ERASE, + ERR_STATUS, + ERR_ECC, + ERR_DL_ERASE_FAIL, + ERR_DL_PROGRAM_FAIL, + ERR_DL_VERIFY_FAIL, + ERR_FMID +}E_UPGRADE_ERR_TYPE; + +#define FT5X_CTPM_ID_L 0X79 +#define FT5X_CTPM_ID_H 0X03 + +#define FT56_CTPM_ID_L 0X79 +#define FT56_CTPM_ID_H 0X06 + +#define FTS_PACKET_LENGTH 128 + +extern struct ft5x0x_data *pContext; +extern int ft5x0x_i2c_rxdata(char *rxdata, int length); +extern int ft5x0x_i2c_txdata(char *txdata, int length); + +static int ft5x0x_write_reg(u8 addr, u8 para) +{ + u8 buf[2]; + int ret = -1; + + buf[0] = addr; + buf[1] = para; + ret = ft5x0x_i2c_txdata(buf, 2); + if (ret <= 0) { + printk("write reg failed! %x ret: %d", buf[0], ret); + return -1; + } + + return 0; +} + +static int ft5x0x_read_reg(u8 addr, u8 *pdata) +{ + int ret; + u8 buf[2]; + struct i2c_msg msgs[2]; + + // + buf[0] = addr; //register address + + msgs[0].addr = pContext->addr; + msgs[0].flags = 0 | I2C_M_NOSTART; + msgs[0].len = 1; + msgs[0].buf = buf; + + msgs[1].addr = pContext->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = 1; + msgs[1].buf = pdata; + + //ret = wmt_i2c_xfer_continue_if_4(msgs, 2, FT5X0X_I2C_BUS); + ret = i2c_transfer(pContext->client->adapter, msgs, 2); + if (ret <= 0) + printk("msg %s i2c read error: %d\n", __func__, ret); + + return ret; + +} + + +/* +[function]: + send a command to ctpm. +[parameters]: + btcmd[in] :command code; + btPara1[in] :parameter 1; + btPara2[in] :parameter 2; + btPara3[in] :parameter 3; + num[in] :the valid input parameter numbers, if only command code needed and no parameters followed,then the num is 1; +[return]: + FTS_TRUE :success; + FTS_FALSE :io fail; +*/ +static u8 cmd_write(u8 *cmd,u8 num) +{ + return ft5x0x_i2c_txdata(cmd, num); +} + +/* +[function]: + write data to ctpm , the destination address is 0. +[parameters]: + pbt_buf[in] :point to data buffer; + bt_len[in] :the data numbers; +[return]: + FTS_TRUE :success; + FTS_FALSE :io fail; +*/ +static u8 byte_write(u8* pbt_buf, int dw_len) +{ + + return ft5x0x_i2c_txdata( pbt_buf, dw_len); +} + +/* +[function]: + read out data from ctpm,the destination address is 0. +[parameters]: + pbt_buf[out] :point to data buffer; + bt_len[in] :the data numbers; +[return]: + FTS_TRUE :success; + FTS_FALSE :io fail; +*/ +static u8 byte_read(u8* pbt_buf, u8 bt_len) +{ + int ret; + struct i2c_msg msg[1]; + + msg[0].addr = pContext->addr; + msg[0].flags = I2C_M_RD; + msg[0].len = bt_len; + msg[0].buf = pbt_buf; + + ret = i2c_transfer(pContext->client->adapter, msg, 1); + //ret = wmt_i2c_xfer_continue_if_4(msg, 1, FT5X0X_I2C_BUS); + if (ret <= 0) + printk("msg i2c read error: %d\n", ret); + + return ret; +} + + +/* +[function]: + burn the FW to ctpm. +[parameters]:(ref. SPEC) + pbt_buf[in] :point to Head+FW ; + dw_lenth[in]:the length of the FW + 6(the Head length); + bt_ecc[in] :the ECC of the FW +[return]: + ERR_OK :no error; + ERR_MODE :fail to switch to UPDATE mode; + ERR_READID :read id fail; + ERR_ERASE :erase chip fail; + ERR_STATUS :status error; + ERR_ECC :ecc error. +*/ +static E_UPGRADE_ERR_TYPE ft5x0x_fw_upgrade(struct ft5x0x_data *ft5x0x, u8* pbt_buf, int dw_lenth) +{ + int i = 0,j = 0,i_ret; + int packet_number; + int temp,lenght; + u8 packet_buf[FTS_PACKET_LENGTH + 6]; + u8 auc_i2c_write_buf[10]; + u8 reg_val[2] = {0}; + u8 ctpm_id[2] = {0}; + u8 cmd[4]; + u8 bt_ecc; + + /*********Step 1:Reset CTPM *****/ + /*write 0xaa to register 0xfc*/ + ft5x0x_write_reg(0xfc,0xaa); + msleep(50); + /*write 0x55 to register 0xfc*/ + ft5x0x_write_reg(0xfc,0x55); + printk("[FTS] Step 1: Reset CTPM.\n"); + msleep(30); + + /*********Step 2:Enter upgrade mode *****/ + auc_i2c_write_buf[0] = 0x55; + auc_i2c_write_buf[1] = 0xaa; + do{ + i ++; + i_ret = byte_write(auc_i2c_write_buf, 2); + mdelay(5); + }while(i_ret <= 0 && i < 5 ); + msleep(20); + + /*********Step 3:check READ-ID**********/ + if(ft5x0x->id == FT5606){ + ctpm_id[0] = FT56_CTPM_ID_L; + ctpm_id[1] = FT56_CTPM_ID_H; + }else{ + ctpm_id[0] = FT5X_CTPM_ID_L; + ctpm_id[1] = FT5X_CTPM_ID_H; + } + + cmd[0] = 0x90; + cmd[1] = 0x00; + cmd[2] = 0x00; + cmd[3] = 0x00; + cmd_write(cmd,4); + byte_read(reg_val,2); + if (reg_val[0] == ctpm_id[0] && reg_val[1] == ctpm_id[1]){ + printk("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + }else{ + printk("[FTS] ID_ERROR: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + return ERR_READID; + } + + cmd[0] = 0xcd; + cmd_write(cmd,1); + byte_read(reg_val,1); + printk("[FTS] bootloader version = 0x%x\n", reg_val[0]); + + /******Step 4:erase app and panel paramenter area *********/ + cmd[0] = 0x61; + cmd_write(cmd,1); //erase app area + msleep(1500); + cmd[0] = 0x63; + cmd_write(cmd,1); //erase panel parameter area + msleep(100); + printk("[FTS] Step 4: erase. \n"); + + /*********Step 5:write firmware(FW) to ctpm flash*********/ + bt_ecc = 0; + printk("[FTS] Step 5: start upgrade. \n"); + dw_lenth = dw_lenth - 8; + packet_number = (dw_lenth) / FTS_PACKET_LENGTH; + packet_buf[0] = 0xbf; + packet_buf[1] = 0x00; + for (j=0;j>8); + packet_buf[3] = (u8)temp; + lenght = FTS_PACKET_LENGTH; + packet_buf[4] = (u8)(lenght>>8); + packet_buf[5] = (u8)lenght; + + for (i=0;i 0){ + temp = packet_number * FTS_PACKET_LENGTH; + packet_buf[2] = (u8)(temp>>8); + packet_buf[3] = (u8)temp; + + temp = (dw_lenth) % FTS_PACKET_LENGTH; + packet_buf[4] = (u8)(temp>>8); + packet_buf[5] = (u8)temp; + + for (i=0;i>8); + packet_buf[3] = (u8)temp; + temp =1; + packet_buf[4] = (u8)(temp>>8); + packet_buf[5] = (u8)temp; + packet_buf[6] = pbt_buf[ dw_lenth + i]; + bt_ecc ^= packet_buf[6]; + + byte_write(&packet_buf[0],7); + mdelay(20); + } + + /*********Step 6: read out checksum********************/ + /*send the opration head*/ + cmd[0] = 0xcc; + cmd_write(cmd,1); + byte_read(reg_val,1); + printk("[FTS] Step 6:read ECC 0x%x, firmware ECC 0x%x. \n", reg_val[0], bt_ecc); + if(reg_val[0] != bt_ecc){ + return ERR_ECC; + } + + /*********Step 7: reset the new FW***********************/ + cmd[0] = 0x07; + cmd_write(cmd,1); + + msleep(300); //make sure CTP startup normally + + return ERR_OK; +} + +int ft5x0x_auto_clb(void) +{ + u8 uc_temp; + u8 i ; + + printk("[FTS] start auto CLB.\n"); + msleep(200); + ft5x0x_write_reg(0, 0x40); + msleep(100); //make sure already enter factory mode + ft5x0x_write_reg(2, 0x4); //write command to start calibration + msleep(300); + for(i=0;i<100;i++){ + ft5x0x_read_reg(0,&uc_temp); + if ( ((uc_temp&0x70)>>4) == 0x0){ //return to normal mode, calibration finish + break; + } + msleep(200); + printk("[FTS] waiting calibration %d\n",i); + } + printk("[FTS] calibration OK.\n"); + + msleep(300); + ft5x0x_write_reg(0, 0x40); //goto factory mode + msleep(100); //make sure already enter factory mode + ft5x0x_write_reg(2, 0x5); //store CLB result + msleep(300); + ft5x0x_write_reg(0, 0x0); //return to normal mode + msleep(300); + printk("[FTS] store CLB result OK.\n"); + return 0; +} + +static int ft5x0x_get_bin_ver(const u8 *fw, int fw_szie) +{ + if (fw_szie > 2){ + return fw[fw_szie - 2]; + }else{ + return 0xff; //default value + } + return 0xff; +} + +int ft5x0x_read_fw_ver(void) +{ + u8 ver=0; + int ret=0; + + ret = ft5x0x_read_reg(FT5X0X_REG_FIRMID, &ver); + if(ret > 0) + return ver; + + return ret; +} + + +static int ft5x0x_get_fw_szie(const char *fw_name) +{ + struct file *pfile = NULL; + struct inode *inode; + unsigned long magic; + off_t fsize = 0; + + if(fw_name == NULL){ + dbg_err("Firmware name error.\n"); + return -EFAULT; + } + + if (NULL == pfile) + pfile = filp_open(fw_name, O_RDONLY, 0); + + if (IS_ERR(pfile)) { + dbg_err("File open error: %s.\n", fw_name); + return -EIO; + } + + inode = pfile->f_dentry->d_inode; + magic = inode->i_sb->s_magic; + fsize = inode->i_size; + filp_close(pfile, NULL); + return fsize; +} + +static int ft5x0x_read_fw(const char *fw_name, u8 *buf) +{ + struct file *pfile = NULL; + struct inode *inode; + unsigned long magic; + off_t fsize; + loff_t pos; + mm_segment_t fs; + + if(fw_name == NULL){ + dbg_err("Firmware name error.\n"); + return -EFAULT; + } + + if (NULL == pfile) + pfile = filp_open(fw_name, O_RDONLY, 0); + if (IS_ERR(pfile)) { + dbg_err("File open error: %s.\n", fw_name); + return -EIO; + } + + inode = pfile->f_dentry->d_inode; + magic = inode->i_sb->s_magic; + fsize = inode->i_size; + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + vfs_read(pfile, buf, fsize, &pos); + filp_close(pfile, NULL); + set_fs(fs); + + return 0; +} + +#define FW_SUFFFIX ".bin" +#define SD_UPG_BIN_PATH "/sdcard/_wmt_ft5x0x_fw_app.bin" +#define FS_UPG_BIN_PATH "/lib/firmware/" + +int ft5x0x_upg_fw_bin(struct ft5x0x_data *ft5x0x, int check_ver) +{ + int i_ret = 0; + int fwsize = 0; + int hw_fw_ver; + int bin_fw_ver; + int do_upg; + u8 *pbt_buf = NULL; + u8 fw_path[128] = {0}; + + if(ft5x0x->upg) + sprintf(fw_path,"%s%s%s", FS_UPG_BIN_PATH, ft5x0x->fw_name,FW_SUFFFIX);//get fw binary file from filesystem + else + strcpy(fw_path,SD_UPG_BIN_PATH); //get fw binary file from SD card + + fwsize = ft5x0x_get_fw_szie(fw_path); + if (fwsize <= 0) { + dbg_err("Get firmware size failed\n"); + return -EIO; + } + + if (fwsize < 8 || fwsize > 32 * 1024) { + dbg_err("FW length error\n"); + return -EIO; + } + + pbt_buf = kmalloc(fwsize + 1, GFP_KERNEL); + if (ft5x0x_read_fw(fw_path, pbt_buf)) { + dbg_err("Request_firmware failed\n"); + i_ret = -EIO; + goto exit; + } + + hw_fw_ver =ft5x0x_read_fw_ver(); + if(hw_fw_ver <= 0){ + dbg_err("Read firmware version failed\n"); + i_ret = hw_fw_ver; + goto exit; + } + + bin_fw_ver = ft5x0x_get_bin_ver(pbt_buf, fwsize); + printk("[FTS] hardware fw ver 0x%0x, binary ver 0x%0x\n",hw_fw_ver, bin_fw_ver); + + if(check_ver){ + if(hw_fw_ver == 0xa6 || hw_fw_ver < bin_fw_ver) + do_upg = 1; + else + do_upg = 0; + }else{ + do_upg = 1; + } + + if(do_upg){ + if ((pbt_buf[fwsize - 8] ^ pbt_buf[fwsize - 6]) == 0xFF && + (pbt_buf[fwsize - 7] ^ pbt_buf[fwsize - 5]) == 0xFF && + (pbt_buf[fwsize - 3] ^ pbt_buf[fwsize - 4]) == 0xFF) { + i_ret = ft5x0x_fw_upgrade(ft5x0x, pbt_buf, fwsize); + if (i_ret) + dbg_err("Upgrade failed, i_ret=%d\n",i_ret); + else { + hw_fw_ver = ft5x0x_read_fw_ver(); + printk("[FTS] upgrade to new version 0x%x\n", hw_fw_ver); + } + } else { + dbg_err("FW format error\n"); + } + } + + ft5x0x_auto_clb();/*start auto CLB*/ + +exit: + kfree(pbt_buf); + return i_ret; +} + + diff --git a/drivers/input/touchscreen/ft5x0x/ini.c b/drivers/input/touchscreen/ft5x0x/ini.c new file mode 100755 index 00000000..a4f8dc38 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ini.c @@ -0,0 +1,406 @@ +#include +#include +#include + +#include "ini.h" + + +char CFG_SSL = '['; /* 项标志符Section Symbol --可根据特殊需要进行定义更改,如 { }等*/ +char CFG_SSR = ']'; /* 项标志符Section Symbol --可根据特殊需要进行定义更改,如 { }等*/ +char CFG_NIS = ':'; /* name 与 index 之间的分隔符 */ +char CFG_NTS = '#'; /* 注释符*/ + +static char * ini_str_trim_r(char * buf); +static char * ini_str_trim_l(char * buf); +static int ini_file_get_line(char *filedata, char *buffer, int maxlen); +static int ini_split_key_value(char *buf, char **key, char **val); +static long atol(char *nptr); + + +/************************************************************* +Function: 获得key的值 +Input: char * filedata 文件;char * section 项值;char * key 键值 +Output: char * value key的值 +Return: 0 SUCCESS + -1 未找到section + -2 未找到key + -10 文件打开失败 + -12 读取文件失败 + -14 文件格式错误 + -22 超出缓冲区大小 +Note: +*************************************************************/ +int ini_get_key(char *filedata, char * section, char * key, char * value) +{ + //char buf1[MAX_CFG_BUF + 1], buf2[MAX_CFG_BUF + 1]; + char *buf1, *buf2; + char *key_ptr, *val_ptr; + int n, ret; + int dataoff = 0; + + *value='\0'; + + buf1 = kzalloc(MAX_CFG_BUF + 1, GFP_KERNEL); + if(!buf1){ + printk("buf1: mem alloc failed.\n"); + return -ENOMEM; + } + buf2 = kzalloc(MAX_CFG_BUF + 1, GFP_KERNEL); + if(!buf2){ + printk("buf2: mem alloc failed.\n"); + kfree(buf1); + return -ENOMEM; + } + + while(1) { /* 搜找项section */ + ret = CFG_ERR_READ_FILE; + n = ini_file_get_line(filedata+dataoff, buf1, MAX_CFG_BUF); + dataoff += n; + if(n < -1) + goto r_cfg_end; + ret = CFG_SECTION_NOT_FOUND; + if(n < 0) + goto r_cfg_end; /* 文件尾,未发现 */ + + n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); + if(n == 0 || buf1[0] == CFG_NTS) + continue; /* 空行 或 注释行 */ + + ret = CFG_ERR_FILE_FORMAT; + if(n > 2 && ((buf1[0] == CFG_SSL && buf1[n-1] != CFG_SSR))) + goto r_cfg_end; + if(buf1[0] == CFG_SSL) { + buf1[n-1] = 0x00; + if(strcmp(buf1+1, section) == 0) + break; /* 找到项section */ + } + } + + while(1){ /* 搜找key */ + ret = CFG_ERR_READ_FILE; + n = ini_file_get_line(filedata+dataoff, buf1, MAX_CFG_BUF); + dataoff += n; + if(n < -1) + goto r_cfg_end; + ret = CFG_KEY_NOT_FOUND; + if(n < 0) + goto r_cfg_end;/* 文件尾,未发现key */ + + n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); + if(n == 0 || buf1[0] == CFG_NTS) + continue; /* 空行 或 注释行 */ + ret = CFG_KEY_NOT_FOUND; + if(buf1[0] == CFG_SSL) + goto r_cfg_end; + if(buf1[n-1] == '+') { /* 遇+号表示下一行继续 */ + buf1[n-1] = 0x00; + while(1) { + ret = CFG_ERR_READ_FILE; + n = ini_file_get_line(filedata+dataoff, buf2, MAX_CFG_BUF); + dataoff += n; + if(n < -1) + goto r_cfg_end; + if(n < 0) + break;/* 文件结束 */ + + n = strlen(ini_str_trim_r(buf2)); + ret = CFG_ERR_EXCEED_BUF_SIZE; + if(n > 0 && buf2[n-1] == '+'){/* 遇+号表示下一行继续 */ + buf2[n-1] = 0x00; + if( (strlen(buf1) + strlen(buf2)) > MAX_CFG_BUF) + goto r_cfg_end; + strcat(buf1, buf2); + continue; + } + if(strlen(buf1) + strlen(buf2) > MAX_CFG_BUF) + goto r_cfg_end; + strcat(buf1, buf2); + break; + } + } + ret = CFG_ERR_FILE_FORMAT; + if(ini_split_key_value(buf1, &key_ptr, &val_ptr) != 1) + goto r_cfg_end; + ini_str_trim_l(ini_str_trim_r(key_ptr)); + if(strcmp(key_ptr, key) != 0) + continue; /* 和key值不匹配 */ + strcpy(value, val_ptr); + break; + } + ret = CFG_OK; +r_cfg_end: + //if(fp != NULL) fclose(fp); + kfree(buf1); + kfree(buf2); + return ret; +} +/************************************************************* +Function: 获得所有section +Input: char *filename 文件,int max 最大可返回的section的个数 +Output: char *sections[] 存放section名字 +Return: 返回section个数。若出错,返回负数。 + -10 文件打开出错 + -12 文件读取错误 + -14 文件格式错误 +Note: +*************************************************************/ +int ini_get_sections(char *filedata, unsigned char * sections[], int max) +{ + //FILE *fp; + char buf1[MAX_CFG_BUF + 1]; + int n, n_sections = 0, ret; + int dataoff = 0; + +// if((fp = fopen(filename, "rb")) == NULL) +// return CFG_ERR_OPEN_FILE; + + while(1) {/*搜找项section */ + ret = CFG_ERR_READ_FILE; + n = ini_file_get_line(filedata+dataoff, buf1, MAX_CFG_BUF); + dataoff += n; + if(n < -1) + goto cfg_scts_end; + if(n < 0) + break;/* 文件尾 */ + n = strlen(ini_str_trim_l(ini_str_trim_r(buf1))); + if(n == 0 || buf1[0] == CFG_NTS) + continue; /* 空行 或 注释行 */ + ret = CFG_ERR_FILE_FORMAT; + if(n > 2 && ((buf1[0] == CFG_SSL && buf1[n-1] != CFG_SSR))) + goto cfg_scts_end; + if(buf1[0] == CFG_SSL) { + if (max!=0){ + buf1[n-1] = 0x00; + strcpy((char *)sections[n_sections], buf1+1); + if (n_sections>=max) + break; /* 超过可返回最大个数 */ + } + n_sections++; + } + + } + ret = n_sections; +cfg_scts_end: +// if(fp != NULL) +// fclose(fp); + return ret; +} + + +/************************************************************* +Function: 去除字符串右边的空字符 +Input: char * buf 字符串指针 +Output: +Return: 字符串指针 +Note: +*************************************************************/ +static char * ini_str_trim_r(char * buf) +{ + int len,i; + char tmp[128]; + + memset(tmp, 0, sizeof(tmp)); + len = strlen(buf); +// tmp = (char *)malloc(len); + + memset(tmp,0x00,len); + for(i = 0;i < len;i++) { + if (buf[i] !=' ') + break; + } + if (i < len) { + strncpy(tmp,(buf+i),(len-i)); + } + strncpy(buf,tmp,len); +// free(tmp); + return buf; +} + +/************************************************************* +Function: 去除字符串左边的空字符 +Input: char * buf 字符串指针 +Output: +Return: 字符串指针 +Note: +*************************************************************/ +static char * ini_str_trim_l(char * buf) +{ + int len,i; + char tmp[128]; + + memset(tmp, 0, sizeof(tmp)); + len = strlen(buf); + //tmp = (char *)malloc(len); + + memset(tmp,0x00,len); + + for(i = 0;i < len;i++) { + if (buf[len-i-1] !=' ') + break; + } + if (i < len) { + strncpy(tmp,buf,len-i); + } + strncpy(buf,tmp,len); + //free(tmp); + return buf; +} +/************************************************************* +Function: 从文件中读取一行 +Input: FILE *fp 文件句柄;int maxlen 缓冲区最大长度 +Output: char *buffer 一行字符串 +Return: >0 实际读的长度 + -1 文件结束 + -2 读文件出错 +Note: +*************************************************************/ +static int ini_file_get_line(char *filedata, char *buffer, int maxlen) +{ + int i, j; + char ch1; + + for(i=0, j=0; i= n) + return 0; + + if(buf[i] == '=') + return -1; + + k1 = i; + for(i++; i < n; i++) + if(buf[i] == '=') + break; + + if(i >= n) + return -2; + k2 = i; + + for(i++; i < n; i++) + if(buf[i] != ' ' && buf[i] != '\t') + break; + + buf[k2] = '\0'; + + *key = buf + k1; + *val = buf + i; + return 1; +} + +int my_atoi(const char *str) +{ + int result = 0; + int signal = 1; /* 默认为正数 */ + if((*str>='0'&&*str<='9')||*str=='-'||*str=='+') { + if(*str=='-'||*str=='+') { + if(*str=='-') + signal = -1; /*输入负数*/ + str++; + } + } + else + return 0; + /*开始转换*/ + while(*str>='0' && *str<='9') + result = result*10 + (*str++ - '0' ); + + return signal*result; +} + +int isspace(int x) +{ + if(x==' '||x=='\t'||x=='\n'||x=='\f'||x=='\b'||x=='\r') + return 1; + else + return 0; +} + +int isdigit(int x) +{ + if(x<='9' && x>='0') + return 1; + else + return 0; + +} + +static long atol(char *nptr) +{ + int c; /* current char */ + long total; /* current total */ + int sign; /* if ''-'', then negative, otherwise positive */ + /* skip whitespace */ + while ( isspace((int)(unsigned char)*nptr) ) + ++nptr; + c = (int)(unsigned char)*nptr++; + sign = c; /* save sign indication */ + if (c == '-' || c == '+') + c = (int)(unsigned char)*nptr++; /* skip sign */ + total = 0; + while (isdigit(c)) { + total = 10 * total + (c - '0'); /* accumulate digit */ + c = (int)(unsigned char)*nptr++; /* get next char */ + } + if (sign == '-') + return -total; + else + return total; /* return result, negated if necessary */ +} +/*** +*int atoi(char *nptr) - Convert string to long +* +*Purpose: +* Converts ASCII string pointed to by nptr to binary. +* Overflow is not detected. Because of this, we can just use +* atol(). +* +*Entry: +* nptr = ptr to string to convert +* +*Exit: +* return int value of the string +* +*Exceptions: +* None - overflow is not detected. +* +*******************************************************************************/ +int atoi(char *nptr) +{ + return (int)atol(nptr); +} + diff --git a/drivers/input/touchscreen/ft5x0x/ini.h b/drivers/input/touchscreen/ft5x0x/ini.h new file mode 100755 index 00000000..72434b53 --- /dev/null +++ b/drivers/input/touchscreen/ft5x0x/ini.h @@ -0,0 +1,43 @@ +#ifndef INI_H +#define INI_H + +#define MAX_CFG_BUF 512 +#define SUCCESS 0 +/* return value */ +#define CFG_OK SUCCESS +#define CFG_SECTION_NOT_FOUND -1 +#define CFG_KEY_NOT_FOUND -2 +#define CFG_ERR -10 + +#define CFG_ERR_OPEN_FILE -10 +#define CFG_ERR_CREATE_FILE -11 +#define CFG_ERR_READ_FILE -12 +#define CFG_ERR_WRITE_FILE -13 +#define CFG_ERR_FILE_FORMAT -14 + + +#define CFG_ERR_EXCEED_BUF_SIZE -22 + +#define COPYF_OK SUCCESS +#define COPYF_ERR_OPEN_FILE -10 +#define COPYF_ERR_CREATE_FILE -11 +#define COPYF_ERR_READ_FILE -12 +#define COPYF_ERR_WRITE_FILE -13 + + +struct ini_key_location { + int ini_section_line_no; + int ini_key_line_no; + int ini_key_lines; +}; + + +int ini_get_key(char *filedata, char * section, char * key, char * value); +int ini_get_sections(char *filedata, unsigned char * sections[], int max); + +int ini_split_section(char *section, char **name, char **index); +//int ini_join_section(char **section, char *name, char *index); + +int atoi(char *nptr); + +#endif -- cgit