ft5x06 驱动带键盘



下面是源文件

/*
 * drivers/input/touchscreen/ft5x0x_ts.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.
 *
 * VERSION       DATE  AUTHOR         Note
 *    1.0   2010-01-05  WenFS     only support mulititouch Wenfs 2010-10-01
 *    2.0         2011-09-05            Duxx       Add touch key, and project setting update, auto CLB command
 *    3.0   2013-03-11  EasyWave Porting to linux2.6.17.14 version  
 *
 */

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <asm/uaccess.h>
#include <linux/version.h> // new v1.3
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/input/mt.h>
#include <linux/input/edt-ft5x06.h>
#include <mach/mfp.h>
#include "ft5x06_ts.h"
#ifdef CONFIG_TOUCH_VKBD
#include <linux/netfilter_ipv4.h>
#endif

#define DEBUG 1
#define DEBUG_0 1

#ifdef DEBUG_0
#define TS_DEBUG(fmt,args...) printk(fmt, ##args )
#else
#define TS_DEBUG(fmt,args...)
#endif

#ifdef DEBUG
#define TS_DEBUG1(fmt,args...) printk(fmt, ##args )
#else
#define TS_DEBUG1(fmt,args...)
#endif

/*
 *****************************************************************************
 *
 * I2C Driver Interface
 *
 *****************************************************************************
 */
static struct i2c_client *this_client;
//static struct mutex touchlock;

struct ts_event {
 u16 au16_x[CFG_MAX_TOUCH_POINTS];             //x coordinate
 u16 au16_y[CFG_MAX_TOUCH_POINTS];              //y coordinate
 u8 au8_touch_event[CFG_MAX_TOUCH_POINTS]; //touch event:  0 -- down; 1-- contact; 2 -- contact
 u8 au8_finger_id[CFG_MAX_TOUCH_POINTS];       //touch ID
 u16 pressure;
 u8 touch_point;
};

struct ft5x0x_ts_data {
 struct input_dev *input_dev;
 struct ts_event event;
 struct work_struct pen_event_work;
 struct workqueue_struct *ts_workqueue;
//struct early_suspend early_suspend;
};
#ifdef CONFIG_TOUCH_VKBD
static int ts_keycode[CFG_NUMOFKEYS]=
{
 /*{ "Esc",*/KEY_ESC,
 /*{ "`",*/KEY_GRAVE /*}*/,
 /*{ "1", */KEY_1 /*}*/,
 /*{ "2",*/KEY_2 /*}*/,
 /*{ "3",*/KEY_3 /*}*/,
 /*{ "4", */KEY_4 /*}*/,
 /*{ "5", */KEY_5 /*}*/,
 /*{ "6", */KEY_6 /*}*/,
 /*{ "7", */KEY_7 /*}*/,
 /*{ "8", */KEY_8 /*}*/,
 /*{ "9", */KEY_9 /*}*/,
 /*{ "0", */KEY_0 /*}*/,
 /*{ "-", */KEY_MINUS /*}*/,
 /*{ "=", */KEY_EQUAL /*}*/,
 /*{ "[", */KEY_LEFTBRACE /*}*/,
 /*{ "]", */KEY_RIGHTBRACE /*}*/,
 /*{ "\\",*/KEY_BACKSLASH /*}*/,
 /*{ ";", */KEY_SEMICOLON /*}*/,
 /*{ "'", */KEY_APOSTROPHE /*}*/,
 /*{ ",", */KEY_COMMA /*}*/,
 /*{ ".", */KEY_DOT /*}*/,
 /*{ "/", */KEY_SLASH /*}*/,
 /*{ "Space",*/KEY_SPACE /*}*/,
 /*{ "Tab", */KEY_TAB /*}*/,
 /*{ "Ins", */KEY_INSERT /*}*/,
 /*{ "Bs", */KEY_BACKSPACE /* }*/,
 /*{ "Enter", */KEY_ENTER /*}*/,
 /*{ "Next", */KEY_UNKNOWN/*}*/
};

struct Keyboard keyboard= {0,0, {
  { "Esc",},
  { "`",},
  { "1",},
  { "2",},
  { "3",},
  { "4",},
  { "5",},
  { "6",},
  { "7",},
  { "8",},
  { "9",},
  { "0",},
  { "-",},
  { "=",},
  { "[",},
  { "]",},
  { "\\",},
  { ";",},
  { "'",},
  { ",",},
  { ".",},
  { "/",},
  { "Space",},
  { "Tab",},
  { "Ins",},
  { "Bs",},
  { "Enter",},
  { "Next",}}
};
#endif
/***********************************************************************************************
 Name : ft5x0x_i2c_rxdata

 Input : *rxdata
 *length

 Output : ret

 function :

 ***********************************************************************************************/
static int ft5x0x_i2c_rxdata(char *rxdata, int length) {
 int ret;

 struct i2c_msg msgs[] = { { .addr = this_client->addr, .flags = 0, .len = 1,
   .buf = rxdata, }, { .addr = this_client->addr, .flags = I2C_M_RD,
   .len = length, .buf = rxdata, }, };

 ret = i2c_transfer(this_client->adapter, msgs, 2);
 // if (ret < 0)
//  printk("%s i2c read error: %d\n", __func__, ret);
 return ret;
}

