blob: 9b215828997f26080687da41c1073b5ee807d3c7 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Source for:
2 * Cypress CY8CTMA300 Prototype touchscreen driver.
3 * drivers/input/touchscreen/cy8c_ts.c
4 *
5 * Copyright (C) 2009, 2010 Cypress Semiconductor, Inc.
6 * Copyright (c) 2010, 2011 Code Aurora Forum. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2, and only version 2, as published by the
11 * Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 * Cypress reserves the right to make changes without further notice
23 * to the materials described herein. Cypress does not assume any
24 * liability arising out of the application described herein.
25 *
26 * Contact Cypress Semiconductor at www.cypress.com
27 *
28 * History:
29 * (C) 2010 Cypress - Update for GPL distribution
30 * (C) 2009 Cypress - Assume maintenance ownership
31 * (C) 2009 Enea - Original prototype
32 *
33 */
34
35#include <linux/init.h>
36#include <linux/module.h>
37#include <linux/i2c.h>
38#include <linux/input.h>
39#include <linux/slab.h>
40#include <linux/interrupt.h>
41#include <linux/irq.h>
42#include <linux/gpio.h>
43#include <linux/workqueue.h>
44#include <linux/mutex.h>
45#include <linux/delay.h>
46#include <linux/input/cy8c_ts.h>
47#include <linux/pm.h>
48#include <linux/pm_runtime.h>
49
50#if defined(CONFIG_HAS_EARLYSUSPEND)
51#include <linux/earlysuspend.h>
52
53/* Early-suspend level */
54#define CY8C_TS_SUSPEND_LEVEL 1
55#endif
56
57#define CY8CTMA300 0x0
58#define CY8CTMG200 0x1
59
60#define INVALID_DATA 0xff
61
62#define TOUCHSCREEN_TIMEOUT (msecs_to_jiffies(10))
63#define INITIAL_DELAY (msecs_to_jiffies(25000))
64
65struct cy8c_ts_data {
66 u8 x_index;
67 u8 y_index;
68 u8 z_index;
69 u8 id_index;
70 u8 touch_index;
71 u8 data_reg;
72 u8 status_reg;
73 u8 data_size;
74 u8 touch_bytes;
75 u8 update_data;
76 u8 touch_meta_data;
77 u8 finger_size;
78};
79
80static struct cy8c_ts_data devices[] = {
81 [0] = {
82 .x_index = 6,
83 .y_index = 4,
84 .z_index = 3,
85 .id_index = 0,
86 .data_reg = 0x3,
87 .status_reg = 0x1,
88 .update_data = 0x4,
89 .touch_bytes = 8,
90 .touch_meta_data = 3,
91 .finger_size = 70,
92 },
93 [1] = {
94 .x_index = 2,
95 .y_index = 4,
96 .id_index = 6,
97 .data_reg = 0x6,
98 .status_reg = 0x5,
99 .update_data = 0x1,
100 .touch_bytes = 12,
101 .finger_size = 70,
102 },
103};
104
105struct cy8c_ts {
106 struct i2c_client *client;
107 struct input_dev *input;
108 struct delayed_work work;
109 struct workqueue_struct *wq;
110 struct cy8c_ts_platform_data *pdata;
111 struct cy8c_ts_data *dd;
112 u8 *touch_data;
113 u8 device_id;
114 u8 prev_touches;
115 bool is_suspended;
116 bool int_pending;
117 struct mutex sus_lock;
118 u32 pen_irq;
119#if defined(CONFIG_HAS_EARLYSUSPEND)
120 struct early_suspend early_suspend;
121#endif
122};
123
124static inline u16 join_bytes(u8 a, u8 b)
125{
126 u16 ab = 0;
127 ab = ab | a;
128 ab = ab << 8 | b;
129 return ab;
130}
131
132static s32 cy8c_ts_write_reg_u8(struct i2c_client *client, u8 reg, u8 val)
133{
134 s32 data;
135
136 data = i2c_smbus_write_byte_data(client, reg, val);
137 if (data < 0)
138 dev_err(&client->dev, "error %d in writing reg 0x%x\n",
139 data, reg);
140
141 return data;
142}
143
144static s32 cy8c_ts_read_reg_u8(struct i2c_client *client, u8 reg)
145{
146 s32 data;
147
148 data = i2c_smbus_read_byte_data(client, reg);
149 if (data < 0)
150 dev_err(&client->dev, "error %d in reading reg 0x%x\n",
151 data, reg);
152
153 return data;
154}
155
156static int cy8c_ts_read(struct i2c_client *client, u8 reg, u8 *buf, int num)
157{
158 struct i2c_msg xfer_msg[2];
159
160 xfer_msg[0].addr = client->addr;
161 xfer_msg[0].len = 1;
162 xfer_msg[0].flags = 0;
163 xfer_msg[0].buf = &reg;
164
165 xfer_msg[1].addr = client->addr;
166 xfer_msg[1].len = num;
167 xfer_msg[1].flags = I2C_M_RD;
168 xfer_msg[1].buf = buf;
169
170 return i2c_transfer(client->adapter, xfer_msg, 2);
171}
172
173static void report_data(struct cy8c_ts *ts, u16 x, u16 y, u8 pressure, u8 id)
174{
175 if (ts->pdata->swap_xy)
176 swap(x, y);
177
178 /* handle inverting coordinates */
179 if (ts->pdata->invert_x)
180 x = ts->pdata->res_x - x;
181 if (ts->pdata->invert_y)
182 y = ts->pdata->res_y - y;
183
184 input_report_abs(ts->input, ABS_MT_TRACKING_ID, id);
185 input_report_abs(ts->input, ABS_MT_POSITION_X, x);
186 input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
187 input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, pressure);
188 input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, ts->dd->finger_size);
189 input_mt_sync(ts->input);
190}
191
192static void process_tma300_data(struct cy8c_ts *ts)
193{
194 u8 id, pressure, touches, i;
195 u16 x, y;
196
197 touches = ts->touch_data[ts->dd->touch_index];
198
199 for (i = 0; i < touches; i++) {
200 id = ts->touch_data[i * ts->dd->touch_bytes +
201 ts->dd->id_index];
202 pressure = ts->touch_data[i * ts->dd->touch_bytes +
203 ts->dd->z_index];
204 x = join_bytes(ts->touch_data[i * ts->dd->touch_bytes +
205 ts->dd->x_index],
206 ts->touch_data[i * ts->dd->touch_bytes +
207 ts->dd->x_index + 1]);
208 y = join_bytes(ts->touch_data[i * ts->dd->touch_bytes +
209 ts->dd->y_index],
210 ts->touch_data[i * ts->dd->touch_bytes +
211 ts->dd->y_index + 1]);
212
213 report_data(ts, x, y, pressure, id);
214 }
215
216 for (i = 0; i < ts->prev_touches - touches; i++) {
217 input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0);
218 input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, 0);
219 input_mt_sync(ts->input);
220 }
221
222 ts->prev_touches = touches;
223 input_sync(ts->input);
224}
225
226static void process_tmg200_data(struct cy8c_ts *ts)
227{
228 u8 id, touches, i;
229 u16 x, y;
230
231 touches = ts->touch_data[ts->dd->touch_index];
232
233 if (touches > 0) {
234 x = join_bytes(ts->touch_data[ts->dd->x_index],
235 ts->touch_data[ts->dd->x_index+1]);
236 y = join_bytes(ts->touch_data[ts->dd->y_index],
237 ts->touch_data[ts->dd->y_index+1]);
238 id = ts->touch_data[ts->dd->id_index];
239
240 report_data(ts, x, y, 255, id - 1);
241
242 if (touches == 2) {
243 x = join_bytes(ts->touch_data[ts->dd->x_index+5],
244 ts->touch_data[ts->dd->x_index+6]);
245 y = join_bytes(ts->touch_data[ts->dd->y_index+5],
246 ts->touch_data[ts->dd->y_index+6]);
247 id = ts->touch_data[ts->dd->id_index+5];
248
249 report_data(ts, x, y, 255, id - 1);
250 }
251 } else {
252 for (i = 0; i < ts->prev_touches; i++) {
253 input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0);
254 input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, 0);
255 input_mt_sync(ts->input);
256 }
257 }
258
259 input_sync(ts->input);
260 ts->prev_touches = touches;
261}
262
263static void cy8c_ts_xy_worker(struct work_struct *work)
264{
265 int rc;
266 struct cy8c_ts *ts = container_of(work, struct cy8c_ts,
267 work.work);
268
269 mutex_lock(&ts->sus_lock);
270 if (ts->is_suspended == true) {
271 dev_dbg(&ts->client->dev, "TS is supended\n");
272 ts->int_pending = true;
273 mutex_unlock(&ts->sus_lock);
274 return;
275 }
276 mutex_unlock(&ts->sus_lock);
277
278 /* read data from DATA_REG */
279 rc = cy8c_ts_read(ts->client, ts->dd->data_reg, ts->touch_data,
280 ts->dd->data_size);
281 if (rc < 0) {
282 dev_err(&ts->client->dev, "read failed\n");
283 goto schedule;
284 }
285
286 if (ts->touch_data[ts->dd->touch_index] == INVALID_DATA)
287 goto schedule;
288
289 if (ts->device_id == CY8CTMA300)
290 process_tma300_data(ts);
291 else
292 process_tmg200_data(ts);
293
294schedule:
295 enable_irq(ts->pen_irq);
296
297 /* write to STATUS_REG to update coordinates*/
298 rc = cy8c_ts_write_reg_u8(ts->client, ts->dd->status_reg,
299 ts->dd->update_data);
300 if (rc < 0) {
301 dev_err(&ts->client->dev, "write failed, try once more\n");
302
303 rc = cy8c_ts_write_reg_u8(ts->client, ts->dd->status_reg,
304 ts->dd->update_data);
305 if (rc < 0)
306 dev_err(&ts->client->dev, "write failed, exiting\n");
307 }
308}
309
310static irqreturn_t cy8c_ts_irq(int irq, void *dev_id)
311{
312 struct cy8c_ts *ts = dev_id;
313
314 disable_irq_nosync(irq);
315
316 queue_delayed_work(ts->wq, &ts->work, 0);
317
318 return IRQ_HANDLED;
319}
320
321static int cy8c_ts_init_ts(struct i2c_client *client, struct cy8c_ts *ts)
322{
323 struct input_dev *input_device;
324 int rc = 0;
325
326 ts->dd = &devices[ts->device_id];
327
328 if (!ts->pdata->nfingers) {
329 dev_err(&client->dev, "Touches information not specified\n");
330 return -EINVAL;
331 }
332
333 if (ts->device_id == CY8CTMA300) {
334 if (ts->pdata->nfingers > 10) {
335 dev_err(&client->dev, "Touches >=1 & <= 10\n");
336 return -EINVAL;
337 }
338 ts->dd->data_size = ts->pdata->nfingers * ts->dd->touch_bytes +
339 ts->dd->touch_meta_data;
340 ts->dd->touch_index = ts->pdata->nfingers *
341 ts->dd->touch_bytes;
342 } else if (ts->device_id == CY8CTMG200) {
343 if (ts->pdata->nfingers > 2) {
344 dev_err(&client->dev, "Touches >=1 & <= 2\n");
345 return -EINVAL;
346 }
347 ts->dd->data_size = ts->dd->touch_bytes;
348 ts->dd->touch_index = 0x0;
349 }
350
351 ts->touch_data = kzalloc(ts->dd->data_size, GFP_KERNEL);
352 if (!ts->touch_data) {
353 pr_err("%s: Unable to allocate memory\n", __func__);
354 return -ENOMEM;
355 }
356
357 ts->prev_touches = 0;
358
359 input_device = input_allocate_device();
360 if (!input_device) {
361 rc = -ENOMEM;
362 goto error_alloc_dev;
363 }
364
365 ts->input = input_device;
366 input_device->name = ts->pdata->ts_name;
367 input_device->id.bustype = BUS_I2C;
368 input_device->dev.parent = &client->dev;
369 input_set_drvdata(input_device, ts);
370
371 __set_bit(EV_ABS, input_device->evbit);
372
373 input_set_abs_params(input_device, ABS_MT_POSITION_X,
374 ts->pdata->dis_min_x, ts->pdata->dis_max_x, 0, 0);
375 input_set_abs_params(input_device, ABS_MT_POSITION_Y,
376 ts->pdata->dis_min_y, ts->pdata->dis_max_y, 0, 0);
377 input_set_abs_params(input_device, ABS_MT_TOUCH_MAJOR,
378 ts->pdata->min_touch, ts->pdata->max_touch, 0, 0);
379 input_set_abs_params(input_device, ABS_MT_WIDTH_MAJOR,
380 ts->pdata->min_width, ts->pdata->max_width, 0, 0);
381 input_set_abs_params(input_device, ABS_MT_TRACKING_ID,
382 ts->pdata->min_tid, ts->pdata->max_tid, 0, 0);
383
384 ts->wq = create_singlethread_workqueue("kworkqueue_ts");
385 if (!ts->wq) {
386 dev_err(&client->dev, "Could not create workqueue\n");
387 goto error_wq_create;
388 }
389
390 INIT_DELAYED_WORK(&ts->work, cy8c_ts_xy_worker);
391
392 rc = input_register_device(input_device);
393 if (rc)
394 goto error_unreg_device;
395
396 return 0;
397
398error_unreg_device:
399 destroy_workqueue(ts->wq);
400error_wq_create:
401 input_free_device(input_device);
402error_alloc_dev:
403 kfree(ts->touch_data);
404 return rc;
405}
406
407#ifdef CONFIG_PM
408static int cy8c_ts_suspend(struct device *dev)
409{
410 struct cy8c_ts *ts = dev_get_drvdata(dev);
411 int rc = 0;
412
413 if (device_may_wakeup(dev)) {
414 /* mark suspend flag */
415 mutex_lock(&ts->sus_lock);
416 ts->is_suspended = true;
417 mutex_unlock(&ts->sus_lock);
418
419 enable_irq_wake(ts->pen_irq);
420 } else {
421 disable_irq_nosync(ts->pen_irq);
422
423 rc = cancel_delayed_work_sync(&ts->work);
424
425 if (rc) {
426 /* missed the worker, write to STATUS_REG to
427 acknowledge interrupt */
428 rc = cy8c_ts_write_reg_u8(ts->client,
429 ts->dd->status_reg, ts->dd->update_data);
430 if (rc < 0) {
431 dev_err(&ts->client->dev,
432 "write failed, try once more\n");
433
434 rc = cy8c_ts_write_reg_u8(ts->client,
435 ts->dd->status_reg,
436 ts->dd->update_data);
437 if (rc < 0)
438 dev_err(&ts->client->dev,
439 "write failed, exiting\n");
440 }
441
442 enable_irq(ts->pen_irq);
443 }
444
445 gpio_free(ts->pdata->irq_gpio);
446
447 if (ts->pdata->power_on) {
448 rc = ts->pdata->power_on(0);
449 if (rc) {
450 dev_err(dev, "unable to goto suspend\n");
451 return rc;
452 }
453 }
454 }
455 return 0;
456}
457
458static int cy8c_ts_resume(struct device *dev)
459{
460 struct cy8c_ts *ts = dev_get_drvdata(dev);
461 int rc = 0;
462
463 if (device_may_wakeup(dev)) {
464 disable_irq_wake(ts->pen_irq);
465
466 mutex_lock(&ts->sus_lock);
467 ts->is_suspended = false;
468
469 if (ts->int_pending == true) {
470 ts->int_pending = false;
471
472 /* start a delayed work */
473 queue_delayed_work(ts->wq, &ts->work, 0);
474 }
475 mutex_unlock(&ts->sus_lock);
476
477 } else {
478 if (ts->pdata->power_on) {
479 rc = ts->pdata->power_on(1);
480 if (rc) {
481 dev_err(dev, "unable to resume\n");
482 return rc;
483 }
484 }
485
486 /* configure touchscreen interrupt gpio */
487 rc = gpio_request(ts->pdata->irq_gpio, "cy8c_irq_gpio");
488 if (rc) {
489 pr_err("%s: unable to request gpio %d\n",
490 __func__, ts->pdata->irq_gpio);
491 goto err_power_off;
492 }
493
494 rc = gpio_direction_input(ts->pdata->irq_gpio);
495 if (rc) {
496 pr_err("%s: unable to set direction for gpio %d\n",
497 __func__, ts->pdata->irq_gpio);
498 goto err_gpio_free;
499 }
500
501 enable_irq(ts->pen_irq);
Mohan Pallakadf53bc32011-08-09 15:37:33 +0530502
503 /* Clear the status register of the TS controller */
504 rc = cy8c_ts_write_reg_u8(ts->client,
505 ts->dd->status_reg, ts->dd->update_data);
506 if (rc < 0) {
507 dev_err(&ts->client->dev,
508 "write failed, try once more\n");
509
510 rc = cy8c_ts_write_reg_u8(ts->client,
511 ts->dd->status_reg,
512 ts->dd->update_data);
513 if (rc < 0)
514 dev_err(&ts->client->dev,
515 "write failed, exiting\n");
516 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517 }
518 return 0;
519err_gpio_free:
520 gpio_free(ts->pdata->irq_gpio);
521err_power_off:
522 if (ts->pdata->power_on)
523 rc = ts->pdata->power_on(0);
524 return rc;
525}
526
527#ifdef CONFIG_HAS_EARLYSUSPEND
528static void cy8c_ts_early_suspend(struct early_suspend *h)
529{
530 struct cy8c_ts *ts = container_of(h, struct cy8c_ts, early_suspend);
531
532 cy8c_ts_suspend(&ts->client->dev);
533}
534
535static void cy8c_ts_late_resume(struct early_suspend *h)
536{
537 struct cy8c_ts *ts = container_of(h, struct cy8c_ts, early_suspend);
538
539 cy8c_ts_resume(&ts->client->dev);
540}
541#endif
542
543static struct dev_pm_ops cy8c_ts_pm_ops = {
544#ifndef CONFIG_HAS_EARLYSUSPEND
545 .suspend = cy8c_ts_suspend,
546 .resume = cy8c_ts_resume,
547#endif
548};
549#endif
550
551static int __devinit cy8c_ts_probe(struct i2c_client *client,
552 const struct i2c_device_id *id)
553{
554 struct cy8c_ts *ts;
555 struct cy8c_ts_platform_data *pdata = client->dev.platform_data;
556 int rc, temp_reg;
557
558 if (!pdata) {
559 dev_err(&client->dev, "platform data is required!\n");
560 return -EINVAL;
561 }
562
563 if (!i2c_check_functionality(client->adapter,
564 I2C_FUNC_SMBUS_READ_WORD_DATA)) {
565 dev_err(&client->dev, "I2C functionality not supported\n");
566 return -EIO;
567 }
568
569 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
570 if (!ts)
571 return -ENOMEM;
572
573 /* Enable runtime PM ops, start in ACTIVE mode */
574 rc = pm_runtime_set_active(&client->dev);
575 if (rc < 0)
576 dev_dbg(&client->dev, "unable to set runtime pm state\n");
577 pm_runtime_enable(&client->dev);
578
579 ts->client = client;
580 ts->pdata = pdata;
581 i2c_set_clientdata(client, ts);
582 ts->device_id = id->driver_data;
583
584 if (ts->pdata->dev_setup) {
585 rc = ts->pdata->dev_setup(1);
586 if (rc < 0) {
587 dev_err(&client->dev, "dev setup failed\n");
588 goto error_touch_data_alloc;
589 }
590 }
591
592 /* power on the device */
593 if (ts->pdata->power_on) {
594 rc = ts->pdata->power_on(1);
595 if (rc) {
596 pr_err("%s: Unable to power on the device\n", __func__);
597 goto error_dev_setup;
598 }
599 }
600
601 /* read one byte to make sure i2c device exists */
602 if (id->driver_data == CY8CTMA300)
603 temp_reg = 0x01;
604 else
605 temp_reg = 0x05;
606
607 rc = cy8c_ts_read_reg_u8(client, temp_reg);
608 if (rc < 0) {
609 dev_err(&client->dev, "i2c sanity check failed\n");
610 goto error_power_on;
611 }
612
613 ts->is_suspended = false;
614 ts->int_pending = false;
615 mutex_init(&ts->sus_lock);
616
617 rc = cy8c_ts_init_ts(client, ts);
618 if (rc < 0) {
619 dev_err(&client->dev, "CY8CTMG200-TMA300 init failed\n");
620 goto error_mutex_destroy;
621 }
622
623 if (ts->pdata->resout_gpio < 0)
624 goto config_irq_gpio;
625
626 /* configure touchscreen reset out gpio */
627 rc = gpio_request(ts->pdata->resout_gpio, "cy8c_resout_gpio");
628 if (rc) {
629 pr_err("%s: unable to request gpio %d\n",
630 __func__, ts->pdata->resout_gpio);
631 goto error_uninit_ts;
632 }
633
634 rc = gpio_direction_output(ts->pdata->resout_gpio, 0);
635 if (rc) {
636 pr_err("%s: unable to set direction for gpio %d\n",
637 __func__, ts->pdata->resout_gpio);
638 goto error_resout_gpio_dir;
639 }
640 /* reset gpio stabilization time */
641 msleep(20);
642
643config_irq_gpio:
644 /* configure touchscreen interrupt gpio */
645 rc = gpio_request(ts->pdata->irq_gpio, "cy8c_irq_gpio");
646 if (rc) {
647 pr_err("%s: unable to request gpio %d\n",
648 __func__, ts->pdata->irq_gpio);
649 goto error_irq_gpio_req;
650 }
651
652 rc = gpio_direction_input(ts->pdata->irq_gpio);
653 if (rc) {
654 pr_err("%s: unable to set direction for gpio %d\n",
655 __func__, ts->pdata->irq_gpio);
656 goto error_irq_gpio_dir;
657 }
658
659 ts->pen_irq = gpio_to_irq(ts->pdata->irq_gpio);
660 rc = request_irq(ts->pen_irq, cy8c_ts_irq,
661 IRQF_TRIGGER_FALLING,
662 ts->client->dev.driver->name, ts);
663 if (rc) {
664 dev_err(&ts->client->dev, "could not request irq\n");
665 goto error_req_irq_fail;
666 }
667
668 /* Clear the status register of the TS controller */
669 rc = cy8c_ts_write_reg_u8(ts->client, ts->dd->status_reg,
670 ts->dd->update_data);
671 if (rc < 0) {
672 /* Do multiple writes in case of failure */
673 dev_err(&ts->client->dev, "%s: write failed %d"
674 "trying again\n", __func__, rc);
675 rc = cy8c_ts_write_reg_u8(ts->client,
676 ts->dd->status_reg, ts->dd->update_data);
677 if (rc < 0) {
678 dev_err(&ts->client->dev, "%s: write failed"
679 "second time(%d)\n", __func__, rc);
680 }
681 }
682
683 device_init_wakeup(&client->dev, ts->pdata->wakeup);
684
685#ifdef CONFIG_HAS_EARLYSUSPEND
686 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
687 CY8C_TS_SUSPEND_LEVEL;
688 ts->early_suspend.suspend = cy8c_ts_early_suspend;
689 ts->early_suspend.resume = cy8c_ts_late_resume;
690 register_early_suspend(&ts->early_suspend);
691#endif
692
693 return 0;
694error_req_irq_fail:
695error_irq_gpio_dir:
696 gpio_free(ts->pdata->irq_gpio);
697error_irq_gpio_req:
698error_resout_gpio_dir:
699 if (ts->pdata->resout_gpio >= 0)
700 gpio_free(ts->pdata->resout_gpio);
701error_uninit_ts:
702 destroy_workqueue(ts->wq);
703 input_unregister_device(ts->input);
704 kfree(ts->touch_data);
705error_mutex_destroy:
706 mutex_destroy(&ts->sus_lock);
707error_power_on:
708 if (ts->pdata->power_on)
709 ts->pdata->power_on(0);
710error_dev_setup:
711 if (ts->pdata->dev_setup)
712 ts->pdata->dev_setup(0);
713error_touch_data_alloc:
714 pm_runtime_set_suspended(&client->dev);
715 pm_runtime_disable(&client->dev);
716 kfree(ts);
717 return rc;
718}
719
720static int __devexit cy8c_ts_remove(struct i2c_client *client)
721{
722 struct cy8c_ts *ts = i2c_get_clientdata(client);
723
724#if defined(CONFIG_HAS_EARLYSUSPEND)
725 unregister_early_suspend(&ts->early_suspend);
726#endif
727 pm_runtime_set_suspended(&client->dev);
728 pm_runtime_disable(&client->dev);
729
730 device_init_wakeup(&client->dev, 0);
731
732 cancel_delayed_work_sync(&ts->work);
733
734 free_irq(ts->pen_irq, ts);
735
736 gpio_free(ts->pdata->irq_gpio);
737
738 if (ts->pdata->resout_gpio >= 0)
739 gpio_free(ts->pdata->resout_gpio);
740
741 destroy_workqueue(ts->wq);
742
743 input_unregister_device(ts->input);
744
745 mutex_destroy(&ts->sus_lock);
746
747 if (ts->pdata->power_on)
748 ts->pdata->power_on(0);
749
750 if (ts->pdata->dev_setup)
751 ts->pdata->dev_setup(0);
752
753 kfree(ts->touch_data);
754 kfree(ts);
755
756 return 0;
757}
758
759static const struct i2c_device_id cy8c_ts_id[] = {
760 {"cy8ctma300", CY8CTMA300},
761 {"cy8ctmg200", CY8CTMG200},
762 {}
763};
764MODULE_DEVICE_TABLE(i2c, cy8c_ts_id);
765
766
767static struct i2c_driver cy8c_ts_driver = {
768 .driver = {
769 .name = "cy8c_ts",
770 .owner = THIS_MODULE,
771#ifdef CONFIG_PM
772 .pm = &cy8c_ts_pm_ops,
773#endif
774 },
775 .probe = cy8c_ts_probe,
776 .remove = __devexit_p(cy8c_ts_remove),
777 .id_table = cy8c_ts_id,
778};
779
780static int __init cy8c_ts_init(void)
781{
782 return i2c_add_driver(&cy8c_ts_driver);
783}
784/* Making this as late init to avoid power fluctuations
785 * during LCD initialization.
786 */
787late_initcall(cy8c_ts_init);
788
789static void __exit cy8c_ts_exit(void)
790{
791 return i2c_del_driver(&cy8c_ts_driver);
792}
793module_exit(cy8c_ts_exit);
794
795MODULE_LICENSE("GPL");
796MODULE_DESCRIPTION("CY8CTMA300-CY8CTMG200 touchscreen controller driver");
797MODULE_AUTHOR("Cypress");
798MODULE_ALIAS("platform:cy8c_ts");