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/regulator/consumer.h>
32 #include <linux/input.h>
33 #include <linux/gpio.h>
39 enum enum_ct36x_ts_cmds {
50 // ****************************************************************************
51 // Globel or static variables
52 // ****************************************************************************
53 static struct ct36x_ts_info ct36x_ts;
56 // ****************************************************************************
57 // Function declaration
58 // ****************************************************************************
59 int ct36x_cmd_list_ind[] = {
69 char ct36x_cmd_list_cmd[] = { 'i','r','v','c','u','b','k',0, };
71 static int ct36x_ts_cmd(char *cmdlist, const char cmd)
76 while ( cmdlist[i] ) {
77 if ( cmd == cmdlist[i] )
78 return ct36x_cmd_list_ind[i];
85 static int ct36x_ts_open(struct inode *inode, struct file *file)
87 if ( CT36X_TS_CORE_DEBUG )
88 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
93 static int ct36x_ts_close(struct inode *inode, struct file *file)
95 if ( CT36X_TS_CORE_DEBUG )
96 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
101 static ssize_t ct36x_ts_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset)
106 if ( CT36X_TS_CORE_DEBUG ) {
107 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
108 printk("%s(): count=0x%x \n", __FUNCTION__, count);
112 cmd = ct36x_ts_cmd(ct36x_cmd_list_cmd, buffer[0]);
115 case CT36X_TS_CHIP_ID:
118 case CT36X_TS_CHIP_RESET:
119 printk("%s(): CT36X_TS_CHIP_RESET\n", __FUNCTION__);
120 ct36x_platform_hw_reset(&ct36x_ts);
123 case CT36X_TS_FW_VER:
126 case CT36X_TS_FW_CHKSUM:
127 printk("%s(): CT36X_TS_FW_CHKSUM\n", __FUNCTION__);
128 rslt = ct36x_chip_get_fwchksum(ct36x_ts.client, ct36x_ts.data.buf);
129 printk("%s(): Fw checksum: 0x%x\n", __FUNCTION__, rslt);
132 case CT36X_TS_FW_UPDATE:
133 printk("%s(): CT36X_TS_FW_UPDATE\n", __FUNCTION__);
134 ct36x_chip_go_bootloader(ct36x_ts.client, ct36x_ts.data.buf);
137 case CT36X_TS_BIN_VER:
140 case CT36X_TS_BIN_CHKSUM:
141 printk("%s(): CT36X_TS_BIN_CHKSUM\n", __FUNCTION__);
142 rslt = ct36x_chip_get_binchksum(ct36x_ts.data.buf);
143 printk("%s(): bin checksum: 0x%x\n", __FUNCTION__, rslt);
147 printk("%s(): No such command (0x%x). \n", __FUNCTION__, buffer[0]);
155 static ssize_t ct36x_ts_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
159 if ( CT36X_TS_CORE_DEBUG ) {
160 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
161 printk("%s(): count=0x%x \n", __FUNCTION__, count);
164 if ( !ct36x_ts.ready )
167 //ct36x_ts_reg_read(ct36x_ts->client, buf[0], buf+1, buf[]);
172 static struct file_operations ct36x_ts_fops = {
173 .owner = THIS_MODULE,
174 .open = ct36x_ts_open,
175 .release = ct36x_ts_close,
176 .write = ct36x_ts_write,
177 .read = ct36x_ts_read,
180 static irqreturn_t ct36x_ts_irq(int irq, void *dev)
182 struct ct36x_ts_info *ts;
184 if ( CT36X_TS_CORE_DEBUG )
185 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
187 ts = (struct ct36x_ts_info *)dev;
189 // touch device is ready??
191 // Disable ts interrupt
192 disable_irq_nosync(ts->irq);
194 queue_work(ts->workqueue, &ts->event_work);
200 static void ct36x_ts_workfunc(struct work_struct *work)
205 struct ct36x_ts_info *ts;
207 if ( CT36X_TS_CORE_DEBUG )
208 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
210 ts = container_of(work, struct ct36x_ts_info, event_work);
212 /* read touch points */
213 ct36x_ts_reg_read(ts->client, ts->i2c_address, (char *) ts->data.pts, sizeof(struct ct36x_finger_info) * CT36X_TS_POINT_NUM);
216 sync = 0; ts->press = 0;
217 for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
218 if ( ts->data.pts[iter].xhi != 0xFF && ts->data.pts[iter].yhi != 0xFF &&
219 (ts->data.pts[iter].status == 1 || ts->data.pts[iter].status == 2) ) {
220 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_XY_SWAP
221 x = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
222 y = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
224 x = (ts->data.pts[iter].xhi<<4)|(ts->data.pts[iter].xlo&0xF);
225 y = (ts->data.pts[iter].yhi<<4)|(ts->data.pts[iter].ylo&0xF);
227 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_X_REVERSE
228 x = CT36X_TS_ABS_X_MAX - x;
230 #ifdef CONFIG_TOUCHSCREEN_CT36X_MISC_Y_REVERSE
231 y = CT36X_TS_ABS_Y_MAX - y;
234 if ( CT36X_TS_EVENT_DEBUG ) {
235 printk("ID: %d\n", ts->data.pts[iter].id);
236 printk("status: %d\n", ts->data.pts[iter].status);
237 printk("X Lo: %d\n", ts->data.pts[iter].xlo);
238 printk("Y Lo: %d\n", ts->data.pts[iter].ylo);
239 printk("X Hi: %d\n", ts->data.pts[iter].xhi);
240 printk("Y Hi: %d\n", ts->data.pts[iter].yhi);
241 printk("X: %d\n", x);
242 printk("Y: %d\n", y);
245 input_report_abs(ts->input, ABS_MT_POSITION_X, x);
246 input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
248 input_mt_sync(ts->input);
251 ts->press |= 0x01 << (ts->data.pts[iter].id - 1);
255 ts->release &= ts->release ^ ts->press;
256 for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) {
257 if ( ts->release & (0x01<<iter) ) {
258 input_mt_sync(ts->input);
262 ts->release = ts->press;
264 if ( sync ) input_sync(ts->input);
266 // Enable ts interrupt
271 static void ct36x_ts_adapter(int state)
273 if ( CT36X_TS_CORE_DEBUG )
274 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
276 if ( !ct36x_ts.ready ) return;
279 #ifdef CONFIG_HAS_EARLYSUSPEND
280 static void ct36x_early_suspend(struct early_suspend *handler)
282 struct ct36x_ts_info *ts;
284 if (CT36X_TS_CORE_DEBUG)
285 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
287 ts = container_of(handler, struct ct36x_ts_info, early_suspend);
289 ct36x_ts_suspend(ts->client, PMSG_SUSPEND);
292 static void ct36x_early_resume(struct early_suspend *handler)
294 struct ct36x_ts_info *ts;
296 if (CT36X_TS_CORE_DEBUG)
297 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
299 ts = container_of(handler, struct ct36x_ts_info, early_suspend);
301 ct36x_ts_resume(ts->client);
305 int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
308 int binchksum, fwchksum;
310 struct ct36x_ts_info *ts;
311 struct ct36x_platform_data *pdata;
314 if ( CT36X_TS_CORE_DEBUG )
315 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
319 pdata = dev->platform_data;
322 ct36x_ts.i2c_address = client->addr;
323 ct36x_ts.rst = pdata->rst;
324 ct36x_ts.ss = pdata->ss;
325 ct36x_platform_get_cfg(&ct36x_ts);
327 ct36x_ts.client = client;
328 i2c_set_clientdata(client, &ct36x_ts);
330 printk("No platform data for device %s.\n", DRIVER_NAME);
332 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
334 /* Create Proc Entry File */
335 ts->proc_entry = create_proc_entry(DRIVER_NAME, 0666/*S_IFREG | S_IRUGO | S_IWUSR*/, NULL);
336 if ( ts->proc_entry == NULL ) {
337 dev_err(dev, "Failed creating proc dir entry file.\n");
339 ts->proc_entry->proc_fops = &ct36x_ts_fops;
342 /* register early suspend */
343 #ifdef CONFIG_HAS_EARLYSUSPEND
344 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
345 ts->early_suspend.suspend = ct36x_early_suspend;
346 ts->early_suspend.resume = ct36x_early_resume;
347 register_early_suspend(&ts->early_suspend);
350 /* Check I2C Functionality */
351 err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
353 dev_err(dev, "Check I2C Functionality Failed.\n");
357 /* Request platform resources (gpio/interrupt pins) */
358 err = ct36x_platform_get_resource(ts);
360 dev_err(dev, "Unable to request platform resource for device %s.\n", DRIVER_NAME);
365 ct36x_platform_hw_reset(ts);
368 // Get binary Checksum
369 binchksum = ct36x_chip_get_binchksum(ts->data.buf);
370 if ( CT36X_TS_CORE_DEBUG )
371 printk("Bin checksum: 0x%x\n", binchksum);
373 // Get firmware Checksum
374 fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
375 if ( CT36X_TS_CORE_DEBUG )
376 printk("Fw checksum: 0x%x\n", fwchksum);
379 while ( binchksum != fwchksum && updcnt--) {
380 /* Update Firmware */
381 ct36x_chip_go_bootloader(client, ts->data.buf);
384 ct36x_platform_hw_reset(ts);
386 // Get firmware Checksum
387 fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf);
388 // if ( CT36X_TS_CORE_DEBUG )
389 printk("Fw checksum: 0x%x\n", fwchksum);
392 printk("Fw update %s. 0x%x, 0x%x\n", binchksum != fwchksum ? "Failed" : "Success", binchksum, fwchksum);
395 ct36x_platform_hw_reset(ts);
397 /* allocate input device */
398 ts->input = input_allocate_device();
400 dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME);
402 goto ERR_INPUT_ALLOC;
405 /* config input device */
406 __set_bit(EV_SYN, ts->input->evbit);
407 __set_bit(EV_KEY, ts->input->evbit);
408 __set_bit(EV_ABS, ts->input->evbit);
410 __set_bit(INPUT_PROP_DIRECT, ts->input->propbit);
412 input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0);
413 input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0);
415 ts->input->name = DRIVER_NAME;
416 ts->input->id.bustype = BUS_I2C;
418 /* register input device */
419 err = input_register_device(ts->input);
421 dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME);
422 goto ERR_INPUT_REGIS;
425 /* Create work queue */
426 INIT_WORK(&ts->event_work, ct36x_ts_workfunc);
427 ts->workqueue = create_singlethread_workqueue(dev_name(&client->dev));
430 err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts);
432 dev_err(dev, "Unable to request irq for device %s.\n", DRIVER_NAME);
436 /* Set device is ready */
438 ts->state = CT36X_STATE_NORMAL;
441 //ct36x_chip_set_adapter_on(client, ts->data.buf);
442 //ct36x_chip_set_adapter_off(client, ts->data.buf);
448 destroy_workqueue(ts->workqueue);
450 input_free_device(ts->input);
453 ct36x_platform_put_resource(ts);
455 #ifdef CONFIG_HAS_EARLYSUSPEND
456 unregister_early_suspend(&ts->early_suspend);
458 remove_proc_entry(DRIVER_NAME, NULL);
462 void ct36x_ts_shutdown(struct i2c_client *client)
464 struct ct36x_ts_info *ts;
466 if (CT36X_TS_CORE_DEBUG)
467 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
469 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
471 ct36x_chip_go_sleep(client, ts->data.buf);
473 #ifdef CONFIG_MACH_RK3188M_F304
474 int ct36x_suspend(struct i2c_client *client, pm_message_t mesg)
476 struct regulator *vcc_tp=NULL;
477 vcc_tp = regulator_get(NULL, "ricoh_ldo3");
479 printk("%s..get vcc_tp error\n",__func__);
482 while(regulator_is_enabled(vcc_tp)>0)
483 regulator_disable(vcc_tp);
484 regulator_put(vcc_tp);
490 int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg)
492 struct ct36x_ts_info *ts;
494 if (CT36X_TS_CORE_DEBUG)
495 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
497 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
499 if ( ts->state == CT36X_STATE_SLEEP ) return 0;
501 disable_irq(ts->irq);
503 cancel_work_sync(&ts->event_work);
505 ct36x_chip_go_sleep(client, ts->data.buf);
507 ts->state = CT36X_STATE_SLEEP;
511 #ifdef CONFIG_MACH_RK3188M_F304
512 int ct36x_resume(struct i2c_client *client)
514 struct regulator *vcc_tp=NULL;
516 vcc_tp = regulator_get(NULL, "ricoh_ldo3");
518 printk("%s..get vcc_tp error\n",__func__);
521 regulator_enable(vcc_tp);
522 regulator_put(vcc_tp);
529 int ct36x_ts_resume(struct i2c_client *client)
531 struct ct36x_ts_info *ts;
533 if (CT36X_TS_CORE_DEBUG)
534 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
536 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
538 if ( ts->state == CT36X_STATE_NORMAL ) return 0;
541 ct36x_platform_hw_reset(ts);
545 ts->state = CT36X_STATE_NORMAL;
550 int __devexit ct36x_ts_remove(struct i2c_client *client)
552 struct ct36x_ts_info *ts;
554 if (CT36X_TS_CORE_DEBUG)
555 printk(">>>>> %s() called <<<<< \n", __FUNCTION__);
557 ts = (struct ct36x_ts_info *)i2c_get_clientdata(client);
559 /* Driver clean up */
560 disable_irq(ts->irq);
561 cancel_work_sync(&ts->event_work);
562 destroy_workqueue(ts->workqueue);
563 input_free_device(ts->input);
564 free_irq(ts->irq, ts);
565 ct36x_platform_put_resource(ts);
566 i2c_unregister_device(client);
567 #ifdef CONFIG_HAS_EARLYSUSPEND
568 unregister_early_suspend(&ts->early_suspend);
570 remove_proc_entry(DRIVER_NAME, NULL);
575 int __init ct36x_ts_init(void)
579 printk("VTL ct36x TouchScreen driver, <george.chen@vtl.com.cn>.\n");
581 ct36x_platform_get_cfg(&ct36x_ts);
583 err = ct36x_platform_set_dev(&ct36x_ts);
584 if ( err ) goto ERR_INIT;
586 err = i2c_add_driver(&ct36x_ts_driver);
587 if ( err ) goto ERR_INIT;
595 void __exit ct36x_ts_exit(void)
597 i2c_del_driver(&ct36x_ts_driver);
600 module_init(ct36x_ts_init);
601 module_exit(ct36x_ts_exit);
603 MODULE_AUTHOR("<george.chen@vtl.com>");
604 MODULE_DESCRIPTION("VTL ct36x TouchScreen driver");
605 MODULE_LICENSE("GPL");