/***********************************************************************************************
 Name : ft5x0x_read_reg

 Input : addr
 pdata

 Output :

 function : read register of ft5x0x

 ***********************************************************************************************/
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 = this_client->addr;
 msgs[0].flags = 0;
 msgs[0].len = 1;
 msgs[0].buf = buf;
 msgs[1].addr = this_client->addr;
 msgs[1].flags = I2C_M_RD;
 msgs[1].len = 1;
 msgs[1].buf = buf;

 ret = i2c_transfer(this_client->adapter, msgs, 2);
 if (ret < 0)
  printk("msg %s i2c read error: %d\n", __func__, ret);
 else
  *pdata = buf[0];
 return ret;
}

/***********************************************************************************************
 Name :  ft5x0x_read_fw_ver

 Input :  void


 Output :  firmware version

 function :  read TP firmware version

 ***********************************************************************************************/
static unsigned char ft5x0x_read_fw_ver(void) {
 unsigned char ver = 0;
 ft5x0x_read_reg(FT5X0X_REG_FIRMID, &ver);
 return (ver);
}

#if CFG_SUPPORT_AUTO_UPG  //upgrade related

/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static int ft5x0x_i2c_txdata(char *txdata, int length)
{
 int ret;

 struct i2c_msg msg[] = {
  {
   .addr = this_client->addr,
   .flags = 0,
   .len = length,
   .buf = txdata,
  },
 };
 ret = i2c_transfer(this_client->adapter, msg, 1);
 if (ret < 0)
 printk("%s i2c write error: %d\n", __func__, ret);

 return ret;
}

/***********************************************************************************************
 Name :  ft5x0x_write_reg

 Input : addr -- address
 para -- parameter

 Output :

 function : write register of ft5x0x

 ***********************************************************************************************/
static int ft5x0x_write_reg(u8 addr, u8 para)
{
 u8 buf[3];
 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;
}

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;

typedef unsigned char FTS_BYTE;     //8 bit
typedef unsigned short FTS_WORD;//16 bit
typedef unsigned int FTS_DWRD;//16 bit
typedef unsigned char FTS_BOOL;//8 bit

typedef struct _FTS_CTP_PROJECT_SETTING_T
{
 unsigned char uc_i2C_addr;             //I2C slave address (8 bit address)
 unsigned char uc_io_voltage;//IO Voltage 0---3.3v; 1----1.8v
 unsigned char uc_panel_factory_id;//TP panel factory ID
}FTS_CTP_PROJECT_SETTING_T;

#define FTS_NULL                0x00
#define FTS_TRUE                0x01
#define FTS_FALSE  0x00

#define I2C_CTPM_ADDRESS 0x70

void delay_qt_ms(unsigned long w_ms)
{
 unsigned long i;
 unsigned long j;

 for (i = 0; i < w_ms; i++) {
  for (j = 0; j < 1000; j++) {
   udelay(1);
  }
 }
}

/*
 [function]:
 callback: read data from ctpm by i2c interface,implemented by special user;
 [parameters]:
 bt_ctpm_addr[in]    :the address of the ctpm;
 pbt_buf[out]        :data buffer;
 dw_lenth[in]        :the length of the data buffer;
 [return]:
 FTS_TRUE     :success;
 FTS_FALSE    :fail;
 */
FTS_BOOL i2c_read_interface(FTS_BYTE bt_ctpm_addr, FTS_BYTE* pbt_buf, FTS_DWRD dw_lenth)
{
 int ret;

 ret = i2c_master_recv(this_client, pbt_buf, dw_lenth);

 if(ret<=0) {
  printk("[FTS]i2c_read_interface error\n");
  return FTS_FALSE;
 }
 return FTS_TRUE;
}

/*
 [function]:
 callback: write data to ctpm by i2c interface,implemented by special user;
 [parameters]:
 bt_ctpm_addr[in]    :the address of the ctpm;
 pbt_buf[in]        :data buffer;
 dw_lenth[in]        :the length of the data buffer;
 [return]:
 FTS_TRUE     :success;
 FTS_FALSE    :fail;
 */
