From: xuhuicong Date: Thu, 21 Mar 2013 15:23:14 +0000 (+0800) Subject: update ft5x0x driver add 10 point, support upgrade tp parameter and modify panic... X-Git-Tag: firefly_0821_release~7365 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=f6fe4f3526c8bd23e5065be4be713c408bafae0e;p=firefly-linux-kernel-4.4.55.git update ft5x0x driver add 10 point, support upgrade tp parameter and modify panic start up when touch --- diff --git a/drivers/input/touchscreen/ft5x0x.c b/drivers/input/touchscreen/ft5x0x.c old mode 100644 new mode 100755 index c8dabff60f11..c2335cf37ad6 --- a/drivers/input/touchscreen/ft5x0x.c +++ b/drivers/input/touchscreen/ft5x0x.c @@ -30,24 +30,12 @@ #define EV_MENU KEY_MENU #define I2C_SPEED 200*1000 -#define MAX_POINT 5 - -#if defined (CONFIG_TOUCHSCREEN_1024X768) -#define SCREEN_MAX_X 1024 -#define SCREEN_MAX_Y 768 -#elif defined (CONFIG_TOUCHSCREEN_1024X600) -#define SCREEN_MAX_X 1024 -#define SCREEN_MAX_Y 600 -#elif defined (CONFIG_TOUCHSCREEN_800X600) -#define SCREEN_MAX_X 800 -#define SCREEN_MAX_Y 600 -#elif defined (CONFIG_TOUCHSCREEN_800X480) -#define SCREEN_MAX_X 800 -#define SCREEN_MAX_Y 480 -#else -#define SCREEN_MAX_X 800 -#define SCREEN_MAX_Y 480 -#endif +#define MAX_POINT 10 + +#define SCREEN_MAX_X 1920 +#define SCREEN_MAX_Y 1200 + +//#define TP_UPGRADE 1 #define PRESS_MAX 200 @@ -92,6 +80,562 @@ struct ft5x0x_data struct i2c_client *g_client; + +#define FT5X0X_REG_FIRMID 0xA6 /* ***************firmware version **********************/ + +/*********************************************************************** + [function]: + callback: write data to ctpm by i2c interface; + [parameters]: + buffer[in]: data buffer; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool i2c_write_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + ret=i2c_master_send(g_client, pbt_buf, dw_lenth); + if(ret<=0) + { + printk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret); + return false; + } + + return true; +} + +#ifdef TP_UPGRADE + +#if 0 +#define FTprintk(x...) printk(x) +#else +#define FTprintk(x...) do{} while(0) +#endif + +//#define CONFIG_FT5X0X_MULTITOUCH 1 +#define FT5306_IIC_SPEED 250*1000 //300*1000 +#define FT5X0X_REG_THRES 0x80 /* Thresshold, the threshold be low, the sensitivy will be high */ +#define FT5X0X_REG_REPORT_RATE 0x88 /* **************report rate, in unit of 10Hz **************/ +#define FT5X0X_REG_PMODE 0xA5 /* Power Consume Mode 0 -- active, 1 -- monitor, 3 -- sleep */ +//#define FT5X0X_REG_FIRMID 0xA6 /* ***************firmware version **********************/ +#define FT5X0X_REG_NOISE_MODE 0xb2 /* to enable or disable power noise, 1 -- enable, 0 -- disable */ + +//FT5X0X_REG_PMODE +#define PMODE_ACTIVE 0x00 +#define PMODE_MONITOR 0x01 +#define PMODE_STANDBY 0x02 +#define PMODE_HIBERNATE 0x03 + + +struct tp_event { + u16 x; + u16 y; + s16 id; + u16 pressure; + u8 touch_point; + u8 flag; +}; + +struct ft5x0x_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + int irq; + int (*platform_sleep)(void); + int (*platform_wakeup)(void); + struct ts_event event; + struct work_struct pen_event_work; + struct workqueue_struct *ts_workqueue; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend ft5306_early_suspend; +#endif +}; + +/***********************************************************************/ + +#define FTS_PACKET_LENGTH 128 + + +static u8 CTPM_FW[]= +{ +//#include "7022620120726B.txt" +//#include "101050-01A-ft_app.i" +//#include "ft_app_u30gt2.i" +#include "20130305-u30gt2-ft5506_app.i" +}; + +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 +}E_UPGRADE_ERR_TYPE; + +/***********************************************************************/ + +/*********************************************************************** + [function]: + callback: send data to ctpm by i2c interface; + [parameters]: + txdata[in]: data buffer which is used to send data; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static int fts_i2c_txdata(u8 *txdata, int length) +{ + int ret; + + struct i2c_msg msg; + + msg.addr = g_client->addr; + msg.flags = 0; + msg.len = length; + msg.buf = txdata; + msg.scl_rate = FT5306_IIC_SPEED; + ret = i2c_transfer(g_client->adapter, &msg, 1); + if (ret < 0) + pr_err("%s i2c write error: %d\n", __func__, ret); + + return ret; +} + + +/*********************************************************************** + [function]: + callback: read register value ftom ctpm by i2c interface; + [parameters]: + reg_name[in]: the register which you want to write; + tx_buf[in]: buffer which is contained of the writing value; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool fts_register_write(u8 reg_name, u8* tx_buf) +{ + u8 write_cmd[2] = {0}; + + write_cmd[0] = reg_name; + write_cmd[1] = *tx_buf; + + /*call the write callback function*/ + return i2c_write_interface(write_cmd, 2); +} + +/*********************************************************************** +[function]: + callback: 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 bool cmd_write(u8 btcmd,u8 btPara1,u8 btPara2,u8 btPara3,u8 num) +{ + u8 write_cmd[4] = {0}; + + write_cmd[0] = btcmd; + write_cmd[1] = btPara1; + write_cmd[2] = btPara2; + write_cmd[3] = btPara3; + return i2c_write_interface(write_cmd, num); +} + +/*********************************************************************** + [function]: + callback: read data from ctpm by i2c interface; + [parameters]: + buffer[in]: data buffer; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool i2c_read_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + + ret=i2c_master_recv(g_client, pbt_buf, dw_lenth); + + if(ret<=0) + { + FTprintk("[TSP]i2c_read_interface error\n"); + return false; + } + + return true; +} + + +/*********************************************************************** +[function]: + callback: read a byte data from ctpm; +[parameters]: + buffer[in]: read buffer; + length[in]: the size of read data; +[return]: + FTS_TRUE: success; + FTS_FALSE: io fail; +************************************************************************/ +static bool byte_read(u8* buffer, int length) +{ + return i2c_read_interface(buffer, length); +} + +/*********************************************************************** +[function]: + callback: write a byte data to ctpm; +[parameters]: + buffer[in]: write buffer; + length[in]: the size of write data; +[return]: + FTS_TRUE: success; + FTS_FALSE: io fail; +************************************************************************/ +static bool byte_write(u8* buffer, int length) +{ + + return i2c_write_interface(buffer, length); +} + +/*********************************************************************** + [function]: + callback: read register value ftom ctpm by i2c interface; + [parameters]: + reg_name[in]: the register which you want to read; + rx_buf[in]: data buffer which is used to store register value; + rx_length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool fts_register_read(u8 reg_name, u8* rx_buf, int rx_length) +{ + u8 read_cmd[2]= {0}; + u8 cmd_len = 0; + + read_cmd[0] = reg_name; + cmd_len = 1; + + /*send register addr*/ + if(!i2c_write_interface(&read_cmd[0], cmd_len)) + { + return false; + } + + /*call the read callback function to get the register value*/ + if(!i2c_read_interface(rx_buf, rx_length)) + { + return false; + } + return true; +} + + + +/*********************************************************************** +[function]: + callback: burn the FW to ctpm. +[parameters]: + pbt_buf[in]: point to Head+FW ; + dw_lenth[in]: the length of the FW + 6(the Head length); +[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. +************************************************************************/ +E_UPGRADE_ERR_TYPE fts_ctpm_fw_upgrade(u8* pbt_buf, int dw_lenth) +{ + u8 cmd,reg_val[2] = {0}; + u8 buffer[2] = {0}; + u8 packet_buf[FTS_PACKET_LENGTH + 6]; + u8 auc_i2c_write_buf[10]; + u8 bt_ecc; + + int j,temp,lenght,i_ret,packet_number, i = 0; + int i_is_new_protocol = 0; + + + /******write 0xaa to register 0xfc******/ + cmd=0xaa; + fts_register_write(0xfc,&cmd); + mdelay(50); + + /******write 0x55 to register 0xfc******/ + cmd=0x55; + fts_register_write(0xfc,&cmd); + FTprintk("[TSP] Step 1: Reset CTPM test\n"); + + mdelay(30); + + + /******write 0xaa to register 0xfc******/ + cmd=0xaa; + fts_register_write(0xfc,&cmd); + mdelay(50); + + /******write 0x55 to register 0xfc******/ + cmd=0x55; + fts_register_write(0xfc,&cmd); + FTprintk("[TSP] Step 1: Reset CTPM test\n"); + + mdelay(30); + + /******write 0xaa to register 0xfc******/ + cmd=0xaa; + fts_register_write(0xfc,&cmd); + mdelay(50); + + /******write 0x55 to register 0xfc******/ + cmd=0x55; + fts_register_write(0xfc,&cmd); + FTprintk("[TSP] Step 1: Reset CTPM test\n"); + + mdelay(30); + + + + + /*******Step 2:Enter upgrade mode ****/ + FTprintk("\n[TSP] Step 2:enter new update mode\n"); + auc_i2c_write_buf[0] = 0x55; + auc_i2c_write_buf[1] = 0xaa; + printk("xhc-----------!!!!!!!!!\n"); + do + { + i ++; + i_ret = fts_i2c_txdata(auc_i2c_write_buf, 2); + mdelay(50); + }while(i_ret <= 0 && i < 10 ); + + if (i > 1) + { + i_is_new_protocol = 1; + } + + /********Step 3:check READ-ID********/ + mdelay(100); + cmd_write(0x90,0x00,0x00,0x00,4); + byte_read(reg_val,2); + printk("################## id0=0x%0x, id1=0x%0x\n", reg_val[0],reg_val[1]); + if (reg_val[0] == 0x79 && reg_val[1] == 0x6) + { + FTprintk("[TSP] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + } + else + { + return ERR_READID; + //i_is_new_protocol = 1; + } + + + /*********Step 4:erase app**********/ + if (i_is_new_protocol) + { + cmd_write(0x61,0x00,0x00,0x00,1); + } + else + { + cmd_write(0x60,0x00,0x00,0x00,1); + } + mdelay(1500); + FTprintk("[TSP] Step 4: erase. \n"); + + + + /*Step 5:write firmware(FW) to ctpm flash*/ + bt_ecc = 0; + FTprintk("[TSP] 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; + FTprintk("[TSP] packet_number = %d\n",packet_number); + 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); + } + + /********send the opration head************/ + cmd_write(0xcc,0x00,0x00,0x00,1); + byte_read(reg_val,1); + FTprintk("[TSP] Step 6: ecc read 0x%x, new firmware 0x%x. \n", reg_val[0], bt_ecc); + if(reg_val[0] != bt_ecc) + { + return ERR_ECC; + } + + /*******Step 7: reset the new FW**********/ + cmd_write(0x07,0x00,0x00,0x00,1); + mdelay(100);//100ms + fts_register_read(0xfc, buffer, 1); + if (buffer[0] == 1) + { + cmd=4; + fts_register_write(0xfc, &cmd); + mdelay(2500);//2500ms + do + { + fts_register_read(0xfc, buffer, 1); + mdelay(100);//100ms + }while (buffer[0] != 1); + } + return ERR_OK; +} + +int fts_ctpm_auto_clb(void) +{ + unsigned char uc_temp; + unsigned char i ; + u8 reg_val; + + printk("[FTS] start auto CLB.\n"); + msleep(200); + reg_val = 0x40; + fts_register_write(0x0, ®_val); + mdelay(100); + reg_val = 0x4; + fts_register_write(0x02, ®_val); + mdelay(300); + + for(i=0;i<100;i++) + { + fts_register_read(0x0, ®_val, 1); + if ( ((reg_val&0x70)>>4) == 0x0) //return to normal mode, calibration finish + { + break; + } + mdelay(200); + printk("[FTS] waiting calibration %d\n",i); + + } + printk("[FTS] calibration OK.\n"); + + msleep(300); + reg_val = 0x40; + fts_register_write(0x0, ®_val); //goto factory mode + mdelay(100); //make sure already enter factory mode + reg_val = 0x05; + fts_register_write(0x2, ®_val); //store CLB result + mdelay(300); + reg_val = 0x0; + fts_register_write(0x0, ®_val); //return to normal mode + msleep(300); + printk("[FTS] store CLB result OK.\n"); + return 0; +} + +/***********************************************************************/ + +int fts_ctpm_fw_upgrade_with_i_file(void) +{ + u8* pbt_buf = 0; + int i_ret; + + pbt_buf = CTPM_FW; + i_ret = fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW)); + + if (i_ret != 0) { + printk("[FTS] upgrade failed i_ret = %d.\n", i_ret); + } else { + fts_ctpm_auto_clb(); //start auto CLB + printk("[FTS] upgrade successfully....\n"); + } + + return i_ret; +} + +/***********************************************************************/ + +unsigned char fts_ctpm_get_upg_ver(void) +{ + unsigned int ui_sz; + + ui_sz = sizeof(CTPM_FW); + if (ui_sz > 2) + { + return CTPM_FW[ui_sz - 2]; + } + else + return 0xff; + +} + +#endif + + /*********************************************************************************************** Name : ft5x0x_i2c_rxdata @@ -266,17 +810,7 @@ static void ft5x0x_chip_reset(struct ft5x0x_data *tsdata) gpio_set_value(tsdata->reset_gpio, 1); } -static int i2c_write_interface(unsigned char* pbt_buf, int dw_lenth) -{ - int ret; - ret = i2c_master_send(g_client, pbt_buf, dw_lenth); - if (ret <= 0) { - printk("i2c_write_interface error\n"); - return -1; - } - return 0; -} static int ft_cmd_write(unsigned char btcmd, unsigned char btPara1, unsigned char btPara2, unsigned char btPara3, int num) @@ -287,7 +821,8 @@ static int ft_cmd_write(unsigned char btcmd, unsigned char btPara1, unsigned cha write_cmd[1] = btPara1; write_cmd[2] = btPara2; write_cmd[3] = btPara3; - return i2c_write_interface(&write_cmd, num); + // printk("&write_cmd=0x%08x, &write_cmd[0]=0x%08x\n", &write_cmd, &write_cmd[0]); + return i2c_write_interface(write_cmd, num); } @@ -327,7 +862,7 @@ static int ft5x0x_chip_init(struct i2c_client * client) ft5x0x_chip_reset(tsdata); ft5x0x_power_en(tsdata, 1); mdelay(500); - ft_cmd_write(0x07,0x00,0x00,0x00,1); + ft_cmd_write(0x07,0x00,0x00,0x00,1); mdelay(10); #if 1 @@ -374,8 +909,8 @@ static int ft5x0x_chip_init(struct i2c_client * client) return ret; -exit_alloc_gpio_power_failed: #if defined (TOUCH_POWER_PIN) +exit_alloc_gpio_power_failed: gpio_free(tsdata->touch_en_gpio); #endif exit_alloc_gpio_rst_failed: @@ -391,17 +926,18 @@ static void key_led_ctrl(int on) #endif } -static int g_screen_key=0; +//static int g_screen_key=0; static int ft5x0x_process_points(struct ft5x0x_data *data) { struct i2c_client *client = data->client; u8 start_reg = 0x0; - u8 buf[32] = {0}; + u8 buf[64] = {0}; int ret = -1; - int status = 0, id, x, y, p, w, touch_num; + int status = 0, id, x, y, touch_num; int offset, i; - int back_press = 0, search_press=0, menu_press=0, home_press=0; + // int static w, p; + // int back_press = 0, search_press=0, menu_press=0, home_press=0; int points; start_reg = 0; @@ -411,7 +947,7 @@ static int ft5x0x_process_points(struct ft5x0x_data *data) if (MAX_POINT == 5) { ret = ft5x0x_rx_data(client, buf, 31); } else { - ret = ft5x0x_rx_data(client, buf, 13); + ret = ft5x0x_rx_data(client, buf, 62); } if (ret < 0) { @@ -423,7 +959,7 @@ static int ft5x0x_process_points(struct ft5x0x_data *data) if (MAX_POINT == 5) { touch_num = buf[2] & 0x07; } else { - touch_num = buf[2] & 0x03; + touch_num = buf[2] & 0x0f; } if (touch_num == 0) { @@ -620,7 +1156,7 @@ static int ft5x0x_client_init(struct i2c_client *client) DBG(KERN_ERR "ft5x0x_client_init: request irq failed,ret is %d\n", ret); return ret; } - //disable_irq(client->irq); + disable_irq(client->irq); return 0; } @@ -630,7 +1166,12 @@ static int ft5x0x_probe(struct i2c_client *client, const struct i2c_device_id * struct ft5x0x_data *ft5x0x_ts; struct ts_hw_data *pdata = client->dev.platform_data; int err = 0; - int i; + // int i; + + unsigned char reg_version; +#ifdef TP_UPGRADE + unsigned char reg_value; +#endif printk("%s enter\n",__FUNCTION__); ft5x0x_ts = kzalloc(sizeof(struct ft5x0x_data), GFP_KERNEL); @@ -700,6 +1241,37 @@ static int ft5x0x_probe(struct i2c_client *client, const struct i2c_device_id * input_set_abs_params(ft5x0x_ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); input_set_abs_params(ft5x0x_ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0); + /***wait CTP to bootup normally***/ + msleep(200); + reg_version = FT5X0X_REG_FIRMID; + ft5x0x_rx_data(client, ®_version,1); + printk("------------------cdy == [TSP] firmware tpversion = 0x%2x-------------------------\n", reg_version); + + +#ifdef TP_UPGRADE //write firmware + fts_register_read(FT5X0X_REG_FIRMID, ®_version,1); + FTprintk("[TSP] firmware version = 0x%2x\n", reg_version); + if (fts_ctpm_get_upg_ver() != reg_version) + { + FTprintk("[TSP] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver()); + msleep(200); + err = fts_ctpm_fw_upgrade_with_i_file(); + if (err == 0) + { + FTprintk("[TSP] ugrade successfuly.\n"); + msleep(300); + fts_register_read(FT5X0X_REG_FIRMID, ®_value,1); + FTprintk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value); + } + else + { + FTprintk("[TSP] ugrade fail err=%d, line = %d.\n",err, __LINE__); + } + msleep(4000); + } +#endif + + #ifdef CONFIG_HAS_EARLYSUSPEND ft5x0x_early_suspend.suspend = ft5x0x_suspend; ft5x0x_early_suspend.resume = ft5x0x_resume; @@ -707,6 +1279,9 @@ static int ft5x0x_probe(struct i2c_client *client, const struct i2c_device_id * register_early_suspend(&ft5x0x_early_suspend); #endif + + + enable_irq(client->irq); return 0; exit_input_register_device_failed: @@ -715,12 +1290,14 @@ exit_input_allocate_device_failed: free_irq(client->irq, ft5x0x_ts); exit_request_gpio_irq_failed: kfree(ft5x0x_ts); -exit_alloc_gpio_power_failed: #if defined (TOUCH_POWER_PIN) +exit_alloc_gpio_power_failed: gpio_free(ft5x0x_ts->touch_en_gpio); #endif +#if 0 exit_alloc_gpio_rst_failed: gpio_free(ft5x0x_ts->reset_gpio); +#endif exit_alloc_data_failed: printk("%s error\n",__FUNCTION__); return err;