2 * drivers/input/touchscreen/ct36x_ts.c
4 * VTL ct36x TouchScreen driver.
6 * Copyright (c) 2010 VTL tech Ltd.
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 * George Chen, 2012-06-15
21 // ****************************************************************************
23 // ****************************************************************************
25 #include <linux/kernel.h>
26 #include <linux/version.h>
27 #include <linux/proc_fs.h>
28 #include <linux/i2c.h>
29 #include <linux/delay.h>
30 #include <linux/interrupt.h>
31 #include <linux/input.h>
32 #include <linux/gpio.h>
38 enum enum_ct36x_ts_cmds {
49 // ****************************************************************************
50 // Globel or static variables
51 // ****************************************************************************
52 static struct ct36x_ts_info ct36x_ts;
55 // ****************************************************************************
56 // Function declaration
57 // ****************************************************************************
58 int ct36x_cmd_list_ind[] = {
68 char ct36x_cmd_list_cmd[] = { 'i','r','v','c','u','b','k',0, };
70 static int ct36x_ts_cmd(char *cmdlist, const char cmd)
75 while ( cmdlist[i] ) {
76 if ( cmd == cmdlist[i] )
77 return ct36x_cmd_list_ind[i];
84 static int ct36x_ts_open(struct inode *inode, struct file *file)
86 if ( CT36X_TS_CORE_DEBUG )
87 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
92 static int ct36x_ts_close(struct inode *inode, struct file *file)
94 if ( CT36X_TS_CORE_DEBUG )
95 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
100 static ssize_t ct36x_ts_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset)
105 if ( CT36X_TS_CORE_DEBUG ) {
106 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
107 printk("%s(): count=0x%x \n", __FUNCTION__, count);
111 cmd = ct36x_ts_cmd(ct36x_cmd_list_cmd, buffer[0]);
114 case CT36X_TS_CHIP_ID:
117 case CT36X_TS_CHIP_RESET:
118 printk("%s(): CT36X_TS_CHIP_RESET\n", __FUNCTION__);
119 ct36x_platform_hw_reset(&ct36x_ts);
122 case CT36X_TS_FW_VER:
125 case CT36X_TS_FW_CHKSUM:
126 printk("%s(): CT36X_TS_FW_CHKSUM\n", __FUNCTION__);
127 rslt = ct36x_chip_get_fwchksum(ct36x_ts.client, ct36x_ts.data.buf);
128 printk("%s(): Fw checksum: 0x%x\n", __FUNCTION__, rslt);
131 case CT36X_TS_FW_UPDATE:
132 printk("%s(): CT36X_TS_FW_UPDATE\n", __FUNCTION__);
133 ct36x_chip_go_bootloader(ct36x_ts.client, ct36x_ts.data.buf);
136 case CT36X_TS_BIN_VER:
139 case CT36X_TS_BIN_CHKSUM:
140 printk("%s(): CT36X_TS_BIN_CHKSUM\n", __FUNCTION__);
141 rslt = ct36x_chip_get_binchksum(ct36x_ts.data.buf);
142 printk("%s(): bin checksum: 0x%x\n", __FUNCTION__, rslt);
146 printk("%s(): No such command (0x%x). \n", __FUNCTION__, buffer[0]);
154 static ssize_t ct36x_ts_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
158 if ( CT36X_TS_CORE_DEBUG ) {
159 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
160 printk("%s(): count=0x%x \n", __FUNCTION__, count);
163 if ( !ct36x_ts.ready )
166 //ct36x_ts_reg_read(ct36x_ts->client, buf[0], buf+1, buf[]);
171 static struct file_operations ct36x_ts_fops = {
172 .owner = THIS_MODULE,
173 .open = ct36x_ts_open,
174 .release = ct36x_ts_close,
175 .write = ct36x_ts_write,
176 .read = ct36x_ts_read,
179 static irqreturn_t ct36x_ts_irq(int irq, void *dev)
181 struct ct36x_ts_info *ts;
183 if ( CT36X_TS_CORE_DEBUG )
184 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
186 ts = (struct ct36x_ts_info *)dev;
188 // touch device is ready??
190 // Disable ts interrupt
191 disable_irq_nosync(ts->irq);
193 queue_work(ts->workqueue, &ts->event_work);
199 static void ct36x_ts_workfunc(struct work_struct *work)
204 struct ct36x_ts_info *ts;
206 if ( CT36X_TS_CORE_DEBUG )
207 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
209 ts = container_of(work, struct ct36x_ts_info, event_work);
211 /* read touch points */
212 ct36x_ts_reg_read(ts->client, ts->i2c_address, (char *) ts->data.pts, sizeof(struct ct36x_finger_info) * CT36X_TS_POINT_NUM);
215 sync = 0; ts->press = 0;
216 for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
217 if ( ts->data.pts[iter].xhi != 0xFF && ts->data.pts[iter].yhi != 0xFF &&
218 (ts->data.pts[iter].status == 1 || ts->data.pts[iter].status == 2) ) {
219 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_XY_SWAP
220 x = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
221 y = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
223 x = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
224 y = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
226 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_X_REVERSE
227 x = CT36X_TS_ABS_X_MAX - x;
229 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_Y_REVERSE
230 y = CT36X_TS_ABS_Y_MAX - y;
233 if ( CT36X_TS_EVENT_DEBUG ) {
234 printk("ID: %d\n", ts->data.pts[iter].id);
235 printk("status: %d\n", ts->data.pts[iter].status);
236 printk("X Lo: %d\n", ts->data.pts[iter].xlo);
237 printk("Y Lo: %d\n", ts->data.pts[iter].ylo);
238 printk("X Hi: %d\n", ts->data.pts[iter].xhi);
239 printk("Y Hi: %d\n", ts->data.pts[iter].yhi);
240 printk("X: %d\n", x);
241 printk("Y: %d\n", y);
244 input_report_abs(ts->input, ABS_MT_POSITION_X, x);
245 input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
247 input_mt_sync(ts->input);
250 ts->press |= 0x01 << (ts->data.pts[iter].id - 1);
254 ts->release &= ts->release ^ ts->press;
255 for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
256 if ( ts->release & (0x01<<iter) ) {
257 input_mt_sync(ts->input);
261 ts->release = ts->press;
263 if ( sync ) input_sync(ts->input);
265 // Enable ts interrupt
270 static void ct36x_ts_adapter(int state)
272 if ( CT36X_TS_CORE_DEBUG )
273 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
275 if ( !ct36x_ts.ready ) return;
278 #ifdef CONFIG_HAS_EARLYSUSPEND
279 static void ct36x_early_suspend(struct early_suspend *handler)
281 struct ct36x_ts_info *ts;
283 if (CT36X_TS_CORE_DEBUG)
284 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
286 ts = container_of(handler, struct ct36x_ts_info, early_suspend);
288 ct36x_ts_suspend(ts->client, PMSG_SUSPEND);
291 static void ct36x_early_resume(struct early_suspend *handler)
293 struct ct36x_ts_info *ts;
295 if (CT36X_TS_CORE_DEBUG)
296 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
298 ts = container_of(handler, struct ct36x_ts_info, early_suspend);
300 ct36x_ts_resume(ts->client);
304 int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
307 int binchksum, fwchksum;
309 struct ct36x_ts_info *ts;
310 struct ct36x_platform_data *pdata;
313 if ( CT36X_TS_CORE_DEBUG )
314 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
318 pdata = dev->platform_data;
321 ct36x_ts.i2c_address = client->addr;
322 ct36x_ts.rst = pdata->rst;
323 ct36x_ts.ss = pdata->ss;
324 ct36x_platform_get_cfg(&ct36x_ts);
326 ct36x_ts.client = client;
327 i2c_set_clientdata(client, &ct36x_ts);
329 printk("No platform data for device %s.\n", DRIVER_NAME);
331 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
333 /* Create Proc Entry File */
334 ts->proc_entry = create_proc_entry(DRIVER_NAME, 0666/*S_IFREG | S_IRUGO | S_IWUSR*/, NULL);
335 if ( ts->proc_entry == NULL ) {
336 dev_err(dev, "Failed creating proc dir entry file.\n");
338 ts->proc_entry->proc_fops = &ct36x_ts_fops;
341 /* register early suspend */
342 #ifdef CONFIG_HAS_EARLYSUSPEND
343 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
344 ts->early_suspend.suspend = ct36x_early_suspend;
345 ts->early_suspend.resume = ct36x_early_resume;
346 register_early_suspend(&ts->early_suspend);
349 /* Check I2C Functionality */
350 err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
352 dev_err(dev, "Check I2C Functionality Failed.\n");
356 /* Request platform resources (gpio/interrupt pins) */
357 err = ct36x_platform_get_resource(ts);
359 dev_err(dev, "Unable to request platform resource for device %s.\n", DRIVER_NAME);
364 ct36x_platform_hw_reset(ts);
366 // Get binary Checksum
367 binchksum = ct36x_chip_get_binchksum(ts->data.buf);
368 if ( CT36X_TS_CORE_DEBUG )
369 printk("Bin checksum: 0x%x\n", binchksum);
371 // Get firmware Checksum
372 fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
373 if ( CT36X_TS_CORE_DEBUG )
374 printk("Fw checksum: 0x%x\n", fwchksum);
377 while ( binchksum != fwchksum && updcnt--) {
378 /* Update Firmware */
379 ct36x_chip_go_bootloader(client, ts->data.buf);
382 ct36x_platform_hw_reset(ts);
384 // Get firmware Checksum
385 fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
386 if ( CT36X_TS_CORE_DEBUG )
387 printk("Fw checksum: 0x%x\n", fwchksum);
390 printk("Fw update %s. 0x%x, 0x%x\n", binchksum != fwchksum ? "Failed" : "Success", binchksum, fwchksum);
393 ct36x_platform_hw_reset(ts);
395 /* allocate input device */
396 ts->input = input_allocate_device();
398 dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME);
400 goto ERR_INPUT_ALLOC;
403 /* config input device */
404 __set_bit(EV_SYN, ts->input->evbit);
405 __set_bit(EV_KEY, ts->input->evbit);
406 __set_bit(EV_ABS, ts->input->evbit);
408 __set_bit(INPUT_PROP_DIRECT, ts->input->propbit);
410 input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0);
411 input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0);
413 ts->input->name = DRIVER_NAME;
414 ts->input->id.bustype = BUS_I2C;
416 /* register input device */
417 err = input_register_device(ts->input);
419 dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME);
420 goto ERR_INPUT_REGIS;
423 /* Create work queue */
424 INIT_WORK(&ts->event_work, ct36x_ts_workfunc);
425 ts->workqueue = create_singlethread_workqueue(dev_name(&client->dev));
428 err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts);
430 dev_err(dev, "Unable to request irq for device %s.\n", DRIVER_NAME);
434 /* Set device is ready */
436 ts->state = CT36X_STATE_NORMAL;
439 //ct36x_chip_set_adapter_on(client, ts->data.buf);
440 //ct36x_chip_set_adapter_off(client, ts->data.buf);
446 destroy_workqueue(ts->workqueue);
448 input_free_device(ts->input);
451 ct36x_platform_put_resource(ts);
453 #ifdef CONFIG_HAS_EARLYSUSPEND
454 unregister_early_suspend(&ts->early_suspend);
456 remove_proc_entry(DRIVER_NAME, NULL);
460 void ct36x_ts_shutdown(struct i2c_client *client)
462 struct ct36x_ts_info *ts;
464 if (CT36X_TS_CORE_DEBUG)
465 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
467 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
469 ct36x_chip_go_sleep(client, ts->data.buf);
472 int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg)
474 struct ct36x_ts_info *ts;
476 if (CT36X_TS_CORE_DEBUG)
477 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
479 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
481 if ( ts->state == CT36X_STATE_SLEEP ) return 0;
483 disable_irq(ts->irq);
485 cancel_work_sync(&ts->event_work);
487 ct36x_chip_go_sleep(client, ts->data.buf);
489 ts->state = CT36X_STATE_SLEEP;
494 int ct36x_ts_resume(struct i2c_client *client)
496 struct ct36x_ts_info *ts;
498 if (CT36X_TS_CORE_DEBUG)
499 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
501 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
503 if ( ts->state == CT36X_STATE_NORMAL ) return 0;
506 ct36x_platform_hw_reset(ts);
510 ts->state = CT36X_STATE_NORMAL;
515 int __devexit ct36x_ts_remove(struct i2c_client *client)
517 struct ct36x_ts_info *ts;
519 if (CT36X_TS_CORE_DEBUG)
520 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
522 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
524 /* Driver clean up */
525 disable_irq(ts->irq);
526 cancel_work_sync(&ts->event_work);
527 destroy_workqueue(ts->workqueue);
528 input_free_device(ts->input);
529 free_irq(ts->irq, ts);
530 ct36x_platform_put_resource(ts);
531 i2c_unregister_device(client);
532 #ifdef CONFIG_HAS_EARLYSUSPEND
533 unregister_early_suspend(&ts->early_suspend);
535 remove_proc_entry(DRIVER_NAME, NULL);
540 int __init ct36x_ts_init(void)
544 printk("VTL ct36x TouchScreen driver, <george.chen@vtl.com.cn>.\n");
546 ct36x_platform_get_cfg(&ct36x_ts);
548 err = ct36x_platform_set_dev(&ct36x_ts);
549 if ( err ) goto ERR_INIT;
551 err = i2c_add_driver(&ct36x_ts_driver);
552 if ( err ) goto ERR_INIT;
560 void __exit ct36x_ts_exit(void)
562 i2c_del_driver(&ct36x_ts_driver);
565 module_init(ct36x_ts_init);
566 module_exit(ct36x_ts_exit);
568 MODULE_AUTHOR("<george.chen@vtl.com>");
569 MODULE_DESCRIPTION("VTL ct36x TouchScreen driver");
570 MODULE_LICENSE("GPL");