FTS_BOOL i2c_write_interface(FTS_BYTE bt_ctpm_addr, FTS_BYTE* pbt_buf, FTS_DWRD dw_lenth)
{
 int ret;
 ret = i2c_master_send(this_client, pbt_buf, dw_lenth);
 if(ret<=0) {
  printk("[FTS]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);
  return FTS_FALSE;
 }
 return FTS_TRUE;
}

/*
 [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;
 */
FTS_BOOL cmd_write(FTS_BYTE btcmd,FTS_BYTE btPara1,FTS_BYTE btPara2,FTS_BYTE btPara3,FTS_BYTE num)
{
 FTS_BYTE write_cmd[4] = {0};

 write_cmd[0] = btcmd;
 write_cmd[1] = btPara1;
 write_cmd[2] = btPara2;
 write_cmd[3] = btPara3;
 return i2c_write_interface(I2C_CTPM_ADDRESS, write_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;
 */
FTS_BOOL byte_write(FTS_BYTE* pbt_buf, FTS_DWRD dw_len)
{
 return i2c_write_interface(I2C_CTPM_ADDRESS, 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;
 */
FTS_BOOL byte_read(FTS_BYTE* pbt_buf, FTS_BYTE bt_len)
{
 return i2c_read_interface(I2C_CTPM_ADDRESS, pbt_buf, bt_len);
}

/*
 [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.
 */

#define    FTS_PACKET_LENGTH        128

static unsigned char CTPM_FW[]= {
#include "ft_app.i"
};

E_UPGRADE_ERR_TYPE fts_ctpm_fw_upgrade(FTS_BYTE* pbt_buf, FTS_DWRD dw_lenth)
{
 FTS_BYTE reg_val[2] = {0};
 FTS_DWRD i = 0;

 FTS_DWRD packet_number;
 FTS_DWRD j;
 FTS_DWRD temp;
 FTS_DWRD lenght;
 FTS_BYTE packet_buf[FTS_PACKET_LENGTH + 6];
 FTS_BYTE auc_i2c_write_buf[10];
 FTS_BYTE bt_ecc;
 int i_ret;

 /*********Step 1:Reset  CTPM *****/
 /*write 0xaa to register 0xfc*/
 ft5x0x_write_reg(0xfc,0xaa);
 delay_qt_ms(50);
 /*write 0x55 to register 0xfc*/
 ft5x0x_write_reg(0xfc,0x55);
 TS_DEBUG("[FTS] Step 1: Reset CTPM test\n");
 delay_qt_ms(30);
 /*********Step 2:Enter upgrade mode *****/
 auc_i2c_write_buf[0] = 0x55;
 auc_i2c_write_buf[1] = 0xaa;
 do {
  i ++;
  i_ret = ft5x0x_i2c_txdata(auc_i2c_write_buf, 2);
  delay_qt_ms(5);
 }while(i_ret <= 0 && i < 5 );

 /*********Step 3:check READ-ID***********************/
 cmd_write(0x90,0x00,0x00,0x00,4);
 byte_read(reg_val,2);
 if (reg_val[0] == 0x79 && reg_val[1] == 0x3) {
  printk("[FTS] 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;
 }

 cmd_write(0xcd,0x0,0x00,0x00,1);
 byte_read(reg_val,1);
 TS_DEBUG("[FTS] bootloader version = 0x%x\n", reg_val[0]);

 /*********Step 4:erase app and panel paramenter area ********************/
 cmd_write(0x61,0x00,0x00,0x00,1);  //erase app area
 delay_qt_ms(1500);
 cmd_write(0x63,0x00,0x00,0x00,1);//erase panel parameter area
 delay_qt_ms(100);
 TS_DEBUG("[FTS] Step 4: erase. \n");

 /*********Step 5:write firmware(FW) to ctpm flash*********/
 bt_ecc = 0;
 TS_DEBUG("[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<packet_number;j++) {
  temp = j * FTS_PACKET_LENGTH;
  packet_buf[2] = (FTS_BYTE)(temp>>8);
  packet_buf[3] = (FTS_BYTE)temp;
  lenght = FTS_PACKET_LENGTH;
  packet_buf[4] = (FTS_BYTE)(lenght>>8);
  packet_buf[5] = (FTS_BYTE)lenght;

  for (i=0;i<FTS_PACKET_LENGTH;i++) {
   packet_buf[6+i] = pbt_buf[j*FTS_PACKET_LENGTH + i];
   bt_ecc ^= packet_buf[6+i];
  }
  byte_write(&packet_buf[0],FTS_PACKET_LENGTH + 6);
  delay_qt_ms(FTS_PACKET_LENGTH/6 + 1);
  if ((j * FTS_PACKET_LENGTH % 1024) == 0) {
   TS_DEBUG("[FTS] upgrade the 0x%x th byte.\n", ((unsigned int)j) * FTS_PACKET_LENGTH);
  }
 }

 if ((dw_lenth) % FTS_PACKET_LENGTH > 0) {

  temp = packet_number * FTS_PACKET_LENGTH;
  packet_buf[2] = (FTS_BYTE)(temp>>8);
  packet_buf[3] = (FTS_BYTE)temp;

  temp = (dw_lenth) % FTS_PACKET_LENGTH;
  packet_buf[4] = (FTS_BYTE)(temp>>8);
  packet_buf[5] = (FTS_BYTE)temp;

  for (i=0;i<temp;i++) {
   packet_buf[6+i] = pbt_buf[ packet_number*FTS_PACKET_LENGTH + i];
   bt_ecc ^= packet_buf[6+i];
  }
  byte_write(&packet_buf[0],temp+6);
  delay_qt_ms(20);
 }

 //send the last six byte
 for (i = 0; i<6; i++) {
  temp = 0x6ffa + i;
  packet_buf[2] = (FTS_BYTE)(temp>>8);
  packet_buf[3] = (FTS_BYTE)temp;
  temp =1;
  packet_buf[4] = (FTS_BYTE)(temp>>8);
  packet_buf[5] = (FTS_BYTE)temp;
  packet_buf[6] = pbt_buf[ dw_lenth + i];
  bt_ecc ^= packet_buf[6];

  byte_write(&packet_buf[0],7);
  delay_qt_ms(20);
 }

 /*********Step 6: read out checksum***********************/
 /*send the opration head*/
 cmd_write(0xcc,0x00,0x00,0x00,1);
 byte_read(reg_val,1);
 TS_DEBUG("[FTS] 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);

 msleep(300);  //make sure CTP startup normally

 return ERR_OK;
}

int fts_ctpm_auto_clb(void)
{
 unsigned char uc_temp;
 unsigned char i;

 TS_DEBUG("[FTS] start auto CLB.\n");
 msleep(200);
 ft5x0x_write_reg(0, 0x40);
 delay_qt_ms(100);   //make sure already enter factory mode
 ft5x0x_write_reg(2, 0x4);//write command to start calibration
 delay_qt_ms(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;
  }
  delay_qt_ms(200);
  printk("[FTS] waiting calibration %d\n",i);
 }
 TS_DEBUG("[FTS] calibration OK.\n");
 msleep(300);
 ft5x0x_write_reg(0, 0x40);  //goto factory mode
 delay_qt_ms(100);//make sure already enter factory mode
 ft5x0x_write_reg(2, 0x5);//store CLB result
 delay_qt_ms(300);
 ft5x0x_write_reg(0, 0x0);//return to normal mode
 msleep(300);
 TS_DEBUG("[FTS] store CLB result OK.\n");
 return 0;
}

int fts_ctpm_fw_upgrade_with_i_file(void)
{
 FTS_BYTE* pbt_buf = FTS_NULL;
 int i_ret;

 //=========FW upgrade========================*/
 pbt_buf = CTPM_FW;
 /*call the upgrade function*/
 i_ret = fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW));
 if (i_ret != 0) {
  TS_DEBUG("[FTS] upgrade failed i_ret = %d.\n", i_ret);
  //error handling ...
  //TBD
 } else {
  TS_DEBUG("[FTS] upgrade successfully.\n");
  fts_ctpm_auto_clb();  //start auto CLB
  fts_ctpm_auto_clb();//start auto CLB
 }
 return i_ret;
}

unsigned char fts_ctpm_get_i_file_ver(void)
{
 unsigned int ui_sz;
 ui_sz = sizeof(CTPM_FW);
 if (ui_sz > 2) {
  return CTPM_FW[ui_sz - 2];
 } else {
  //TBD, error handling?
  return 0xff;//default value
 }
}

#define    FTS_SETTING_BUF_LEN        128

//update project setting
//only update these settings for COB project, or for some special case
int fts_ctpm_update_project_setting(void)
{
 unsigned char uc_i2c_addr;             //I2C slave address (8 bit address)
 unsigned char uc_io_voltage;//IO Voltage 0---3.3v; 1----1.8v
 unsigned char uc_panel_factory_id;//TP panel factory ID

 unsigned char buf[FTS_SETTING_BUF_LEN];
 FTS_BYTE reg_val[2] = {0};
 FTS_BYTE auc_i2c_write_buf[10];
 FTS_BYTE packet_buf[FTS_SETTING_BUF_LEN + 6];
 FTS_DWRD i = 0;
 int i_ret;

 uc_i2c_addr = 0x70;
 uc_io_voltage = 0x0;
 uc_panel_factory_id = 0x5a;

 /*********Step 1:Reset  CTPM *****/
 /*write 0xaa to register 0xfc*/
 ft5x0x_write_reg(0xfc,0xaa);
 delay_qt_ms(50);
 /*write 0x55 to register 0xfc*/
 ft5x0x_write_reg(0xfc,0x55);
 printk("[FTS] Step 1: Reset CTPM test\n");

 delay_qt_ms(30);

 /*********Step 2:Enter upgrade mode *****/
 auc_i2c_write_buf[0] = 0x55;
 auc_i2c_write_buf[1] = 0xaa;
 do {
  i ++;
  i_ret = ft5x0x_i2c_txdata(auc_i2c_write_buf, 2);
  delay_qt_ms(5);
 }while(i_ret <= 0 && i < 5 );

 /*********Step 3:check READ-ID***********************/
 cmd_write(0x90,0x00,0x00,0x00,4);
 byte_read(reg_val,2);
 if (reg_val[0] == 0x79 && reg_val[1] == 0x3) {
  TS_DEBUG("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]);
 } else {
  return ERR_READID;
 }

 cmd_write(0xcd,0x0,0x00,0x00,1);
 byte_read(reg_val,1);
 TS_DEBUG("bootloader version = 0x%x\n", reg_val[0]);

 /* --------- read current project setting  ---------- */
 //set read start address
 buf[0] = 0x3;
 buf[1] = 0x0;
 buf[2] = 0x78;
 buf[3] = 0x0;
 byte_write(buf, 4);
 byte_read(buf, FTS_SETTING_BUF_LEN);

 TS_DEBUG("[FTS] old setting: uc_i2c_addr = 0x%x, uc_io_voltage = %d, uc_panel_factory_id = 0x%x\n",
   buf[0], buf[2], buf[4]);
 for (i = 0; i < FTS_SETTING_BUF_LEN; i++)
 {
  if (i % 16 == 0) printk("\n");
  printk("0x%x, ", buf[i]);
 }
 printk("\n");

 /*--------- Step 4:erase project setting --------------*/
 cmd_write(0x62,0x00,0x00,0x00,1);
 delay_qt_ms(100);
 /*----------  Set new settings ------------------------*/
 buf[0] = uc_i2c_addr;
 buf[1] = ~uc_i2c_addr;
 buf[2] = uc_io_voltage;
 buf[3] = ~uc_io_voltage;
 buf[4] = uc_panel_factory_id;
 buf[5] = ~uc_panel_factory_id;
 packet_buf[0] = 0xbf;
 packet_buf[1] = 0x00;
 packet_buf[2] = 0x78;
 packet_buf[3] = 0x0;
 packet_buf[4] = 0;
 packet_buf[5] = FTS_SETTING_BUF_LEN;
 for (i = 0; i < FTS_SETTING_BUF_LEN; i++)
 {
  packet_buf[6 + i] = buf[i];
  if (i % 16 == 0) TS_DEBUG("\n");
  TS_DEBUG("0x%x, ", buf[i]);
 }
 TS_DEBUG("\n");
 byte_write(&packet_buf[0],FTS_SETTING_BUF_LEN + 6);
 delay_qt_ms(100);
 /********* reset the new FW**************************/
 cmd_write(0x07,0x00,0x00,0x00,1);
 msleep(200);

 return 0;
}

int fts_ctpm_auto_upg(void)
{
 unsigned char uc_host_fm_ver;
 unsigned char uc_tp_fm_ver;
 int i_ret;

 uc_tp_fm_ver = ft5x0x_read_fw_ver();
 uc_host_fm_ver = fts_ctpm_get_i_file_ver();
 if ( uc_tp_fm_ver == 0xa6 || //the firmware in touch panel maybe corrupted
   uc_tp_fm_ver < uc_host_fm_ver//the firmware in host flash is new, need upgrade
 ) {
  msleep(100);
  TS_DEBUG("[FTS] uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x\n", uc_tp_fm_ver, uc_host_fm_ver);
  i_ret = fts_ctpm_fw_upgrade_with_i_file();
  if (i_ret == 0) {
   msleep(300);
   uc_host_fm_ver = fts_ctpm_get_i_file_ver();
   TS_DEBUG("[FTS] upgrade to new version 0x%x\n", uc_host_fm_ver);
  } else {
   TS_DEBUG("[FTS] upgrade failed ret=%d.\n", i_ret);
  }
 }
 return 0;
}

#endif

/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static void ft5x0x_ts_release(void) {
 struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
#ifdef CONFIG_FT5X0X_MULTITOUCH
 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
#else
 input_report_abs(data->input_dev, ABS_PRESSURE, 0);
#endif
 input_sync(data->input_dev);
}

//read touch point information
static int ft5x0x_read_data(void) {
 struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
 struct ts_event *event = &data->event;
 u8 buf[CFG_POINT_READ_BUF] = { 0 };
 int ret = -1;
 int i;

 ret = ft5x0x_i2c_rxdata(buf, CFG_POINT_READ_BUF);
 if (ret < 0) {
  TS_DEBUG("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
  return ret;
 }

 memset(event, 0, sizeof(struct ts_event));
 event->touch_point = buf[2] & 0x07;

 if (event->touch_point == 0) {
  ft5x0x_ts_release();
  return -1;
 }

 if (event->touch_point > CFG_MAX_TOUCH_POINTS) {
  event->touch_point = CFG_MAX_TOUCH_POINTS;
 }

 for (i = 0; i < event->touch_point; i++) {
  event->au8_touch_event[i] = buf[3 + 6 * i] >> 6;
  event->au16_x[i] = (s16) (buf[3 + 6 * i] & 0x0F) << 8
    | (s16) buf[4 + 6 * i];
  event->au8_finger_id[i] = (buf[5 + 6 * i]) >> 4;
  event->au16_y[i] = (s16) (buf[5 + 6 * i] & 0x0F) << 8
    | (s16) buf[6 + 6 * i];
  event->au16_y[i] = SCREEN_MAX_Y - event->au16_y[i]; // switch y
  TS_DEBUG("event:%d,x:%d,y:%d,finger id:%d\n", event->au8_touch_event[i],
    event->au16_x[i], event->au16_y[i], event->au8_finger_id[i]);
 }

 event->pressure = 200;

 return 0;
}
#ifdef CONFIG_TOUCH_VKBD
#define STARTY 240
void ft5x0x_touch_init_key_postion(void)
{
 int i;
 for (i=0;i<CFG_NUMOFKEYS;i++)
 {
  keyboard.keys[i].lx=i*(480/14);
  keyboard.keys[i].ly=STARTY+(i%28)*16;
  keyboard.keys[i].rx=(i+1)*(480/14);
  keyboard.keys[i].ry=STARTY+(i%28)*16+16;
 }
}
int ft5x0x_touch_report_key(struct input_dev *dev,int x,int y,int touch_event)
{
 int i;
 for (i=0;i<CFG_NUMOFKEYS;i++)
 {
  if (keyboard.keys[i].key_status==KEY_PRESS)
  {
   input_report_key(dev,((int*)dev->keycode)[i],0);
   keyboard.keys[i].key_status=KEY_RELEASE;
   TS_DEBUG("report key %s released:%d \n",keyboard.keys[i].key_name,((int*)dev->keycode)[i]);
  }
  if ((x>=keyboard.keys[i].lx)&&(x<=keyboard.keys[i].rx)&&
    (y>=keyboard.keys[i].ly)&&(y<=keyboard.keys[i].ry))
  {
   if (touch_event==0)
   {
    input_report_key(dev,((int*)dev->keycode)[i],1);
    keyboard.keys[i].key_status=KEY_PRESS;
    TS_DEBUG("report key %s pressed:%d \n",keyboard.keys[i].key_name,((int*)dev->keycode)[i]);
   }
  }
 }
 return 0;
}
#endif
/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static void ft5x0x_report_value(void) {
 struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
 struct ts_event *event = &data->event;
 int i, uppoint, MaxY;
 uppoint = 0;
#ifdef CONFIG_TOUCH_VKBD
 if ( keyboard.active)
 MaxY=SCREEN_Y;
 else
 MaxY=SCREEN_MAX_Y;
#endif
 for (i = 0; i < event->touch_point; i++) {
  if ((event->au16_x[i] < SCREEN_MAX_X) && (event->au16_y[i] < MaxY)) {
   // LCD view area
   //TS_DEBUG("event->au16_x[i]=%d,event->au16_y[i]=%d\n",event->au16_x[i],event->au16_y[i]);
#ifdef CONFIG_FT5X0X_MULTITOUCH
   input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
   input_report_abs(data->input_dev, ABS_MT_PRESSURE, event->pressure);
   input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);
   input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->au16_y[i]);
   input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,event->au8_finger_id[i]);
#else
   input_report_abs(data->input_dev, ABS_X, event->au16_x[i]);
   input_report_abs(data->input_dev, ABS_Y, event->au16_y[i]);
   input_report_abs(data->input_dev, ABS_PRESSURE, event->pressure);
#endif
   input_report_key(data->input_dev, BTN_TOUCH, 1); //所有手指都抬起了 发送BTN_TOUCH 抬起事件
  }
#ifdef CONFIG_TOUCH_VKBD
  else {
   TS_DEBUG("report key:x=%d,y=%d\n",event->au16_x[i],event->au16_y[i]);
   ft5x0x_touch_report_key(data->input_dev,event->au16_x[i],event->au16_y[i],event->au8_touch_event[i]);
   input_report_key(data->input_dev, BTN_TOUCH, 1); //所有手指都抬起了 发送BTN_TOUCH 抬起事件
  }
#endif
 }
// if (event->touch_point == uppoint) {
//  input_report_key(data->input_dev, BTN_TOUCH, 0); //所有手指都抬起了 发送BTN_TOUCH 抬起事件
// } else {
//    input_report_key(data->input_dev, BTN_TOUCH, event->touch_point > 0); //还有手指没抬起,发送BTN_TOUCH 按下的事件
// }
 input_sync(data->input_dev);
}

/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static void ft5x0x_ts_pen_irq_work(struct work_struct *work) {
 int ret = -1;

 ret = ft5x0x_read_data();
 if (ret == 0) {
  ft5x0x_report_value();
 }

}
/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) {
 struct ft5x0x_ts_data *ft5x0x_ts = (struct ft5x0x_ts_data*) dev_id;

 if (!work_pending(&ft5x0x_ts->pen_event_work)) {
  queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
 }

 return IRQ_HANDLED;
}

static int ft5x06_ts_reset(struct i2c_client *client, int reset_pin) {
 int error;

 if (gpio_is_valid(reset_pin)) {
  /* this pulls reset down, enabling the low active reset */
  error = gpio_request_one(reset_pin, GPIOF_OUT_INIT_HIGH,
    "edt-ft5x06 reset");
  if (error) {
   dev_err(&client->dev,
     "Failed to request GPIO %d as reset pin, error %d\n",
     reset_pin, error);
   return error;
  }
  gpio_set_value(reset_pin, 1);
  mdelay(100);
  gpio_set_value(reset_pin, 0);
  mdelay(200);
  gpio_set_value(reset_pin, 1);
 }

 return 0;
}

#ifdef CONFIG_TOUCH_VKBD

static int data_to_kernel(struct sock *sk, int cmd, void *user,
  unsigned int len)
{
 switch(cmd)
 {
  case IMP1_SET:
  {
   char umsg[4];
   memset(umsg, 0, sizeof(char)*1);
   copy_from_user(umsg, user, sizeof(char)*1);
   switch(umsg[0])
   {
    case 0:
    keyboard.active=0;
    break;
    case 1:
    keyboard.active=1;
    break;
    case 3:
    keyboard.currentpage=0;
    break;
    case 4:
    keyboard.currentpage=1;
    break;
   }
   break;
  }
  return 0;
 }

 static int data_from_kernel(struct sock *sk, int cmd, void *user, int *len)
 {
  switch(cmd)
  {
   case IMP1_GET:
   {
    copy_to_user(user, (char*)&keyboard, 2); //retrun active status and current page
   }
   break;
  }
  return 0;
 }

 static struct nf_sockopt_ops imp1_sockops =
 {
  .pf = PF_INET,
  .set_optmin = IMP1_SET,
  .set_optmax = IMP1_MAX,
  .set = data_to_kernel,
  .get_optmin = IMP1_GET,
  .get_optmax = IMP1_MAX,
  .get = data_from_kernel,
 };

 static int init_sockopt(void)
 {
  return nf_register_sockopt(&imp1_sockops);
 }

 static void exit_sockopt(void)
 {
  nf_unregister_sockopt(&imp1_sockops);
 }

#endif

/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/
static int ft5x0x_ts_probe(struct i2c_client *client,
  const struct i2c_device_id *id) {
 const struct edt_ft5x06_platform_data *pdata = client->dev.platform_data;
 struct ft5x0x_ts_data *ft5x0x_ts;
 struct input_dev *input_dev;
 int err = 0;
 unsigned char i, uc_reg_value;

 dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");

 if (!pdata) {
  dev_err(&client->dev, "no platform data?\n");
  return -EINVAL;
 }

 err = ft5x06_ts_reset(client, pdata->reset_pin);
 if (err)
  return err;

 if (gpio_is_valid(pdata->irq_pin)) {
  //#if 0 //GPIO interrupt
  err = gpio_request_one(pdata->irq_pin,
  GPIOF_IN, "edt-ft5x06 irq");
  if (err) {
   dev_err(&client->dev, "Failed to request GPIO %d, error %d\n",
     pdata->irq_pin, err);
   return err;
  }
// #else
//  nuc970_mfp_set_port_i(1, 0xF); //INT6
//  nuc970_mfp_set_port_i(2, 0xF); //INT7
// #endif
  client->irq = gpio_to_irq(pdata->irq_pin);
 }

 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  err = -ENODEV;
  goto exit_check_functionality_failed;
 }

 //TS_DEBUG("==kzalloc=\n");
 ft5x0x_ts = kzalloc(sizeof(struct ft5x0x_ts_data), GFP_KERNEL);
 if (!ft5x0x_ts) {
  err = -ENOMEM;
  goto exit_alloc_data_failed;
 }

 INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);

 ft5x0x_ts->ts_workqueue = create_singlethread_workqueue(
   dev_name(&client->dev));
 if (!ft5x0x_ts->ts_workqueue) {
  err = -ESRCH;
  goto exit_create_singlethread;
 }

 err = request_irq(client->irq, ft5x0x_ts_interrupt,
 IRQF_ONESHOT | IRQF_TRIGGER_FALLING, "ft5x0x_ts", ft5x0x_ts);
 if (err < 0) {
  dev_err(&client->dev, "client->irq: %d", client->irq);
  dev_err(&client->dev, "ft5x0x_probe: request irq failed\n");
  goto exit_irq_request_failed;
 }
 disable_irq(client->irq);
 //TS_DEBUG("==input_allocate_device=\n");
 input_dev = input_allocate_device();
 if (!input_dev) {
  err = -ENOMEM;
  dev_err(&client->dev, "failed to allocate input device\n");
  goto exit_input_dev_alloc_failed;
 }

 input_dev->name = "FT5x16 TouchScreen";
 input_dev->id.bustype = BUS_I2C;
 input_dev->phys = "input/event0";

 ft5x0x_ts->input_dev = input_dev;

 input_dev->name = FT5X0X_NAME;
 input_dev->id.bustype = BUS_I2C;
 input_dev->dev.parent = &client->dev;

#ifdef CONFIG_FT5X0X_MULTITOUCH 
 set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
 set_bit(ABS_MT_POSITION_X, input_dev->absbit);
 set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
 set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);

 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, PRESS_MAX, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 5, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X-1, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y-1, 0, 0);
 set_bit(BTN_TOUCH, input_dev->keybit);
