1 /****************************************************************************************
2 * driver/input/touchscreen/hannstar_p1003.c
3 *Copyright :ROCKCHIP Inc
6 *This driver use for rk28 chip extern touchscreen. Use i2c IF ,the chip is Hannstar
8 ********************************************************************************************/
9 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include <linux/earlysuspend.h>
12 #include <linux/hrtimer.h>
13 #include <linux/i2c.h>
14 #include <linux/input.h>
15 #include <linux/interrupt.h>
17 #include <linux/platform_device.h>
18 #include <mach/gpio.h>
19 #include <linux/irq.h>
20 #include <mach/board.h>
22 #define MAX_SUPPORT_POINT 2// // 4
23 //#define Singltouch_Mode
26 #define sakura_dbg_msg(fmt,...) do { \
27 printk("sakura dbg msg------>" \
28 " (func-->%s ; line-->%d) " fmt, __func__, __LINE__ , ##__VA_ARGS__); \
30 #define sakura_dbg_report_key_msg(fmt,...) do{ \
31 printk("sakura report " fmt,##__VA_ARGS__); \
34 #define sakura_dbg_msg(fmt,...) do {} while(0)
35 #define sakura_dbg_report_key_msg(fmt,...) do{}while(0)
44 struct multitouch_event{
45 struct point_data point_data[MAX_SUPPORT_POINT];
51 struct input_dev *input;
53 struct delayed_work work;
54 struct workqueue_struct *wq;
56 struct i2c_client *client;
57 struct multitouch_event mt_event;
63 int has_relative_report;
64 int (*get_pendown_state)(void);
65 void (*clear_penirq)(void);
68 int p1003_get_pendown_state(void)
73 static void p1003_report_event(struct ts_p1003 *ts,struct multitouch_event *tc)
75 struct input_dev *input = ts->input;
77 dev_dbg(&ts->client->dev, "UP\n");
79 for(i=0; i<MAX_SUPPORT_POINT;i++){
80 if(tc->point_data[i].status >= 0){
81 pandown |= tc->point_data[i].status;
82 input_report_abs(input, ABS_MT_TRACKING_ID, i);
83 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tc->point_data[i].status);
84 input_report_abs(input, ABS_MT_WIDTH_MAJOR, 0);
85 input_report_abs(input, ABS_MT_POSITION_X, tc->point_data[i].x);
86 input_report_abs(input, ABS_MT_POSITION_Y, tc->point_data[i].y);
89 sakura_dbg_report_key_msg("ABS_MT_TRACKING_ID = %x, ABS_MT_TOUCH_MAJOR = %x\n",
90 " ABS_MT_POSITION_X = %x, ABS_MT_POSITION_Y = %x\n",i,tc->point_data[i].status,tc->point_data[i].x,tc->point_data[i].y);
92 if(tc->point_data[i].status == 0)
93 tc->point_data[i].status--;
97 ts->pendown = pandown;
101 #if defined (Singltouch_Mode)
102 static void p1003_report_single_event(struct ts_p1003 *ts,struct multitouch_event *tc)
104 struct input_dev *input = ts->input;
109 input_report_abs(input, ABS_X, tc->point_data[cid].x);
110 input_report_abs(input, ABS_Y, tc->point_data[cid].y);
113 if(ts->pendown != ts->status){
114 ts->pendown = ts->status;
115 input_report_key(input, BTN_TOUCH, ts->status);
117 sakura_dbg_report_key_msg("%s x =0x%x,y = 0x%x \n",ts->status?"down":"up",tc->point_data[cid].x,tc->point_data[cid].y);
122 static inline int p1003_read_values(struct ts_p1003 *ts, struct multitouch_event *tc)
129 data = i2c_master_normal_recv(ts->client, buf,len, 200*1000);
131 if (data < 0 || (buf[0]!=0x04)) {
133 dev_err(&ts->client->dev, "i2c io error: %d or Hannstar read reg failed\n", data);
134 for(i = 0; i < 10 ; i++)
135 dev_err(&ts->client->dev," hannstar reg[%d] = 0x%x\n",i,buf[i]);
140 contactid = (buf[1]&0x7C)>>2;
141 tc->contactid = contactid;
142 tc->point_data[contactid].status = buf[1]&0x01;
143 tc->point_data[contactid].x = ((buf[3]<<8) + buf[2])>>4;
144 tc->point_data[contactid].y = ((buf[5]<<8) + buf[4])>>4;
145 tc->validtouch = buf[1]&0x80;
146 ts->status = tc->point_data[contactid].status;
147 // printk("validtouch =%d,status= %d,contactid =%d\n",tc->validtouch,tc->point_data[contactid].status,contactid);
152 static void p1003_work(struct work_struct *work)
154 struct ts_p1003 *ts =
155 container_of(to_delayed_work(work), struct ts_p1003, work);
156 struct multitouch_event *tc = &ts->mt_event;
159 rt = p1003_read_values(ts,tc);
164 #if defined (Singltouch_Mode)
165 p1003_report_single_event(ts,tc);
167 p1003_report_event(ts,tc);
172 queue_delayed_work(ts->wq, &ts->work, msecs_to_jiffies(10));
177 static irqreturn_t p1003_irq(int irq, void *handle)
179 struct ts_p1003 *ts = handle;
181 if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
182 disable_irq_nosync(ts->irq);
183 queue_delayed_work(ts->wq, &ts->work, 0);
190 static void p1003_free_irq(struct ts_p1003 *ts)
192 free_irq(ts->irq, ts);
193 if (cancel_delayed_work_sync(&ts->work)) {
195 * Work was pending, therefore we need to enable
196 * IRQ here to balance the disable_irq() done in the
203 static int __devinit p1003_probe(struct i2c_client *client,
204 const struct i2c_device_id *id)
207 struct p1003_platform_data *pdata = pdata = client->dev.platform_data;
208 struct input_dev *input_dev;
212 dev_err(&client->dev, "platform data is required!\n");
216 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
219 ts = kzalloc(sizeof(struct ts_p1003), GFP_KERNEL);
220 input_dev = input_allocate_device();
221 if (!ts || !input_dev) {
227 ts->irq = client->irq;
228 ts->input = input_dev;
229 ts->status =0 ;// fjp add by 2010-9-30
230 ts->pendown = 0; // fjp add by 2010-10-06
232 ts->wq = create_rt_workqueue("p1003_wq");
233 INIT_DELAYED_WORK(&ts->work, p1003_work);
235 ts->model = pdata->model;
237 snprintf(ts->phys, sizeof(ts->phys),
238 "%s/input0", dev_name(&client->dev));
240 input_dev->name = "p1003 Touchscreen";
241 input_dev->phys = ts->phys;
242 input_dev->id.bustype = BUS_I2C;
244 #if defined (Singltouch_Mode)
245 set_bit(EV_SYN, input_dev->evbit);
246 set_bit(EV_KEY, input_dev->evbit);
247 set_bit(BTN_TOUCH, input_dev->keybit);
248 set_bit(BTN_2, input_dev->keybit);
249 set_bit(EV_ABS, input_dev->evbit);
250 input_set_abs_params(input_dev,ABS_X,0,1087,0,0);
251 input_set_abs_params(input_dev,ABS_Y,0,800,0,0);
253 ts->has_relative_report = 0;
254 input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);
255 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
256 input_dev->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); //jaocbchen for dual
257 input_set_abs_params(input_dev, ABS_X, 0, 1087, 0, 0);
258 input_set_abs_params(input_dev, ABS_Y, 0, 800, 0, 0);
259 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
260 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
261 input_set_abs_params(input_dev, ABS_HAT0X, 0, 1087, 0, 0);
262 input_set_abs_params(input_dev, ABS_HAT0Y, 0, 800, 0, 0);
263 input_set_abs_params(input_dev, ABS_MT_POSITION_X,0, 1087, 0, 0);
264 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 800, 0, 0);
265 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
266 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
267 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0);
270 if (pdata->init_platform_hw)
271 pdata->init_platform_hw();
274 dev_dbg(&ts->client->dev, "no IRQ?\n");
277 ts->irq = gpio_to_irq(ts->irq);
280 err = request_irq(ts->irq, p1003_irq, 0,
281 client->dev.driver->name, ts);
284 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
291 err = set_irq_type(ts->irq,IRQ_TYPE_LEVEL_LOW);
293 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
299 err = input_register_device(input_dev);
303 i2c_set_clientdata(client, ts);
309 if (pdata->exit_platform_hw)
310 pdata->exit_platform_hw();
312 input_free_device(input_dev);
317 static int __devexit p1003_remove(struct i2c_client *client)
319 struct ts_p1003 *ts = i2c_get_clientdata(client);
320 struct p1003_platform_data *pdata = client->dev.platform_data;
324 if (pdata->exit_platform_hw)
325 pdata->exit_platform_hw();
327 input_unregister_device(ts->input);
333 static struct i2c_device_id p1003_idtable[] = {
334 { "p1003_touch", 0 },
338 MODULE_DEVICE_TABLE(i2c, p1003_idtable);
340 static struct i2c_driver p1003_driver = {
342 .owner = THIS_MODULE,
343 .name = "p1003_touch"
345 .id_table = p1003_idtable,
346 .probe = p1003_probe,
347 .remove = __devexit_p(p1003_remove),
350 static int __init p1003_init(void)
352 printk("--------> %s <-------------\n",__func__);
353 return i2c_add_driver(&p1003_driver);
356 static void __exit p1003_exit(void)
358 return i2c_del_driver(&p1003_driver);
360 module_init(p1003_init);
361 module_exit(p1003_exit);
362 MODULE_LICENSE("GPL");