blob: f74f2d58cd348679fa39638e097aea5f602ea0b9 [file] [log] [blame]
Mohan Pallakaa2595072012-01-12 22:23:15 +05301/*
2 *
3 * FocalTech ft5x06 TouchScreen driver.
4 *
5 * Copyright (c) 2010 Focal tech Ltd.
Duy Truong790f06d2013-02-13 16:38:12 -08006 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Mohan Pallakaa2595072012-01-12 22:23:15 +05307 *
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.
11 *
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.
16 *
17 */
18
19#include <linux/i2c.h>
20#include <linux/input.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
23#include <linux/delay.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/gpio.h>
27#include <linux/regulator/consumer.h>
28#include <linux/input/ft5x06_ts.h>
29
30#ifdef CONFIG_HAS_EARLYSUSPEND
31#include <linux/earlysuspend.h>
32/* Early-suspend level */
33#define FT5X06_SUSPEND_LEVEL 1
34#endif
35
36#define CFG_MAX_TOUCH_POINTS 5
37
38#define FT_STARTUP_DLY 150
39#define FT_RESET_DLY 20
40
41#define FT_PRESS 0x7F
42#define FT_MAX_ID 0x0F
43#define FT_TOUCH_STEP 6
44#define FT_TOUCH_X_H_POS 3
45#define FT_TOUCH_X_L_POS 4
46#define FT_TOUCH_Y_H_POS 5
47#define FT_TOUCH_Y_L_POS 6
48#define FT_TOUCH_EVENT_POS 3
49#define FT_TOUCH_ID_POS 5
50
51#define POINT_READ_BUF (3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS)
52
53/*register address*/
54#define FT5X06_REG_PMODE 0xA5
55#define FT5X06_REG_FW_VER 0xA6
56#define FT5X06_REG_POINT_RATE 0x88
57#define FT5X06_REG_THGROUP 0x80
58
59/* power register bits*/
60#define FT5X06_PMODE_ACTIVE 0x00
61#define FT5X06_PMODE_MONITOR 0x01
62#define FT5X06_PMODE_STANDBY 0x02
63#define FT5X06_PMODE_HIBERNATE 0x03
64
65#define FT5X06_VTG_MIN_UV 2600000
66#define FT5X06_VTG_MAX_UV 3300000
67#define FT5X06_I2C_VTG_MIN_UV 1800000
68#define FT5X06_I2C_VTG_MAX_UV 1800000
69
70struct ts_event {
71 u16 x[CFG_MAX_TOUCH_POINTS]; /*x coordinate */
72 u16 y[CFG_MAX_TOUCH_POINTS]; /*y coordinate */
73 /* touch event: 0 -- down; 1-- contact; 2 -- contact */
74 u8 touch_event[CFG_MAX_TOUCH_POINTS];
75 u8 finger_id[CFG_MAX_TOUCH_POINTS]; /*touch ID */
76 u16 pressure;
77 u8 touch_point;
78};
79
80struct ft5x06_ts_data {
81 struct i2c_client *client;
82 struct input_dev *input_dev;
83 struct ts_event event;
84 const struct ft5x06_ts_platform_data *pdata;
85 struct regulator *vdd;
86 struct regulator *vcc_i2c;
87#ifdef CONFIG_HAS_EARLYSUSPEND
88 struct early_suspend early_suspend;
89#endif
90};
91
92static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf,
93 int writelen, char *readbuf, int readlen)
94{
95 int ret;
96
97 if (writelen > 0) {
98 struct i2c_msg msgs[] = {
99 {
100 .addr = client->addr,
101 .flags = 0,
102 .len = writelen,
103 .buf = writebuf,
104 },
105 {
106 .addr = client->addr,
107 .flags = I2C_M_RD,
108 .len = readlen,
109 .buf = readbuf,
110 },
111 };
112 ret = i2c_transfer(client->adapter, msgs, 2);
113 if (ret < 0)
114 dev_err(&client->dev, "%s: i2c read error.\n",
115 __func__);
116 } else {
117 struct i2c_msg msgs[] = {
118 {
119 .addr = client->addr,
120 .flags = I2C_M_RD,
121 .len = readlen,
122 .buf = readbuf,
123 },
124 };
125 ret = i2c_transfer(client->adapter, msgs, 1);
126 if (ret < 0)
127 dev_err(&client->dev, "%s:i2c read error.\n", __func__);
128 }
129 return ret;
130}
131
132static int ft5x06_i2c_write(struct i2c_client *client, char *writebuf,
133 int writelen)
134{
135 int ret;
136
137 struct i2c_msg msgs[] = {
138 {
139 .addr = client->addr,
140 .flags = 0,
141 .len = writelen,
142 .buf = writebuf,
143 },
144 };
145 ret = i2c_transfer(client->adapter, msgs, 1);
146 if (ret < 0)
147 dev_err(&client->dev, "%s: i2c write error.\n", __func__);
148
149 return ret;
150}
151
152static void ft5x06_report_value(struct ft5x06_ts_data *data)
153{
154 struct ts_event *event = &data->event;
155 int i;
156 int fingerdown = 0;
157
158 for (i = 0; i < event->touch_point; i++) {
159 if (event->touch_event[i] == 0 || event->touch_event[i] == 2) {
160 event->pressure = FT_PRESS;
161 fingerdown++;
162 } else {
163 event->pressure = 0;
164 }
165
166 input_report_abs(data->input_dev, ABS_MT_POSITION_X,
167 event->x[i]);
168 input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
169 event->y[i]);
170 input_report_abs(data->input_dev, ABS_MT_PRESSURE,
171 event->pressure);
172 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
173 event->finger_id[i]);
174 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
175 event->pressure);
176 input_mt_sync(data->input_dev);
177 }
178
179 input_report_key(data->input_dev, BTN_TOUCH, !!fingerdown);
180 input_sync(data->input_dev);
181}
182
183static int ft5x06_handle_touchdata(struct ft5x06_ts_data *data)
184{
185 struct ts_event *event = &data->event;
186 int ret, i;
187 u8 buf[POINT_READ_BUF] = { 0 };
188 u8 pointid = FT_MAX_ID;
189
190 ret = ft5x06_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
191 if (ret < 0) {
192 dev_err(&data->client->dev, "%s read touchdata failed.\n",
193 __func__);
194 return ret;
195 }
196 memset(event, 0, sizeof(struct ts_event));
197
198 event->touch_point = 0;
199 for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
200 pointid = (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
201 if (pointid >= FT_MAX_ID)
202 break;
203 else
204 event->touch_point++;
205 event->x[i] =
206 (s16) (buf[FT_TOUCH_X_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
207 8 | (s16) buf[FT_TOUCH_X_L_POS + FT_TOUCH_STEP * i];
208 event->y[i] =
209 (s16) (buf[FT_TOUCH_Y_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
210 8 | (s16) buf[FT_TOUCH_Y_L_POS + FT_TOUCH_STEP * i];
211 event->touch_event[i] =
212 buf[FT_TOUCH_EVENT_POS + FT_TOUCH_STEP * i] >> 6;
213 event->finger_id[i] =
214 (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
215 }
216
217 ft5x06_report_value(data);
218
219 return 0;
220}
221
222static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
223{
224 struct ft5x06_ts_data *data = dev_id;
225 int rc;
226
227 rc = ft5x06_handle_touchdata(data);
228 if (rc)
229 pr_err("%s: handling touchdata failed\n", __func__);
230
231 return IRQ_HANDLED;
232}
233
234static int ft5x06_power_on(struct ft5x06_ts_data *data, bool on)
235{
236 int rc;
237
238 if (!on)
239 goto power_off;
240
241 rc = regulator_enable(data->vdd);
242 if (rc) {
243 dev_err(&data->client->dev,
244 "Regulator vdd enable failed rc=%d\n", rc);
245 return rc;
246 }
247
248 rc = regulator_enable(data->vcc_i2c);
249 if (rc) {
250 dev_err(&data->client->dev,
251 "Regulator vcc_i2c enable failed rc=%d\n", rc);
252 regulator_disable(data->vdd);
253 }
254
255 return rc;
256
257power_off:
258 rc = regulator_disable(data->vdd);
259 if (rc) {
260 dev_err(&data->client->dev,
261 "Regulator vdd disable failed rc=%d\n", rc);
262 return rc;
263 }
264
265 rc = regulator_disable(data->vcc_i2c);
266 if (rc) {
267 dev_err(&data->client->dev,
268 "Regulator vcc_i2c disable failed rc=%d\n", rc);
269 regulator_enable(data->vdd);
270 }
271
272 return rc;
273}
274
275static int ft5x06_power_init(struct ft5x06_ts_data *data, bool on)
276{
277 int rc;
278
279 if (!on)
280 goto pwr_deinit;
281
282 data->vdd = regulator_get(&data->client->dev, "vdd");
283 if (IS_ERR(data->vdd)) {
284 rc = PTR_ERR(data->vdd);
285 dev_err(&data->client->dev,
286 "Regulator get failed vdd rc=%d\n", rc);
287 return rc;
288 }
289
290 if (regulator_count_voltages(data->vdd) > 0) {
291 rc = regulator_set_voltage(data->vdd, FT5X06_VTG_MIN_UV,
292 FT5X06_VTG_MAX_UV);
293 if (rc) {
294 dev_err(&data->client->dev,
295 "Regulator set_vtg failed vdd rc=%d\n", rc);
296 goto reg_vdd_put;
297 }
298 }
299
300 data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c");
301 if (IS_ERR(data->vcc_i2c)) {
302 rc = PTR_ERR(data->vcc_i2c);
303 dev_err(&data->client->dev,
304 "Regulator get failed vcc_i2c rc=%d\n", rc);
305 goto reg_vdd_set_vtg;
306 }
307
308 if (regulator_count_voltages(data->vcc_i2c) > 0) {
309 rc = regulator_set_voltage(data->vcc_i2c, FT5X06_I2C_VTG_MIN_UV,
310 FT5X06_I2C_VTG_MAX_UV);
311 if (rc) {
312 dev_err(&data->client->dev,
313 "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
314 goto reg_vcc_i2c_put;
315 }
316 }
317
318 return 0;
319
320reg_vcc_i2c_put:
321 regulator_put(data->vcc_i2c);
322reg_vdd_set_vtg:
323 if (regulator_count_voltages(data->vdd) > 0)
324 regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
325reg_vdd_put:
326 regulator_put(data->vdd);
327 return rc;
328
329pwr_deinit:
330 if (regulator_count_voltages(data->vdd) > 0)
331 regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
332
333 regulator_put(data->vdd);
334
335 if (regulator_count_voltages(data->vcc_i2c) > 0)
336 regulator_set_voltage(data->vcc_i2c, 0, FT5X06_I2C_VTG_MAX_UV);
337
338 regulator_put(data->vcc_i2c);
339 return 0;
340}
341
342#ifdef CONFIG_PM
343static int ft5x06_ts_suspend(struct device *dev)
344{
345 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
346 char txbuf[2];
347
348 disable_irq(data->client->irq);
349
350 if (gpio_is_valid(data->pdata->reset_gpio)) {
351 txbuf[0] = FT5X06_REG_PMODE;
352 txbuf[1] = FT5X06_PMODE_HIBERNATE;
353 ft5x06_i2c_write(data->client, txbuf, sizeof(txbuf));
354 }
355
356 return 0;
357}
358
359static int ft5x06_ts_resume(struct device *dev)
360{
361 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
362
363 if (gpio_is_valid(data->pdata->reset_gpio)) {
364 gpio_set_value_cansleep(data->pdata->reset_gpio, 0);
365 msleep(FT_RESET_DLY);
366 gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
367 }
368 enable_irq(data->client->irq);
369
370 return 0;
371}
372
373#ifdef CONFIG_HAS_EARLYSUSPEND
374static void ft5x06_ts_early_suspend(struct early_suspend *handler)
375{
376 struct ft5x06_ts_data *data = container_of(handler,
377 struct ft5x06_ts_data,
378 early_suspend);
379
380 ft5x06_ts_suspend(&data->client->dev);
381}
382
383static void ft5x06_ts_late_resume(struct early_suspend *handler)
384{
385 struct ft5x06_ts_data *data = container_of(handler,
386 struct ft5x06_ts_data,
387 early_suspend);
388
389 ft5x06_ts_resume(&data->client->dev);
390}
391#endif
392
393static const struct dev_pm_ops ft5x06_ts_pm_ops = {
394#ifndef CONFIG_HAS_EARLYSUSPEND
395 .suspend = ft5x06_ts_suspend,
396 .resume = ft5x06_ts_resume,
397#endif
398};
399#endif
400
401static int ft5x06_ts_probe(struct i2c_client *client,
402 const struct i2c_device_id *id)
403{
404 const struct ft5x06_ts_platform_data *pdata = client->dev.platform_data;
405 struct ft5x06_ts_data *data;
406 struct input_dev *input_dev;
407 u8 reg_value;
408 u8 reg_addr;
409 int err;
410
411 if (!pdata) {
412 dev_err(&client->dev, "Invalid pdata\n");
413 return -EINVAL;
414 }
415
416 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
417 dev_err(&client->dev, "I2C not supported\n");
418 return -ENODEV;
419 }
420
421 data = kzalloc(sizeof(struct ft5x06_ts_data), GFP_KERNEL);
422 if (!data) {
423 dev_err(&client->dev, "Not enough memory\n");
424 return -ENOMEM;
425 }
426
427 input_dev = input_allocate_device();
428 if (!input_dev) {
429 err = -ENOMEM;
430 dev_err(&client->dev, "failed to allocate input device\n");
431 goto free_mem;
432 }
433
434 data->input_dev = input_dev;
435 data->client = client;
436 data->pdata = pdata;
437
438 input_dev->name = "ft5x06_ts";
439 input_dev->id.bustype = BUS_I2C;
440 input_dev->dev.parent = &client->dev;
441
442 input_set_drvdata(input_dev, data);
443 i2c_set_clientdata(client, data);
444
445 __set_bit(EV_KEY, input_dev->evbit);
446 __set_bit(EV_ABS, input_dev->evbit);
447 __set_bit(BTN_TOUCH, input_dev->keybit);
Amy Malochedd2703d2012-06-20 11:03:56 -0700448 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530449
450 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
451 pdata->x_max, 0, 0);
452 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
453 pdata->y_max, 0, 0);
454 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
455 CFG_MAX_TOUCH_POINTS, 0, 0);
456 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, FT_PRESS, 0, 0);
457 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, FT_PRESS, 0, 0);
458
459 err = input_register_device(input_dev);
460 if (err) {
461 dev_err(&client->dev, "Input device registration failed\n");
462 goto free_inputdev;
463 }
464
465 if (pdata->power_init) {
466 err = pdata->power_init(true);
467 if (err) {
468 dev_err(&client->dev, "power init failed");
469 goto unreg_inputdev;
470 }
471 } else {
472 err = ft5x06_power_init(data, true);
473 if (err) {
474 dev_err(&client->dev, "power init failed");
475 goto unreg_inputdev;
476 }
477 }
478
479 if (pdata->power_on) {
480 err = pdata->power_on(true);
481 if (err) {
482 dev_err(&client->dev, "power on failed");
483 goto pwr_deinit;
484 }
485 } else {
486 err = ft5x06_power_on(data, true);
487 if (err) {
488 dev_err(&client->dev, "power on failed");
489 goto pwr_deinit;
490 }
491 }
492
493 if (gpio_is_valid(pdata->irq_gpio)) {
494 err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio");
495 if (err) {
496 dev_err(&client->dev, "irq gpio request failed");
497 goto pwr_off;
498 }
499 err = gpio_direction_input(pdata->irq_gpio);
500 if (err) {
501 dev_err(&client->dev,
502 "set_direction for irq gpio failed\n");
503 goto free_irq_gpio;
504 }
505 }
506
507 if (gpio_is_valid(pdata->reset_gpio)) {
508 err = gpio_request(pdata->reset_gpio, "ft5x06_reset_gpio");
509 if (err) {
510 dev_err(&client->dev, "reset gpio request failed");
511 goto free_irq_gpio;
512 }
513
514 err = gpio_direction_output(pdata->reset_gpio, 0);
515 if (err) {
516 dev_err(&client->dev,
517 "set_direction for reset gpio failed\n");
518 goto free_reset_gpio;
519 }
520 msleep(FT_RESET_DLY);
521 gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
522 }
523
524 /* make sure CTP already finish startup process */
525 msleep(FT_STARTUP_DLY);
526
527 /*get some register information */
528 reg_addr = FT5X06_REG_FW_VER;
529 err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
530 if (err)
531 dev_err(&client->dev, "version read failed");
532
533 dev_info(&client->dev, "[FTS] Firmware version = 0x%x\n", reg_value);
534
535 reg_addr = FT5X06_REG_POINT_RATE;
536 ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
537 if (err)
538 dev_err(&client->dev, "report rate read failed");
539 dev_info(&client->dev, "[FTS] report rate is %dHz.\n", reg_value * 10);
540
541 reg_addr = FT5X06_REG_THGROUP;
542 err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
543 if (err)
544 dev_err(&client->dev, "threshold read failed");
545 dev_dbg(&client->dev, "[FTS] touch threshold is %d.\n", reg_value * 4);
546
547 err = request_threaded_irq(client->irq, NULL,
548 ft5x06_ts_interrupt, pdata->irqflags,
549 client->dev.driver->name, data);
550 if (err) {
551 dev_err(&client->dev, "request irq failed\n");
552 goto free_reset_gpio;
553 }
554
555#ifdef CONFIG_HAS_EARLYSUSPEND
556 data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
557 FT5X06_SUSPEND_LEVEL;
558 data->early_suspend.suspend = ft5x06_ts_early_suspend;
559 data->early_suspend.resume = ft5x06_ts_late_resume;
560 register_early_suspend(&data->early_suspend);
561#endif
562
563 return 0;
564
565free_reset_gpio:
566 if (gpio_is_valid(pdata->reset_gpio))
567 gpio_free(pdata->reset_gpio);
568free_irq_gpio:
569 if (gpio_is_valid(pdata->irq_gpio))
570 gpio_free(pdata->reset_gpio);
571pwr_off:
572 if (pdata->power_on)
573 pdata->power_on(false);
574 else
575 ft5x06_power_on(data, false);
576pwr_deinit:
577 if (pdata->power_init)
578 pdata->power_init(false);
579 else
580 ft5x06_power_init(data, false);
581unreg_inputdev:
582 input_unregister_device(input_dev);
583 input_dev = NULL;
584free_inputdev:
585 input_free_device(input_dev);
586free_mem:
587 kfree(data);
588 return err;
589}
590
591static int __devexit ft5x06_ts_remove(struct i2c_client *client)
592{
593 struct ft5x06_ts_data *data = i2c_get_clientdata(client);
594
595#ifdef CONFIG_HAS_EARLYSUSPEND
596 unregister_early_suspend(&data->early_suspend);
597#endif
598 free_irq(client->irq, data);
599
600 if (gpio_is_valid(data->pdata->reset_gpio))
601 gpio_free(data->pdata->reset_gpio);
602
603 if (gpio_is_valid(data->pdata->irq_gpio))
604 gpio_free(data->pdata->reset_gpio);
605
606 if (data->pdata->power_on)
607 data->pdata->power_on(false);
608 else
609 ft5x06_power_on(data, false);
610
611 if (data->pdata->power_init)
612 data->pdata->power_init(false);
613 else
614 ft5x06_power_init(data, false);
615
616 input_unregister_device(data->input_dev);
617 kfree(data);
618
619 return 0;
620}
621
622static const struct i2c_device_id ft5x06_ts_id[] = {
623 {"ft5x06_ts", 0},
624 {},
625};
626
627MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id);
628
629static struct i2c_driver ft5x06_ts_driver = {
630 .probe = ft5x06_ts_probe,
631 .remove = __devexit_p(ft5x06_ts_remove),
632 .driver = {
633 .name = "ft5x06_ts",
634 .owner = THIS_MODULE,
635#ifdef CONFIG_PM
636 .pm = &ft5x06_ts_pm_ops,
637#endif
638 },
639 .id_table = ft5x06_ts_id,
640};
641
642static int __init ft5x06_ts_init(void)
643{
644 return i2c_add_driver(&ft5x06_ts_driver);
645}
646module_init(ft5x06_ts_init);
647
648static void __exit ft5x06_ts_exit(void)
649{
650 i2c_del_driver(&ft5x06_ts_driver);
651}
652module_exit(ft5x06_ts_exit);
653
654MODULE_DESCRIPTION("FocalTech ft5x06 TouchScreen driver");
655MODULE_LICENSE("GPL v2");