#else
 set_bit(ABS_X, input_dev->absbit);
 set_bit(ABS_Y, input_dev->absbit);
 set_bit(ABS_PRESSURE, input_dev->absbit);
 set_bit(BTN_TOUCH, input_dev->keybit);
 input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
 input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
 input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0, 0);
#endif
 set_bit(EV_ABS, input_dev->evbit);
 set_bit(EV_KEY, input_dev->evbit);
#ifdef CONFIG_TOUCH_VKBD
 dev_info(&client->dev,"Virtual keyboard initialized.\n");
 ft5x0x_touch_init_key_postion();
 set_bit(EV_SYN, input_dev->evbit);
 input_dev->keycode=ts_keycode;
 for (i=0;i<CFG_NUMOFKEYS;i++)
 {
  input_set_capability(input_dev,EV_KEY,((int*)input_dev->keycode)[i]);
 }
#endif
 err = input_register_device(input_dev);
 if (err) {
  dev_err(&client->dev,
    "ft5x0x_ts_probe: failed to register input device: %s\n",
    dev_name(&client->dev));
  goto exit_input_register_device_failed;
 }
 msleep(150);
 //TS_DEBUG("==i2c_set_clientdata=\n");
 this_client = client;
 i2c_set_clientdata(client, ft5x0x_ts);

 //get some register information
 uc_reg_value = ft5x0x_read_fw_ver();
 TS_DEBUG("[FTS] Firmware version = 0x%x\n", uc_reg_value);
 ft5x0x_read_reg(FT5X0X_REG_PERIODACTIVE, &uc_reg_value);
 TS_DEBUG("[FTS] report rate is %dHz.\n", uc_reg_value * 10);
 ft5x0x_read_reg(FT5X0X_REG_THGROUP, &uc_reg_value);
 TS_DEBUG("[FTS] touch threshold is %d.\n", uc_reg_value * 4);
 enable_irq(client->irq);
