#define DBG(x...)\r
#endif\r
\r
+#define PEN_DOWN 1\r
+#define PEN_RELEASE 0\r
+#define PEN_DOWN_UP 2 //from down to up\r
+\r
\r
#define GT8110_ID_REG 0x00\r
#define GT8110_DATA_REG 0x00\r
if(enable)\r
{\r
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);\r
- mdelay(200);\r
+ mdelay(10);\r
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);\r
msleep(200);\r
}\r
int irq_pin = irq_to_gpio(ts->pdata->irq);\r
char version_data[18] = {240};\r
char init_data[95] = {\r
- 0x65,0x02,0x00,0x10,0x00,0x10,0x0A,0x6E,0x0A,0x00,\r
- 0x0F,0x1E,0x02,0x08,0x10,0x00,0x00,0x27,0x00,0x00,\r
- 0x50,0x10,0x10,0x11,0x37,0x00,0x00,0x00,0x01,0x02,\r
- 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0xFF,\r
- 0xFF,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,\r
- 0x07,0x08,0x09,0x0A,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,\r
- 0x00,0x50,0x64,0x50,0x00,0x00,0x00,0x00,0x00,0x00,\r
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
- 0x00,0x00,0x00,0x00,0x20\r
+ 0x65,0x02,0x00,0x10,0x00,0x10,0x0A,0x62,0x4A,0x00,
+ 0x0F,0x28,0x02,0x10,0x10,0x00,0x00,0x20,0x00,0x00,
+ 0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,
+ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,
+ 0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+ 0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,
+ 0x00,0x3C,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00\r
};\r
int result = 0, i = 0;\r
\r
return result;\r
}\r
\r
+static bool goodix_get_status(char *p1,int*p2)\r
+{\r
+ bool status = PEN_DOWN;\r
+ if((*p2==PEN_DOWN) && (*p1==PEN_RELEASE))\r
+ {\r
+ *p2 = PEN_DOWN_UP; //¸Õ¸Õµ¯Æð\r
+ status = PEN_RELEASE; \r
+ }\r
+ else if((*p2==PEN_RELEASE) && (*p1==PEN_RELEASE))\r
+ {\r
+ *p2 = PEN_RELEASE;\r
+ status = PEN_RELEASE; \r
+ }\r
+ else\r
+ {\r
+ *p2 = PEN_DOWN;\r
+ }\r
+ return status;\r
+}\r
+\r
+\r
+\r
+static int ts_check_irq(struct i2c_client *client)\r
+{\r
+ struct ts_private_data *ts =\r
+ (struct ts_private_data *) i2c_get_clientdata(client); \r
+ struct ts_platform_data *pdata = ts->pdata; \r
+ struct ts_event *event = &ts->event;\r
+ int gpio_level_no_int = GPIO_HIGH;\r
+ int id = 0, i = 0;\r
+ \r
+ if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_FALLING))\r
+ gpio_level_no_int = GPIO_HIGH;\r
+ else \r
+ gpio_level_no_int = GPIO_LOW;\r
+\r
+ if(gpio_get_value(ts->pdata->irq) == gpio_level_no_int) \r
+ {\r
+ for(i = 0; i<ts->ops->max_point; i++)\r
+ { \r
+ id = i; \r
+ if(event->point[id].last_status != 0)\r
+ {\r
+ event->point[i].last_status = PEN_RELEASE; \r
+ input_mt_slot(ts->input_dev, event->point[i].id); \r
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);\r
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
+ DBG("%s:%s press up,id=%d\n\n",__func__,ts->ops->name, event->point[i].id);\r
+ }\r
+ }\r
+ \r
+ input_sync(ts->input_dev); \r
+ memset(event, 0x00, sizeof(struct ts_event)); \r
+ enable_irq(ts->client->irq);\r
+ }\r
+ else\r
+ schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));\r
+ \r
+}\r
+\r
\r
static int ts_report_value(struct i2c_client *client)\r
{\r
//for(i=0; i<ts->ops->read_len; i++)\r
//DBG("buf[%d]=0x%x\n",i,buf[i]);\r
\r
- //temp = (buf[2]<<8) + buf[1];\r
+ temp = (buf[1] << 8) | buf[0];\r
\r
- temp = ((buf[2]&0x03) << 8) | buf[1];\r
for(i=0; i<ts->ops->max_point; i++)\r
{\r
if(temp & (1 << i)) \r
+ { \r
+ event->point[i].status = PEN_DOWN;\r
num++;\r
- }\r
-\r
- event->touch_point = num;\r
-#if 0\r
- if(event->touch_point == 0)\r
- { \r
- for(i=0; i<ts->ops->max_point; i++)\r
- {\r
- if(event->point[i].status != 0)\r
- {\r
- event->point[i].status = 0; \r
- input_mt_slot(ts->input_dev, event->point[i].id); \r
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);\r
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
- DBG("%s:%s press up,id=%d\n",__func__,ts->ops->name, event->point[i].id);\r
- }\r
}\r
- \r
- input_sync(ts->input_dev);\r
- memset(event, 0x00, sizeof(struct ts_event));\r
- \r
- return 0;\r
}\r
-#endif \r
- for(i = 0; i<ts->ops->max_point; i++)\r
+ \r
+ if(num > event->touch_point)\r
+ event->touch_point = num;\r
+\r
+ for(i = 0; i<event->touch_point; i++)\r
{\r
- off = 3 + i*4;\r
+ off = 2 + i*4;\r
\r
id = i; \r
event->point[id].id = id;\r
- event->point[id].status = temp & (1 << (ts->ops->max_point - i -1));\r
- event->point[id].x = (unsigned int)(buf[off+0]<<8) + (unsigned int)buf[off+1];\r
- event->point[id].y = (unsigned int)(buf[off+2]<<8) + (unsigned int)buf[off+3];\r
- //event->point[id].press = buf[off+4];\r
-\r
- //for(j=0; j<(3 + (i+1)*4); j++)\r
+ \r
+ if(goodix_get_status(&event->point[id].status,&event->point[id].last_status))\r
+ {\r
+ event->point[id].x = (unsigned int)(buf[off+1]<<8) + (unsigned int)buf[off+0];\r
+ event->point[id].y = (unsigned int)(buf[off+3]<<8) + (unsigned int)buf[off+2];\r
+ }\r
+ \r
+ if((event->point[id].x <= 0) || (event->point[id].x >= ts->ops->range[0]) || (event->point[id].y <= 0) || (event->point[id].y >= ts->ops->range[1]))\r
+ {\r
+ event->point[id].status = 0;\r
+ continue;\r
+ }\r
+ //for(j=0; j<(2 + (i+1)*4); j++)\r
//DBG("buf[%d]=0x%x\n",j,buf[j]);\r
\r
if(ts->ops->xy_swap)\r
event->point[id].y = ts->ops->pixel.max_y - event->point[id].y;\r
}\r
\r
- DBG("%s:point[%d].status=%d,point[%d].last_status=%d\n",__func__,i,event->point[i].status,i,event->point[i].last_status);\r
-\r
- if(event->point[id].status != 0)\r
+ \r
+ if(event->point[id].status==PEN_DOWN_UP)\r
+ {\r
+ event->point[id].status=PEN_RELEASE;\r
+ input_mt_slot(ts->input_dev, event->point[i].id); \r
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);\r
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
+ DBG("%s:%s press is uping,id=%d\n\n",__func__,ts->ops->name, event->point[i].id);\r
+ continue;\r
+ }\r
+ \r
+ if(event->point[id].status==PEN_DOWN)\r
{ \r
input_mt_slot(ts->input_dev, event->point[id].id);\r
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[id].id);\r
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1); \r
DBG("%s:%s press down,id=%d,x=%d,y=%d\n\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);\r
}\r
- else if((event->point[id].status == 0) && (event->point[id].last_status != 0))\r
- {\r
- event->point[i].status = 0; \r
- input_mt_slot(ts->input_dev, event->point[i].id); \r
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);\r
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
- DBG("%s:%s press up,id=%d\n\n",__func__,ts->ops->name, event->point[i].id);\r
-\r
- }\r
\r
event->point[id].last_status = event->point[id].status;\r
}\r
struct ts_private_data *ts =\r
(struct ts_private_data *) i2c_get_clientdata(client); \r
struct ts_platform_data *pdata = ts->pdata;\r
- \r
- if(ts->pdata->irq_enable) \r
- disable_irq_nosync(client->irq);\r
\r
if(ts->ops->active)\r
ts->ops->active(client, 0);\r
(struct ts_private_data *) i2c_get_clientdata(client); \r
struct ts_platform_data *pdata = ts->pdata;\r
\r
- if(ts->pdata->irq_enable) \r
- enable_irq(client->irq);\r
-\r
if(ts->ops->active)\r
ts->ops->active(client, 1);\r
return 0;\r
.id_data = TS_UNKNOW_DATA, \r
.read_reg = GT8110_DATA_REG, //read data\r
.read_len = 5*10+3+1, //data length\r
- .trig = IRQ_TYPE_LEVEL_LOW | IRQF_ONESHOT, \r
+ .trig = IRQ_TYPE_LEVEL_LOW, \r
.max_point = 10,\r
.xy_swap = 0,\r
.x_revert = 0,\r
.y_revert = 0,\r
.range = {4096,4096},\r
+ .irq_enable = 1,\r
+ .poll_delay_ms = 30,\r
.active = ts_active, \r
- .init = ts_init,\r
+ .init = ts_init, \r
+ .check_irq = ts_check_irq,\r
.report = ts_report_value,\r
.firmware = NULL,\r
.suspend = ts_suspend,\r
if (ts_get_data(client) < 0) \r
DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
\r
- if(!ts->pdata->irq_enable)//restart work while polling\r
- schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->pdata->poll_delay_ms));\r
- //else\r
- //{\r
- //if((ts->ops->trig == IRQF_TRIGGER_LOW) || (ts->ops->trig == IRQF_TRIGGER_HIGH))\r
- //enable_irq(ts->client->irq);\r
- //}\r
+ if(!ts->ops->irq_enable)//restart work while polling\r
+ schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));\r
+ else\r
+ {\r
+ if(ts->ops->check_irq)\r
+ {\r
+ ts->ops->check_irq(client); \r
+ }\r
+ else\r
+ {\r
+ if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_HIGH))\r
+ enable_irq(ts->client->irq);\r
+ }\r
+ }\r
mutex_unlock(&ts->ts_mutex);\r
\r
DBG("%s:%s\n",__func__,ts->i2c_id->name);\r
struct ts_private_data *ts = (struct ts_private_data *)dev_id;\r
\r
//use threaded IRQ\r
- if (ts_get_data(ts->client) < 0) \r
- DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
- msleep(ts->pdata->poll_delay_ms);\r
-\r
- \r
- //if((ts->ops->trig == IRQF_TRIGGER_LOW) || (ts->ops->trig == IRQF_TRIGGER_HIGH))\r
- //disable_irq_nosync(irq);\r
- //schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->pdata->poll_delay_ms));\r
+ //if (ts_get_data(ts->client) < 0) \r
+ // DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
+ //msleep(ts->ops->poll_delay_ms);\r
+ if(ts->ops->check_irq)\r
+ {\r
+ disable_irq_nosync(irq);\r
+ }\r
+ else\r
+ {\r
+ if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_HIGH))\r
+ disable_irq_nosync(irq);\r
+ }\r
+ schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));\r
DBG("%s:irq=%d\n",__func__,irq);\r
return IRQ_HANDLED;\r
}\r
(struct ts_private_data *) i2c_get_clientdata(client); \r
int result = 0;\r
int irq;\r
- if((ts->pdata->irq_enable)&&(ts->ops->trig != TS_UNKNOW_DATA))\r
+ if((ts->ops->irq_enable)&&(ts->ops->trig != TS_UNKNOW_DATA))\r
{\r
- //INIT_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);\r
- if(ts->pdata->poll_delay_ms < 0)\r
- ts->pdata->poll_delay_ms = 30;\r
+ INIT_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);\r
+ if(ts->ops->poll_delay_ms < 0)\r
+ ts->ops->poll_delay_ms = 30;\r
\r
result = gpio_request(client->irq, ts->i2c_id->name);\r
if (result)\r
\r
gpio_pull_updown(client->irq, PullEnable);\r
irq = gpio_to_irq(client->irq);\r
- //result = request_irq(irq, ts_interrupt, ts->ops->trig, ts->ops->name, ts);\r
- result = request_threaded_irq(irq, NULL, ts_interrupt, ts->ops->trig, ts->ops->name, ts);\r
+ result = request_irq(irq, ts_interrupt, ts->ops->trig, ts->ops->name, ts);\r
+ //result = request_threaded_irq(irq, NULL, ts_interrupt, ts->ops->trig, ts->ops->name, ts);\r
if (result) {\r
printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result); \r
goto error; \r
client->irq = irq;\r
printk("%s:use irq=%d\n",__func__,irq);\r
}\r
- else if(!ts->pdata->irq_enable)\r
+ else if(!ts->ops->irq_enable)\r
{ \r
INIT_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);\r
- if(ts->pdata->poll_delay_ms < 0)\r
- ts->pdata->poll_delay_ms = 30;\r
+ if(ts->ops->poll_delay_ms < 0)\r
+ ts->ops->poll_delay_ms = 30;\r
\r
- printk("%s:use polling,delay=%d ms\n",__func__,ts->pdata->poll_delay_ms);\r
+ schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));\r
+ printk("%s:use polling,delay=%d ms\n",__func__,ts->ops->poll_delay_ms);\r
}\r
\r
error: \r
if(ts->ops->suspend)\r
ts->ops->suspend(ts->client);\r
\r
+ if(ts->ops->irq_enable) \r
+ disable_irq_nosync(ts->client->irq);\r
+ else\r
+ cancel_delayed_work_sync(&ts->delaywork); \r
+\r
}\r
\r
static void ts_resume(struct early_suspend *h)\r
\r
if(ts->ops->resume)\r
ts->ops->resume(ts->client);\r
+\r
+ if(ts->ops->irq_enable) \r
+ enable_irq(ts->client->irq);\r
+ else\r
+ {\r
+ PREPARE_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);\r
+ schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));\r
+ }\r
}\r
#endif\r
\r