From 9d40ac5867b9aefe0722bc1f110b965ff294d30d Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 15 Nov 2014 10:00:36 +0800 Subject: add via modify part source code for wm8880 4.4 kitkat --- .../input/touchscreen/cyp140_ts/cyp140_i2c.c | 1412 ++++++++++++++++++++ 1 file changed, 1412 insertions(+) create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c (limited to 'ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c') diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c b/ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c new file mode 100755 index 00000000..ca4717ac --- /dev/null +++ b/ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c @@ -0,0 +1,1412 @@ +/* drivers/input/touchscreen/cyp140_i2c.c + * 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. + * ZEITEC Semiconductor Co., Ltd + * Tel: +886-3-579-0045 + * Fax: +886-3-579-9960 + * http://www.zeitecsemi.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "wmt_ts.h" +#define TP_POINTS_CNT 5 +#define U8 unsigned char +//fw update. +//#include "cyp140_fw.h" + +//****************************add for cyp140 2013-1-6 +//extern struct tpd_device *tpd; +static struct i2c_client *i2c_client = NULL; +static struct task_struct *thread = NULL; + +static DECLARE_WAIT_QUEUE_HEAD(waiter); + +#define TPD_DEVICE "cyp140" +static int tpd_load_status = 0;//add !!!2013-1-6 +//static struct early_suspend early_suspend; + +#ifdef CONFIG_HAS_EARLYSUSPEND +static struct early_suspend early_suspend; +static void tpd_early_suspend(struct early_suspend *handler); +static void tpd_late_resume(struct early_suspend *handler); +#endif + +static int tilt = 1, rev_x = -1, rev_y = 1; +static int max_x = 1024, max_y = 600; +//static int max_x = 800, max_y = 480; + +//extern void mt65xx_eint_unmask(unsigned int line); +//extern void mt65xx_eint_mask(unsigned int line); +//extern void mt65xx_eint_set_hw_debounce(kal_uint8 eintno, kal_uint32 ms); +//extern kal_uint32 mt65xx_eint_set_sens(kal_uint8 eintno, kal_bool sens); +//extern mt65xx_eint_set_polarity(unsigned int eint_num, unsigned int pol); +//extern void mt65xx_eint_registration(kal_uint8 eintno, kal_bool Dbounce_En, + // kal_bool ACT_Polarity, void (EINT_FUNC_PTR)(void), + // kal_bool auto_umask); + + +static irqreturn_t tpd_eint_interrupt_handler(int irq, void *dev_id); +//static int tpd_get_bl_info(int show); +static int __devinit tpd_probe(struct i2c_client *client); +//static int tpd_detect(struct i2c_client *client, int kind, struct i2c_board_info *info); +//static int __devexit tpd_remove(struct i2c_client *client); +static int touch_event_handler(void *unused); +//static int tpd_initialize(struct i2c_client * client); + + +volatile static int tpd_flag = 0;//0; debug 2013-5-6 + +#ifdef TPD_HAVE_BUTTON +static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS; +static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM; +#endif + +#define TPD_OK 0 +//#define TPD_EREA_Y 799 +//#define TPD_EREA_X 479 +#define TPD_EREA_Y 479 +#define TPD_EREA_X 319 + +#define TPD_DISTANCE_LIMIT 100 + +#define TPD_REG_BASE 0x00 +#define TPD_SOFT_RESET_MODE 0x01 +#define TPD_OP_MODE 0x00 +#define TPD_LOW_PWR_MODE 0x04 +#define TPD_SYSINFO_MODE 0x10 +#define GET_HSTMODE(reg) ((reg & 0x70) >> 4) // in op mode or not +#define GET_BOOTLOADERMODE(reg) ((reg & 0x10) >> 4) // in bl mode +//#define GPIO_CTP_EN_PIN_M_GPIO 0 +//#define GPIO_CTP_EN_PIN 0xff + +static u8 bl_cmd[] = { + 0x00, 0x00, 0xFF, 0xA5, + 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, + 0x06, 0x07}; +//exit bl mode +struct tpd_operation_data_t{ + U8 hst_mode; + U8 tt_mode; + U8 tt_stat; + + U8 x1_M,x1_L; + U8 y1_M,y1_L; + U8 x5_M; + U8 touch12_id; + + U8 x2_M,x2_L; + U8 y2_M,y2_L; + U8 x5_L; + U8 gest_cnt; + U8 gest_id; + //U8 gest_set; + + + U8 x3_M,x3_L; + U8 y3_M,y3_L; + U8 y5_M; + U8 touch34_id; + + U8 x4_M,x4_L; + U8 y4_M,y4_L; + U8 y5_L; + + //U8 x5_M,x5_L; + U8 Undefinei1B; + U8 Undefined1C; + U8 Undefined1D; + U8 GEST_SET; + U8 touch5_id; +}; + +struct tpd_bootloader_data_t{ + U8 bl_file; + U8 bl_status; + U8 bl_error; + U8 blver_hi,blver_lo; + U8 bld_blver_hi,bld_blver_lo; + + U8 ttspver_hi,ttspver_lo; + U8 appid_hi,appid_lo; + U8 appver_hi,appver_lo; + + U8 cid_0; + U8 cid_1; + U8 cid_2; + +}; + +struct tpd_sysinfo_data_t{ + U8 hst_mode; + U8 mfg_cmd; + U8 mfg_stat; + U8 cid[3]; + u8 tt_undef1; + + u8 uid[8]; + U8 bl_verh; + U8 bl_verl; + + u8 tts_verh; + u8 tts_verl; + + U8 app_idh; + U8 app_idl; + U8 app_verh; + U8 app_verl; + + u8 tt_undef2[6]; + U8 act_intrvl; + U8 tch_tmout; + U8 lp_intrvl; + +}; + +struct touch_info { + int x[5]; + int y[5]; + int p[5]; + int id[5]; + int count; +}; + +struct id_info{ + int pid1; + int pid2; + int reportid1; + int reportid2; + int id1; + int id2; + +}; +static struct tpd_operation_data_t g_operation_data; +//static struct tpd_bootloader_data_t g_bootloader_data; +//static struct tpd_sysinfo_data_t g_sysinfo_data; + +//******************************************************** + +/* -------------- global variable definition -----------*/ +#define _MACH_MSM_TOUCH_H_ + +#define ZET_TS_ID_NAME "cyp140-ts" + +#define MJ5_TS_NAME "cyp140_touchscreen" + +//#define TS_INT_GPIO S3C64XX_GPN(9) /*s3c6410*/ +//#define TS1_INT_GPIO AT91_PIN_PB17 /*AT91SAM9G45 external*/ +//#define TS1_INT_GPIO AT91_PIN_PA27 /*AT91SAM9G45 internal*/ +//#define TS_RST_GPIO S3C64XX_GPN(10) + +#define TS_RST_GPIO +#define TPINFO 1 +#define X_MAX 800 //1024 +#define Y_MAX 480 //576 +#define FINGER_NUMBER 5 +#define KEY_NUMBER 3 //0 +#define P_MAX 1 +#define D_POLLING_TIME 25000 +#define U_POLLING_TIME 25000 +#define S_POLLING_TIME 100 +#define REPORT_POLLING_TIME 5 + +#define MAX_KEY_NUMBER 8 +#define MAX_FINGER_NUMBER 16 +#define TRUE 1 +#define FALSE 0 + +//#define debug_mode 1 +//#define DPRINTK(fmt,args...) do { if (debug_mode) printk(KERN_EMERG "[%s][%d] "fmt"\n", __FUNCTION__, __LINE__, ##args);} while(0) + +//#define TRANSLATE_ENABLE 1 +#define TOPRIGHT 0 +#define TOPLEFT 1 +#define BOTTOMRIGHT 2 +#define BOTTOMLEFT 3 +#define ORIGIN BOTTOMRIGHT + +#define TIME_CHECK_CHARGE 3000 + +struct msm_ts_platform_data { + unsigned int x_max; + unsigned int y_max; + unsigned int pressure_max; +}; + +struct tpd_device{ + struct i2c_client * client;//i2c_ts; + struct work_struct work1; + struct input_dev *input; + struct timer_list polling_timer; + struct delayed_work work; // for polling + struct workqueue_struct *queue; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + unsigned int gpio; /* GPIO used for interrupt of TS1*/ + unsigned int irq; + unsigned int x_max; + unsigned int y_max; + unsigned int pressure_max; +}; +// +struct tpd_device *tpd; + + +//static int l_suspend = 0; // 1:suspend, 0:normal state + +//static int resetCount = 0; //albert++ 20120807 + + +//static u16 polling_time = S_POLLING_TIME; + +//static int l_powermode = -1; +//static struct mutex i2c_mutex; + + +//static int __devinit cyp140_ts_probe(struct i2c_client *client, const struct i2c_device_id *id); +//static int __devexit cyp140_ts_remove(struct i2c_client *dev); + + + + + +//static int filterCount = 0; +//static u32 filterX[MAX_FINGER_NUMBER][2], filterY[MAX_FINGER_NUMBER][2]; + +//static u8 key_menu_pressed = 0x1; +//static u8 key_back_pressed = 0x1; +//static u8 key_search_pressed = 0x1; + +//static u16 ResolutionX=X_MAX; +//static u16 ResolutionY=Y_MAX; +//static u16 FingerNum=0; +//static u16 KeyNum=0; +//static int bufLength=0; +//static u8 xyExchange=0; +//static u16 inChargerMode = 0; +//static struct i2c_client *this_client; +struct workqueue_struct *ts_wq = NULL; +#if 0 +static int l_tskey[4][2] = { + {KEY_BACK,0}, + {KEY_MENU,0}, + {KEY_HOME,0}, + {KEY_SEARCH,0}, +}; +#endif +u8 pc[8]; +// {IC Model, FW Version, FW version,Codebase Type=0x08, Customer ID, Project ID, Config Board No, Config Serial No} + +//Touch Screen +/*static const struct i2c_device_id cyp140_ts_idtable[] = { + { ZET_TS_ID_NAME, 0 }, + { } +}; + +static struct i2c_driver cyp140_ts_driver = { + .driver = { + .owner = THIS_MODULE, + .name = ZET_TS_ID_NAME, + }, + .probe = cyp140_ts_probe, + .remove = __devexit_p(cyp140_ts_remove), + .id_table = cyp140_ts_idtable, +}; +*/ + + +/*********************************************************************** + [function]: + callback: Timer Function if there is no interrupt fuction; + [parameters]: + arg[in]: arguments; + [return]: + NULL; +************************************************************************/ + + +//extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num,int bus_id); +/*********************************************************************** + [function]: + callback: read data by i2c interface; + [parameters]: + client[in]: struct i2c_client — represent an I2C slave device; + data [out]: data buffer to read; + length[in]: data length to read; + [return]: + Returns negative errno, else the number of messages executed; +************************************************************************/ +int cyp140_i2c_read_tsdata(struct i2c_client *client, u8 *data, u8 length) +{ + struct i2c_msg msg; + msg.addr = client->addr; + msg.flags = I2C_M_RD; + msg.len = length; + msg.buf = data; + return i2c_transfer(client->adapter,&msg, 1); + + /*int rc = 0; + + memset(data, 0, length); + rc = i2c_master_recv(client, data, length); + if (rc <= 0) + { + errlog("error!\n"); + return -EINVAL; + } else if (rc != length) + { + dbg("want:%d,real:%d\n", length, rc); + } + return rc;*/ +} + +/*********************************************************************** + [function]: + callback: write data by i2c interface; + [parameters]: + client[in]: struct i2c_client — represent an I2C slave device; + data [out]: data buffer to write; + length[in]: data length to write; + [return]: + Returns negative errno, else the number of messages executed; +************************************************************************/ +int cyp140_i2c_write_tsdata(struct i2c_client *client, u8 *data, u8 length) +{ + struct i2c_msg msg; + msg.addr = client->addr; + msg.flags = 0; + msg.len = length; + msg.buf = data; + return i2c_transfer(client->adapter,&msg, 1); + + /*int ret = i2c_master_recv(client, data, length); + if (ret <= 0) + { + errlog("error!\n"); + } + return ret; + */ +} + +/*********************************************************************** + [function]: + callback: coordinate traslating; + [parameters]: + px[out]: value of X axis; + py[out]: value of Y axis; + p [in]: pressed of released status of fingers; + [return]: + NULL; +************************************************************************/ +void touch_coordinate_traslating(u32 *px, u32 *py, u8 p) +{ + int i; + u8 pressure; + + #if ORIGIN == TOPRIGHT + for(i=0;i> (MAX_FINGER_NUMBER-i-1)) & 0x1; + if(pressure) + { + px[i] = X_MAX - px[i]; + } + } + #elif ORIGIN == BOTTOMRIGHT + for(i=0;i> (MAX_FINGER_NUMBER-i-1)) & 0x1; + if(pressure) + { + px[i] = X_MAX - px[i]; + py[i] = Y_MAX - py[i]; + } + } + #elif ORIGIN == BOTTOMLEFT + for(i=0;i> (MAX_FINGER_NUMBER-i-1)) & 0x1; + if(pressure) + { + py[i] = Y_MAX - py[i]; + } + } + #endif +} + +/*********************************************************************** + [function]: + callback: reset function; + [parameters]: + void; + [return]: + void; +************************************************************************/ +void ctp_reset(void) +{ +#if defined(TS_RST_GPIO) + //reset mcu + /* gpio_direction_output(TS_RST_GPIO, 1); + msleep(1); + gpio_direction_output(TS_RST_GPIO, 0); + msleep(10); + gpio_direction_output(TS_RST_GPIO, 1); + msleep(20);*/ + wmt_rst_output(1); + msleep(1); + wmt_rst_output(0); + msleep(10); + wmt_rst_output(1); + msleep(20); + dbg("has done\n"); +#else + u8 ts_reset_cmd[1] = {0xb0}; + cyp140_i2c_write_tsdata(this_client, ts_reset_cmd, 1); +#endif + +} + +//************************************************* +#if 1 +#include //wake_up_process() +#include //kthread_create()、kthread_run() +//#include //IS_ERR()、PTR_ERR() + +void cyttsp_sw_reset(void); +//static struct task_struct *esd_task; +volatile bool need_rst_flag = 0; +volatile int tp_interrupt_flag = 0; +volatile int tp_suspend_flag = 0; +volatile int tp_reseting_flag = 0; + +void cyttsp_print_reg(struct i2c_client *client) +{ +#if 1 + char buffer[20]; + int status=0; + int i; + + status = i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 16, &(buffer[0])); + + printk("++++cyttsp_print_reg=%d: ",status); + for(i = 0; i<16;i++) + printk(" %02x", buffer[i]); + printk("\n"); +#endif + +} + +int exit_boot_mode(void) +{ + + //int retval = TPD_OK; + + char buffer[2]; + int status=0; + status = i2c_smbus_read_i2c_block_data(i2c_client, 0x01, 1, &(buffer[0])); + if(status<0) { + printk ("++++exit_boot_mode failed---1\n"); + return status; + } + else + { + if(buffer[0] & 0x10) + { + status = i2c_master_send(i2c_client, bl_cmd, 12); + if( status < 0) + { + printk ("++++exit_boot_mode failed---2\n"); + return status; + } + else + { + //printk("++++exit_boot_mode ok\n"); + } + msleep(300); + status = i2c_smbus_read_i2c_block_data(i2c_client, 0x01, 1, &(buffer[0])); + if(status<0) { + printk ("++++exit_boot_mode set failed\n"); + return status; + } +// printk("++++exit_boot_mode set: 0x%x\n",buffer[0]); + cyttsp_print_reg(i2c_client); + } + else + { + // printk("++++exit_boot_mode-- not in bootmode\n"); + } + + } + return 0; + +} + +void esd_check(void) +{ + if(need_rst_flag) + { + if(tp_suspend_flag == 0) + { + printk("++++esd_check---rst\n"); + //mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); + tp_reseting_flag = 1; + cyttsp_sw_reset(); + tp_reseting_flag = 0; + //mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); + } + need_rst_flag = 0; + } +} +static int fp_count = 0; +#if 0 //close 2013-1-6 +void esd_thread(void) +{ + static int i = 0, j = 0; + while(1) + { + printk("++++esd_thread, need_rst_flag=%d, fp_count=%d\n", need_rst_flag,fp_count); + fp_count = 0; + if(need_rst_flag) + { + j = 0; + while(tp_interrupt_flag==1 && j<200) //wujinyou + { + j ++; + if(tp_suspend_flag) + msleep(1000); + else + msleep(10); + } + if(tp_suspend_flag == 0) + { + printk("++++esd_thread, start reset, mask int\n"); + //mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); + tp_reseting_flag = 1; + cyttsp_sw_reset(); + i = 0; + need_rst_flag = 0; + tp_reseting_flag = 0; + //mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); + } + } + msleep(1000); + i ++; + if(i == 10) + { + i = 0; + //cyttsp_sw_reset(); + //need_rst_flag = 1; + } + } +} +static int esd_init_thread(void) +{ + int err; + printk("++++%s, line %d----\n", __FUNCTION__, __LINE__); + + esd_task = kthread_create(esd_thread, NULL, "esd_task"); + + if(IS_ERR(esd_task)){ + printk("++++Unable to start kernel thread.\n"); + err = PTR_ERR(esd_task); + esd_task = NULL; + return err; + } + + wake_up_process(esd_task); + + return 0; + +} +#endif //close 2013-1-6 + +#endif + +static void tpd_down(int x, int y, int p) { + + + //printk("<<<<< 480) { + tpd_button(x, y, 1); + } + } +#endif + //*****here process x y coord and then report!!!! 2013-1-7 + +#if 1//0 + int tmp; + if (tilt) + { + tmp = x; + x = y; + y =tmp; + } + if (rev_x < 0) + x = max_x -x; + if (rev_y < 0) + y = max_y -y; + + +#endif + if (wmt_ts_get_lcdexchg()) { + int t; + t = x; + x = y; + y = max_x - t; + } + + //printk("<<<<<< transfer x,y (%d, %d)\n", x, y);//debug 2013-5-6 + + input_report_abs(tpd->input, ABS_PRESSURE,p); + input_report_key(tpd->input, BTN_TOUCH, 1); + //input_report_abs(tpd->input,ABS_MT_TRACKING_ID,i); + input_report_abs(tpd->input, ABS_MT_TOUCH_MAJOR, 1); + input_report_abs(tpd->input, ABS_MT_POSITION_X, x); + input_report_abs(tpd->input, ABS_MT_POSITION_Y, y); + ////TPD_DEBUG("Down x:%4d, y:%4d, p:%4d \n ", x, y, p); + input_mt_sync(tpd->input); + //TPD_DOWN_DEBUG_TRACK(x,y); + fp_count ++; +} + +static void tpd_up(int x, int y,int p) { + + input_report_abs(tpd->input, ABS_PRESSURE, 0); + input_report_key(tpd->input, BTN_TOUCH, 0); + // input_report_abs(tpd->input,ABS_MT_TRACKING_ID,i); + input_report_abs(tpd->input, ABS_MT_TOUCH_MAJOR, 0); + //input_report_abs(tpd->input, ABS_MT_POSITION_X, x); + //input_report_abs(tpd->input, ABS_MT_POSITION_Y, y); //!!!! + //TPD_DEBUG("Up x:%4d, y:%4d, p:%4d \n", x, y, 0); + input_mt_sync(tpd->input); + // TPD_UP_DEBUG_TRACK(x,y); +} +void test_retval(s32 ret) +{ +#if 1 + if(ret<0) + { + need_rst_flag = 1; + printk("++++test_retval=1-------\n"); + } +#endif +} +static int tpd_touchinfo(struct touch_info *cinfo, struct touch_info *pinfo) +{ + + s32 retval; + static u8 tt_mode; + //pinfo->count = cinfo->count; + u8 data0,data1; + + memcpy(pinfo, cinfo, sizeof(struct touch_info)); + memset(cinfo, 0, sizeof(struct touch_info)); +// printk("pinfo->count =%d\n",pinfo->count); + + retval = i2c_smbus_read_i2c_block_data(i2c_client, TPD_REG_BASE, 8, (u8 *)&g_operation_data); + retval += i2c_smbus_read_i2c_block_data(i2c_client, TPD_REG_BASE + 8, 8, (((u8 *)(&g_operation_data)) + 8)); + retval += i2c_smbus_read_i2c_block_data(i2c_client, TPD_REG_BASE + 16, 8, (((u8 *)(&g_operation_data)) + 16)); + retval += i2c_smbus_read_i2c_block_data(i2c_client, TPD_REG_BASE + 24, 8, (((u8 *)(&g_operation_data)) + 24)); + + + //cyttsp_print_reg(i2c_client); + ////TPD_DEBUG("received raw data from touch panel as following:\n"); + + /*("hst_mode = %02X, tt_mode = %02X, tt_stat = %02X\n", \ + g_operation_data.hst_mode,\ + g_operation_data.tt_mode,\ + g_operation_data.tt_stat); */ + + cinfo->count = (g_operation_data.tt_stat & 0x0f) ; //point count + + //TPD_DEBUG("cinfo->count =%d\n",cinfo->count); + + //TPD_DEBUG("Procss raw data...\n"); + + cinfo->x[0] = (( g_operation_data.x1_M << 8) | ( g_operation_data.x1_L)); //point 1 + cinfo->y[0] = (( g_operation_data.y1_M << 8) | ( g_operation_data.y1_L)); + cinfo->p[0] = 0;//g_operation_data.z1; + + //printk("Before: cinfo->x0 = %3d, cinfo->y0 = %3d, cinfo->p0 = %3d cinfo->id0 = %3d\n", cinfo->x[0] ,cinfo->y[0] ,cinfo->p[0], cinfo->id[0]); + if(cinfo->x[0] < 1) cinfo->x[0] = 1; + if(cinfo->y[0] < 1) cinfo->y[0] = 1; + cinfo->id[0] = ((g_operation_data.touch12_id & 0xf0) >>4) -1; + //printk("After: cinfo->x0 = %3d, cinfo->y0 = %3d, cinfo->p0 = %3d cinfo->id0 = %3d\n", cinfo->x[0] ,cinfo->y[0] ,cinfo->p[0], cinfo->id[0]); + + if(cinfo->count >1) + { + cinfo->x[1] = (( g_operation_data.x2_M << 8) | ( g_operation_data.x2_L)); //point 2 + cinfo->y[1] = (( g_operation_data.y2_M << 8) | ( g_operation_data.y2_L)); + cinfo->p[1] = 0;//g_operation_data.z2; + + //printk("before: cinfo->x2 = %3d, cinfo->y2 = %3d, cinfo->p2 = %3d\n", cinfo->x2, cinfo->y2, cinfo->p2); + if(cinfo->x[1] < 1) cinfo->x[1] = 1; + if(cinfo->y[1] < 1) cinfo->y[1] = 1; + cinfo->id[1] = ((g_operation_data.touch12_id & 0x0f)) -1; + //printk("After: cinfo->x[1] = %3d, cinfo->y[1] = %3d, cinfo->p[1] = %3d, cinfo->id[1] = %3d\n", cinfo->x[1], cinfo->y[1], cinfo->p[1], cinfo->id[1]); + + if (cinfo->count > 2) + { + cinfo->x[2]= (( g_operation_data.x3_M << 8) | ( g_operation_data.x3_L)); //point 3 + cinfo->y[2] = (( g_operation_data.y3_M << 8) | ( g_operation_data.y3_L)); + cinfo->p[2] = 0;//g_operation_data.z3; + cinfo->id[2] = ((g_operation_data.touch34_id & 0xf0) >> 4) -1; + + //printk("before: cinfo->x[2] = %3d, cinfo->y[2] = %3d, cinfo->p[2] = %3d\n", cinfo->x[2], cinfo->y[2], cinfo->p[2]); + if(cinfo->x[2] < 1) cinfo->x[2] = 1; + if(cinfo->y[2]< 1) cinfo->y[2] = 1; + //printk("After: cinfo->x[2]= %3d, cinfo->y[2] = %3d, cinfo->p[2]= %3d, cinfo->id[2] = %3d\n", cinfo->x[2], cinfo->y[2], cinfo->p[2], cinfo->id[2]); + + if (cinfo->count > 3) + { + cinfo->x[3] = (( g_operation_data.x4_M << 8) | ( g_operation_data.x4_L)); //point 3 + cinfo->y[3] = (( g_operation_data.y4_M << 8) | ( g_operation_data.y4_L)); + cinfo->p[3] = 0;//g_operation_data.z4; + cinfo->id[3] = ((g_operation_data.touch34_id & 0x0f)) -1; + + //printk("before: cinfo->x[3] = %3d, cinfo->y[3] = %3d, cinfo->p[3] = %3d, cinfo->id[3] = %3d\n", cinfo->x[3], cinfo->y[3], cinfo->p[3], cinfo->id[3]); + //printk("before: x4_M = %3d, x4_L = %3d\n", g_operation_data.x4_M, g_operation_data.x4_L); + if(cinfo->x[3] < 1) cinfo->x[3] = 1; + if(cinfo->y[3] < 1) cinfo->y[3] = 1; + //printk("After: cinfo->x[3] = %3d, cinfo->y[3] = %3d, cinfo->p[3]= %3d, cinfo->id[3] = %3d\n", cinfo->x[3], cinfo->y[3], cinfo->p[3], cinfo->id[3]); + } + if (cinfo->count > 4) + { + cinfo->x[4] = (( g_operation_data.x5_M << 8) | ( g_operation_data.x5_L)); //point 3 + cinfo->y[4] = (( g_operation_data.y5_M << 8) | ( g_operation_data.y5_L)); + cinfo->p[4] = 0;//g_operation_data.z4; + cinfo->id[4] = ((g_operation_data.touch5_id & 0xf0) >> 4) -1; + + //printk("before: cinfo->x[4] = %3d, cinfo->y[4] = %3d, cinfo->id[4] = %3d\n", cinfo->x[4], cinfo->y[4], cinfo->id[4]); + //printk("before: x5_M = %3d, x5_L = %3d\n", g_operation_data.x5_M, g_operation_data.x5_L); + if(cinfo->x[4] < 1) cinfo->x[4] = 1; + if(cinfo->y[4] < 1) cinfo->y[4] = 1; + //printk("After: cinfo->x[4] = %3d, cinfo->y[4] = %3d, cinfo->id[4] = %3d\n", cinfo->x[4], cinfo->y[4], cinfo->id[4]); + } + } + + } + + if (!cinfo->count) return true; // this is a touch-up event + + if (g_operation_data.tt_mode & 0x20) { + //TPD_DEBUG("uffer is not ready for use!\n"); + memcpy(cinfo, pinfo, sizeof(struct touch_info)); + return false; + }//return false; // buffer is not ready for use// buffer is not ready for use + + // data toggle + + data0 = i2c_smbus_read_i2c_block_data(i2c_client, TPD_REG_BASE, 1, (u8*)&g_operation_data); + ////TPD_DEBUG("before hst_mode = %02X \n", g_operation_data.hst_mode); + + if((g_operation_data.hst_mode & 0x80)==0) + g_operation_data.hst_mode = g_operation_data.hst_mode|0x80; + else + g_operation_data.hst_mode = g_operation_data.hst_mode & (~0x80); + + ////TPD_DEBUG("after hst_mode = %02X \n", g_operation_data.hst_mode); + data1 = i2c_smbus_write_i2c_block_data(i2c_client, TPD_REG_BASE, sizeof(g_operation_data.hst_mode), &g_operation_data.hst_mode); + + + if (tt_mode == g_operation_data.tt_mode) { + //TPD_DEBUG("sampling not completed!\n"); + memcpy(cinfo, pinfo, sizeof(struct touch_info)); + return false; + }// sampling not completed + else + tt_mode = g_operation_data.tt_mode; + + return true; + +}; + +static int touch_event_handler(void *unused) +{ + int i,j; + int keeppoint[5]; + struct touch_info cinfo, pinfo; + struct sched_param param = { .sched_priority = 70/*RTPM_PRIO_TPD*/ }; + sched_setscheduler(current, SCHED_RR, ¶m); + + do + { + //printk("++++%s, line %d----unmask int\n", __FUNCTION__, __LINE__); + // mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); + wmt_enable_gpirq(); + set_current_state(TASK_INTERRUPTIBLE); + tp_interrupt_flag = 0; + //printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + wait_event_interruptible(waiter,tpd_flag!=0); +// printk("++++%s, line %d----start\n", __FUNCTION__, __LINE__); + + tpd_flag = 0; //debg 2013-5-6 + set_current_state(TASK_RUNNING); + + exit_boot_mode(); + if (tpd_touchinfo(&cinfo, &pinfo)) + { + memset(keeppoint, 0x0, sizeof(keeppoint)); + if(cinfo.count >0 && cinfo.count < (TP_POINTS_CNT+1)) + { + switch(cinfo.count) + { + case 5: + { + tpd_down(cinfo.x[4], cinfo.y[4], cinfo.p[4]); + } + case 4: + { + tpd_down(cinfo.x[3], cinfo.y[3], cinfo.p[3]); + } + case 3: + { + tpd_down(cinfo.x[2], cinfo.y[2], cinfo.p[2]); + } + case 2: + { + tpd_down(cinfo.x[1], cinfo.y[1], cinfo.p[1]); + } + case 1: + { + tpd_down(cinfo.x[0], cinfo.y[0], cinfo.p[0]); + } + default: + break; + } + for(i = 0; i < cinfo.count; i++) + for(j = 0; j < pinfo.count; j++) + { + if(cinfo.id[i] == pinfo.id[j])keeppoint[j] = 1; + else if(keeppoint[j] != 1)keeppoint[j] = 0; + } + + for(j = 0; j < pinfo.count; j++) + { + if(keeppoint[j] != 1) + { + tpd_up(pinfo.x[j], pinfo.y[j], pinfo.p[j]); + } + } + + } + else if(cinfo.count == 0 && pinfo.count !=0) + { + switch(pinfo.count ) + { + case 5: + { + tpd_up(pinfo.x[4], pinfo.y[4], pinfo.p[4]); + } + case 4: + { + tpd_up(pinfo.x[3], pinfo.y[3], pinfo.p[3]); + } + case 3: + { + tpd_up(pinfo.x[2], pinfo.y[2], pinfo.p[2]); + } + case 2: + { + tpd_up(pinfo.x[1], pinfo.y[1], pinfo.p[1]); + } + case 1: + { + tpd_up(pinfo.x[0], pinfo.y[0], pinfo.p[0]); + } + default: + break; + } + } + + input_sync(tpd->input); + + } + + + + }while(!kthread_should_stop()); + tp_interrupt_flag = 0; + + return 0; +} + + + + +static irqreturn_t tpd_eint_interrupt_handler(int irq, void *dev_id) +{ + static int i = 0; + i ++; + //printk("++++eint=%d\n",i); + + //mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); +// printk("++++%s, line %d, tpd_flag=%d,i=%d\n", __FUNCTION__, __LINE__, tpd_flag,i); + + if (wmt_is_tsint()) + { + // printk("<<<client/*i2c_ts*/ = client; + i2c_set_clientdata(client, tpd); + tpd->input = input_dev; + + input_dev->name = "touch_cyp140"; //MJ5_TS_NAME; + input_dev->phys = "cyp140_touch/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0002; + input_dev->id.version = 0x0100; + + input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + if (wmt_ts_get_lcdexchg()) { + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, max_y/*480*//*600*//*ResolutionX*//*ResolutionX*/, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, max_x /*ResolutionY*//*800*//* 1024*/, 0, 0); + } else { + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, max_x/*480*//*600*//*ResolutionX*//*ResolutionX*/, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, max_y /*ResolutionY*//*800*//* 1024*/, 0, 0); + } + + set_bit(KEY_BACK, input_dev->keybit); + set_bit(KEY_HOME, input_dev->keybit); + set_bit(KEY_MENU, input_dev->keybit); + retval = input_register_device(input_dev); + if (retval) + { + printk("%s input register device error!!\n", __FUNCTION__); + goto E_REG_INPUT; + } + //**************************** + //ctp_power_on(1); //wujinyou //!!!!2013-1-6 + + msleep(1000); + + //printk("<<<irq = wmt_get_tsirqnum(); + retval = request_irq(tpd->irq, tpd_eint_interrupt_handler,IRQF_SHARED, "cypcm", tpd); + //**************************************** + + printk("tpd_probe request_irq retval=%d!\n",retval); + msleep(100); + msleep(1000); + + cust_ts.client = i2c_client; +// cyttsp_fw_upgrade(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#if 0 //by linda 20130126 + status = i2c_smbus_read_i2c_block_data(i2c_client, 0x01, 1, &(buffer[0])); + printk("tpd_probe request_irq status=%d!\n",status); + + retval = i2c_master_send(i2c_client, bl_cmd, 12); + if( retval < 0) + { + printk("tpd_probe i2c_master_send retval=%d!\n",retval); + + //return retval; + goto I2C_ERR; + } +#else + retval = exit_boot_mode(); + if (retval) + { + printk("%s exit_boot_mod error!\n", __FUNCTION__); + goto I2C_ERR; + } + +#endif +/* + msleep(1000); + retval = i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 1, &(buffer[0])); + if(retval<0) { + retval = i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 1, &(buffer[0])); + if(retval<0) { + printk("error read !%d\n", __LINE__); + + goto I2C_ERR; + } + } +*/ + //TPD_DEBUG("[mtk-tpd], cyttsp tpd_i2c_probe success!!\n"); + tpd_load_status = 1; + thread = kthread_run(touch_event_handler, 0, TPD_DEVICE); + if (IS_ERR(thread)) { + retval = PTR_ERR(thread); + return retval; + + } + + + msleep(100); + printk("++++tpd_probe,retval=%d\n", retval); +#ifdef CONFIG_HAS_EARLYSUSPEND + tpd->early_suspend.suspend = tpd_early_suspend, + tpd->early_suspend.resume = tpd_late_resume, + tpd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;//,EARLY_SUSPEND_LEVEL_DISABLE_FB + 2; + register_early_suspend(&tpd->early_suspend); +#endif + //disable_irq(cyp140_ts->irq); + + wmt_enable_gpirq(); + +//cust_timer_init(); +// esd_init_thread(); //close it 2013-1-6 + return 0; //retval; + I2C_ERR: + free_irq(tpd->irq, tpd); + input_unregister_device(input_dev); // + E_REG_INPUT: + input_free_device(input_dev); + kfree(tpd); + //return retval; + Fail_request_rstgpio: + gpio_free(gpio_rst); + gpio_free(gpio_irq); + return retval; + +} +//******************************* + +//module_init(cyp140_ts_init); +static int tpd_local_init(void) +{ + if (tpd_probe(ts_get_i2c_client()))// ???? + { + return -1; + } + + + if(tpd_load_status == 0){ + //return -1; + ; + } + +#ifdef TPD_HAVE_BUTTON + tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data + boot_mode = get_boot_mode(); +#endif + return 0;//!!!!2013-1-7 +} + +//**********************suspend & resume +static int tpd_resume(/*struct i2c_client *client*/struct platform_device *pdev) +{ + int retval = TPD_OK; + int status = 0; + printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + //mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); + msleep(100); + #if 1 + ctp_power_on(1); + #endif + + msleep(1); + wmt_rst_output(0); + msleep(1); + wmt_rst_output(1); + msleep(100); + + wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);//sometimes gpio7 will in low after resume 2013-5-9 + wmt_enable_gpirq(); + printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + + //TPD_DEBUG("TPD wake up\n"); + + #if 0 //0 // by linda 20120126 change rambo 2013-5-6 + status = i2c_master_send(i2c_client, bl_cmd, 12); + #else + exit_boot_mode(); + #endif + printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + + if( status < 0) + { + printk("++++ [mtk-tpd], cyttsp tpd exit bootloader mode failed--tpd_resume!\n"); + return status; + } + //exit_boot_mode(); + printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + msleep(300); + //wmt_enable_gpirq(); //debg 2013-5-6 + tp_suspend_flag = 0; + return retval; +} + +static int tpd_suspend(/*struct i2c_client *client*/struct platform_device *pdev, pm_message_t message) +{ + int i = 0; + int retval = TPD_OK; + //u8 sleep_mode = 0x02; // 0x02--CY_DEEP_SLEEP_MODE, 0x04--CY_LOW_PWR_MODE + //TPD_DEBUG("TPD enter sleep\n"); + //u8 sleep_reg[2] = {0, 2}; + printk("++++%s, line %d----end\n", __FUNCTION__, __LINE__); + wmt_disable_gpirq(); + //wmt_disable_gpirq(); //dbg 2013-5-6 + + while((tp_reseting_flag || tp_interrupt_flag) && i<30) + { + i ++; + msleep(100); + } + tp_suspend_flag = 1; +#if 1 + //retval = i2c_smbus_write_i2c_block_data(i2c_client,0x00,sizeof(sleep_mode), &sleep_mode); + //retval = i2c_master_send(i2c_client, sleep_reg, 2); //send cmd error -5! + msleep(1); + ctp_power_on(0); + mdelay(1); +#else + mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO); + mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT); + mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE); +#endif + + return retval; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void tpd_early_suspend(struct early_suspend *handler) +{ + tpd_suspend(i2c_client, PMSG_SUSPEND); +} + +static void tpd_late_resume(struct early_suspend *handler) +{ + tpd_resume(i2c_client); +} +#endif +//**************************** + + +static void cyp140_ts_exit(void) +{ + printk("<<<%s\n", __FUNCTION__); + + wmt_disable_gpirq(); + free_irq(tpd->irq, tpd); + //kthread_stop(thread); // halt rmmod?? + input_unregister_device(tpd->input); // + + input_free_device(tpd->input); + kfree(tpd); + gpio_free(wmt_ts_get_irqgpnum()); + gpio_free(wmt_ts_get_resetgpnum()); +} +//module_exit(cyp140_ts_exit); + +void cyp140_set_ts_mode(u8 mode) +{ + dbg( "[Touch Screen]ts mode = %d \n", mode); +} +//EXPORT_SYMBOL_GPL(cyp140_set_ts_mode); + +struct wmtts_device cyp140_tsdev = { + .driver_name = WMT_TS_I2C_NAME, + .ts_id = "cyp140", + .init = tpd_local_init, + .exit = cyp140_ts_exit, + .suspend = tpd_suspend, + .resume = tpd_resume, +}; + + + +MODULE_DESCRIPTION("cyp140 I2C Touch Screen driver"); +MODULE_LICENSE("GPL v2"); -- cgit