#ifdef CONFIG_TOUCH_VKBD
 init_sockopt();
#endif
 dev_info(&client->dev,
   "Screen size: %dX%d initialized:  IRQ pin %d ==> %d, Reset pin %d.\n",
   SCREEN_MAX_X, SCREEN_MAX_Y, pdata->irq_pin, client->irq,
   pdata->reset_pin);

 return 0;

 exit_input_register_device_failed: input_free_device(input_dev);
 exit_input_dev_alloc_failed: free_irq(client->irq, ft5x0x_ts);
 exit_irq_request_failed: cancel_work_sync(&ft5x0x_ts->pen_event_work);
 destroy_workqueue(ft5x0x_ts->ts_workqueue);
 exit_create_singlethread: i2c_set_clientdata(client, NULL);
 kfree(ft5x0x_ts);
 exit_alloc_data_failed: exit_check_functionality_failed: if (gpio_is_valid(
   pdata->irq_pin))
  gpio_free(pdata->irq_pin);
 return err;
}

/***********************************************************************************************
 Name :

 Input :


 Output :

 function :

 ***********************************************************************************************/

static int ft5x0x_ts_remove(struct i2c_client *client) {
 const struct edt_ft5x06_platform_data *pdata = dev_get_platdata(
   &client->dev);
 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);

 input_unregister_device(ft5x0x_ts->input_dev);
 destroy_workqueue(ft5x0x_ts->ts_workqueue);
 free_irq(client->irq, ft5x0x_ts);

 i2c_set_clientdata(client, NULL);
 i2c_set_clientdata(this_client, NULL); //Add by EasyWave 20130402
 if (gpio_is_valid(pdata->irq_pin))
  gpio_free(pdata->irq_pin);
 if (gpio_is_valid(pdata->reset_pin))
  gpio_free(pdata->reset_pin);

 kfree(ft5x0x_ts);
#ifdef CONFIG_TOUCH_VKBD
 exit_sockopt();
#endif
 return 0;
}

static const struct i2c_device_id ft5x0x_ts_id[] =
  { { FT5X0X_NAME, 0x38 }, { } };

MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);

static struct i2c_driver ft5x0x_ts_driver = { .probe = ft5x0x_ts_probe,
  .remove = ft5x0x_ts_remove, .id_table = ft5x0x_ts_id, .driver = {
    .name = FT5X0X_NAME, .owner = THIS_MODULE, }, };

module_i2c_driver( ft5x0x_ts_driver);



下面是h文件

#ifndef __LINUX_FT5X0X_TS_H__
#define __LINUX_FT5X0X_TS_H__

#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,17)

#define WORK_STRUCT_PENDING    0  /*  if work item pending execution */
#define work_data_bits(work)   ((unsigned long *)(&(work)->pending))
/**
 * work_pending - Find out whether a work item is currently pending
 * @work: The work item in question
 */
#define work_pending(work) \
 test_bit(WORK_STRUCT_PENDING, work_data_bits(work))

#endif

/* -- dirver configure -- */
#define CFG_SUPPORT_AUTO_UPG   0
#define CFG_SUPPORT_UPDATE_PROJECT_SETTING 0
//#define CFG_SUPPORT_TOUCH_KEY     1    //touch key, HOME, SEARCH, RETURN etc
#ifdef CONFIG_FT5X0X_MULTITOUCH
#define CFG_MAX_TOUCH_POINTS   5 //2
#else
#define CFG_MAX_TOUCH_POINTS   1 //2
#endif

#define CFG_FTS_CTP_DRIVER_VERSION "2.0"

#define SCREEN_MAX_X    480
#ifdef CONFIG_TOUCH_VKBD
#define SCREEN_Y     (272-32)
#endif

#define SCREEN_MAX_Y     272
#define PRESS_MAX    255

#define CFG_POINT_READ_BUF   (3 + 6 * (CFG_MAX_TOUCH_POINTS))

#define FT5X0X_NAME    "ft5x0x_ts"

#define KEY_PRESS    1
#define KEY_RELEASE    0

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

#ifndef ABS_MT_TOUCH_MAJOR
 #define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */
 #define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */
 #define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */
 #define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */
 #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
 #define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
 #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
 #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
 #define ABS_MT_BLOB_ID  0x38 /* Group set of pkts as blob */
#endif /* ABS_MT_TOUCH_MAJOR */

#ifndef ABS_MT_TRACKING_ID
 #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#endif

#ifdef CONFIG_TOUCH_VKBD

#define IMP1_OPS_BASIC 128
#define IMP1_SET IMP1_OPS_BASIC
#define IMP1_GET IMP1_OPS_BASIC
#define IMP1_MAX IMP1_OPS_BASIC+1

#define CFG_NUMOFKEYS  28
#define KEY_RELEASE 0
#define KEY_PRESS 1
struct Keys
{
 char key_name[20];
 int key_status;
 int lx,ly,rx,ry;
};

struct Keyboard
{
 unsigned char active;
 unsigned char currentpage;
 struct Keys keys[CFG_NUMOFKEYS];
};

#endif

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值