]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/input/touchscreen/cyttsp_core.c
Input: cyttsp - I2C driver split into two modules
[karo-tx-linux.git] / drivers / input / touchscreen / cyttsp_core.c
1 /*
2  * Core Source for:
3  * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers.
4  * For use with Cypress Txx3xx parts.
5  * Supported parts include:
6  * CY8CTST341
7  * CY8CTMA340
8  *
9  * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
10  * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * version 2, and only version 2, as published by the
15  * Free Software Foundation.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25  *
26  * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
27  *
28  */
29
30 #include <linux/delay.h>
31 #include <linux/input.h>
32 #include <linux/input/mt.h>
33 #include <linux/gpio.h>
34 #include <linux/interrupt.h>
35 #include <linux/slab.h>
36
37 #include "cyttsp_core.h"
38
39 /* Bootloader number of command keys */
40 #define CY_NUM_BL_KEYS          8
41
42 /* helpers */
43 #define GET_NUM_TOUCHES(x)              ((x) & 0x0F)
44 #define IS_LARGE_AREA(x)                (((x) & 0x10) >> 4)
45 #define IS_BAD_PKT(x)                   ((x) & 0x20)
46 #define IS_VALID_APP(x)                 ((x) & 0x01)
47 #define IS_OPERATIONAL_ERR(x)           ((x) & 0x3F)
48 #define GET_HSTMODE(reg)                (((reg) & 0x70) >> 4)
49 #define GET_BOOTLOADERMODE(reg)         (((reg) & 0x10) >> 4)
50
51 #define CY_REG_BASE                     0x00
52 #define CY_REG_ACT_DIST                 0x1E
53 #define CY_REG_ACT_INTRVL               0x1D
54 #define CY_REG_TCH_TMOUT                (CY_REG_ACT_INTRVL + 1)
55 #define CY_REG_LP_INTRVL                (CY_REG_TCH_TMOUT + 1)
56 #define CY_MAXZ                         255
57 #define CY_DELAY_DFLT                   20 /* ms */
58 #define CY_DELAY_MAX                    500
59 #define CY_ACT_DIST_DFLT                0xF8
60 #define CY_HNDSHK_BIT                   0x80
61 /* device mode bits */
62 #define CY_OPERATE_MODE                 0x00
63 #define CY_SYSINFO_MODE                 0x10
64 /* power mode select bits */
65 #define CY_SOFT_RESET_MODE              0x01 /* return to Bootloader mode */
66 #define CY_DEEP_SLEEP_MODE              0x02
67 #define CY_LOW_POWER_MODE               0x04
68
69 /* Slots management */
70 #define CY_MAX_FINGER                   4
71 #define CY_MAX_ID                       16
72
73 static const u8 bl_command[] = {
74         0x00,                   /* file offset */
75         0xFF,                   /* command */
76         0xA5,                   /* exit bootloader command */
77         0, 1, 2, 3, 4, 5, 6, 7  /* default keys */
78 };
79
80 static int ttsp_read_block_data(struct cyttsp *ts, u8 command,
81                                 u8 length, void *buf)
82 {
83         int error;
84         int tries;
85
86         for (tries = 0; tries < CY_NUM_RETRY; tries++) {
87                 error = ts->bus_ops->read(ts->dev, ts->xfer_buf, command,
88                                 length, buf);
89                 if (!error)
90                         return 0;
91
92                 msleep(CY_DELAY_DFLT);
93         }
94
95         return -EIO;
96 }
97
98 static int ttsp_write_block_data(struct cyttsp *ts, u8 command,
99                                  u8 length, void *buf)
100 {
101         int error;
102         int tries;
103
104         for (tries = 0; tries < CY_NUM_RETRY; tries++) {
105                 error = ts->bus_ops->write(ts->dev, ts->xfer_buf, command,
106                                 length, buf);
107                 if (!error)
108                         return 0;
109
110                 msleep(CY_DELAY_DFLT);
111         }
112
113         return -EIO;
114 }
115
116 static int ttsp_send_command(struct cyttsp *ts, u8 cmd)
117 {
118         return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd);
119 }
120
121 static int cyttsp_load_bl_regs(struct cyttsp *ts)
122 {
123         memset(&ts->bl_data, 0, sizeof(ts->bl_data));
124         ts->bl_data.bl_status = 0x10;
125
126         return ttsp_read_block_data(ts, CY_REG_BASE,
127                                     sizeof(ts->bl_data), &ts->bl_data);
128 }
129
130 static int cyttsp_exit_bl_mode(struct cyttsp *ts)
131 {
132         int error;
133         u8 bl_cmd[sizeof(bl_command)];
134
135         memcpy(bl_cmd, bl_command, sizeof(bl_command));
136         if (ts->pdata->bl_keys)
137                 memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS],
138                         ts->pdata->bl_keys, sizeof(bl_command));
139
140         error = ttsp_write_block_data(ts, CY_REG_BASE,
141                                       sizeof(bl_cmd), bl_cmd);
142         if (error)
143                 return error;
144
145         /* wait for TTSP Device to complete the operation */
146         msleep(CY_DELAY_DFLT);
147
148         error = cyttsp_load_bl_regs(ts);
149         if (error)
150                 return error;
151
152         if (GET_BOOTLOADERMODE(ts->bl_data.bl_status))
153                 return -EIO;
154
155         return 0;
156 }
157
158 static int cyttsp_set_operational_mode(struct cyttsp *ts)
159 {
160         int error;
161
162         error = ttsp_send_command(ts, CY_OPERATE_MODE);
163         if (error)
164                 return error;
165
166         /* wait for TTSP Device to complete switch to Operational mode */
167         error = ttsp_read_block_data(ts, CY_REG_BASE,
168                                      sizeof(ts->xy_data), &ts->xy_data);
169         if (error)
170                 return error;
171
172         return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0;
173 }
174
175 static int cyttsp_set_sysinfo_mode(struct cyttsp *ts)
176 {
177         int error;
178
179         memset(&ts->sysinfo_data, 0, sizeof(ts->sysinfo_data));
180
181         /* switch to sysinfo mode */
182         error = ttsp_send_command(ts, CY_SYSINFO_MODE);
183         if (error)
184                 return error;
185
186         /* read sysinfo registers */
187         msleep(CY_DELAY_DFLT);
188         error = ttsp_read_block_data(ts, CY_REG_BASE, sizeof(ts->sysinfo_data),
189                                       &ts->sysinfo_data);
190         if (error)
191                 return error;
192
193         if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl)
194                 return -EIO;
195
196         return 0;
197 }
198
199 static int cyttsp_set_sysinfo_regs(struct cyttsp *ts)
200 {
201         int retval = 0;
202
203         if (ts->pdata->act_intrvl != CY_ACT_INTRVL_DFLT ||
204             ts->pdata->tch_tmout != CY_TCH_TMOUT_DFLT ||
205             ts->pdata->lp_intrvl != CY_LP_INTRVL_DFLT) {
206
207                 u8 intrvl_ray[] = {
208                         ts->pdata->act_intrvl,
209                         ts->pdata->tch_tmout,
210                         ts->pdata->lp_intrvl
211                 };
212
213                 /* set intrvl registers */
214                 retval = ttsp_write_block_data(ts, CY_REG_ACT_INTRVL,
215                                         sizeof(intrvl_ray), intrvl_ray);
216                 msleep(CY_DELAY_DFLT);
217         }
218
219         return retval;
220 }
221
222 static int cyttsp_soft_reset(struct cyttsp *ts)
223 {
224         unsigned long timeout;
225         int retval;
226
227         /* wait for interrupt to set ready completion */
228         INIT_COMPLETION(ts->bl_ready);
229         ts->state = CY_BL_STATE;
230
231         enable_irq(ts->irq);
232
233         retval = ttsp_send_command(ts, CY_SOFT_RESET_MODE);
234         if (retval)
235                 goto out;
236
237         timeout = wait_for_completion_timeout(&ts->bl_ready,
238                         msecs_to_jiffies(CY_DELAY_DFLT * CY_DELAY_MAX));
239         retval = timeout ? 0 : -EIO;
240
241 out:
242         ts->state = CY_IDLE_STATE;
243         disable_irq(ts->irq);
244         return retval;
245 }
246
247 static int cyttsp_act_dist_setup(struct cyttsp *ts)
248 {
249         u8 act_dist_setup = ts->pdata->act_dist;
250
251         /* Init gesture; active distance setup */
252         return ttsp_write_block_data(ts, CY_REG_ACT_DIST,
253                                 sizeof(act_dist_setup), &act_dist_setup);
254 }
255
256 static void cyttsp_extract_track_ids(struct cyttsp_xydata *xy_data, int *ids)
257 {
258         ids[0] = xy_data->touch12_id >> 4;
259         ids[1] = xy_data->touch12_id & 0xF;
260         ids[2] = xy_data->touch34_id >> 4;
261         ids[3] = xy_data->touch34_id & 0xF;
262 }
263
264 static const struct cyttsp_tch *cyttsp_get_tch(struct cyttsp_xydata *xy_data,
265                                                int idx)
266 {
267         switch (idx) {
268         case 0:
269                 return &xy_data->tch1;
270         case 1:
271                 return &xy_data->tch2;
272         case 2:
273                 return &xy_data->tch3;
274         case 3:
275                 return &xy_data->tch4;
276         default:
277                 return NULL;
278         }
279 }
280
281 static void cyttsp_report_tchdata(struct cyttsp *ts)
282 {
283         struct cyttsp_xydata *xy_data = &ts->xy_data;
284         struct input_dev *input = ts->input;
285         int num_tch = GET_NUM_TOUCHES(xy_data->tt_stat);
286         const struct cyttsp_tch *tch;
287         int ids[CY_MAX_ID];
288         int i;
289         DECLARE_BITMAP(used, CY_MAX_ID);
290
291         if (IS_LARGE_AREA(xy_data->tt_stat) == 1) {
292                 /* terminate all active tracks */
293                 num_tch = 0;
294                 dev_dbg(ts->dev, "%s: Large area detected\n", __func__);
295         } else if (num_tch > CY_MAX_FINGER) {
296                 /* terminate all active tracks */
297                 num_tch = 0;
298                 dev_dbg(ts->dev, "%s: Num touch error detected\n", __func__);
299         } else if (IS_BAD_PKT(xy_data->tt_mode)) {
300                 /* terminate all active tracks */
301                 num_tch = 0;
302                 dev_dbg(ts->dev, "%s: Invalid buffer detected\n", __func__);
303         }
304
305         cyttsp_extract_track_ids(xy_data, ids);
306
307         bitmap_zero(used, CY_MAX_ID);
308
309         for (i = 0; i < num_tch; i++) {
310                 tch = cyttsp_get_tch(xy_data, i);
311
312                 input_mt_slot(input, ids[i]);
313                 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
314                 input_report_abs(input, ABS_MT_POSITION_X, be16_to_cpu(tch->x));
315                 input_report_abs(input, ABS_MT_POSITION_Y, be16_to_cpu(tch->y));
316                 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tch->z);
317
318                 __set_bit(ids[i], used);
319         }
320
321         for (i = 0; i < CY_MAX_ID; i++) {
322                 if (test_bit(i, used))
323                         continue;
324
325                 input_mt_slot(input, i);
326                 input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
327         }
328
329         input_sync(input);
330 }
331
332 static irqreturn_t cyttsp_irq(int irq, void *handle)
333 {
334         struct cyttsp *ts = handle;
335         int error;
336
337         if (unlikely(ts->state == CY_BL_STATE)) {
338                 complete(&ts->bl_ready);
339                 goto out;
340         }
341
342         /* Get touch data from CYTTSP device */
343         error = ttsp_read_block_data(ts, CY_REG_BASE,
344                                  sizeof(struct cyttsp_xydata), &ts->xy_data);
345         if (error)
346                 goto out;
347
348         /* provide flow control handshake */
349         if (ts->pdata->use_hndshk) {
350                 error = ttsp_send_command(ts,
351                                 ts->xy_data.hst_mode ^ CY_HNDSHK_BIT);
352                 if (error)
353                         goto out;
354         }
355
356         if (unlikely(ts->state == CY_IDLE_STATE))
357                 goto out;
358
359         if (GET_BOOTLOADERMODE(ts->xy_data.tt_mode)) {
360                 /*
361                  * TTSP device has reset back to bootloader mode.
362                  * Restore to operational mode.
363                  */
364                 error = cyttsp_exit_bl_mode(ts);
365                 if (error) {
366                         dev_err(ts->dev,
367                                 "Could not return to operational mode, err: %d\n",
368                                 error);
369                         ts->state = CY_IDLE_STATE;
370                 }
371         } else {
372                 cyttsp_report_tchdata(ts);
373         }
374
375 out:
376         return IRQ_HANDLED;
377 }
378
379 static int cyttsp_power_on(struct cyttsp *ts)
380 {
381         int error;
382
383         error = cyttsp_soft_reset(ts);
384         if (error)
385                 return error;
386
387         error = cyttsp_load_bl_regs(ts);
388         if (error)
389                 return error;
390
391         if (GET_BOOTLOADERMODE(ts->bl_data.bl_status) &&
392             IS_VALID_APP(ts->bl_data.bl_status)) {
393                 error = cyttsp_exit_bl_mode(ts);
394                 if (error)
395                         return error;
396         }
397
398         if (GET_HSTMODE(ts->bl_data.bl_file) != CY_OPERATE_MODE ||
399             IS_OPERATIONAL_ERR(ts->bl_data.bl_status)) {
400                 return -ENODEV;
401         }
402
403         error = cyttsp_set_sysinfo_mode(ts);
404         if (error)
405                 return error;
406
407         error = cyttsp_set_sysinfo_regs(ts);
408         if (error)
409                 return error;
410
411         error = cyttsp_set_operational_mode(ts);
412         if (error)
413                 return error;
414
415         /* init active distance */
416         error = cyttsp_act_dist_setup(ts);
417         if (error)
418                 return error;
419
420         ts->state = CY_ACTIVE_STATE;
421
422         return 0;
423 }
424
425 static int cyttsp_enable(struct cyttsp *ts)
426 {
427         int error;
428
429         /*
430          * The device firmware can wake on an I2C or SPI memory slave
431          * address match. So just reading a register is sufficient to
432          * wake up the device. The first read attempt will fail but it
433          * will wake it up making the second read attempt successful.
434          */
435         error = ttsp_read_block_data(ts, CY_REG_BASE,
436                                      sizeof(ts->xy_data), &ts->xy_data);
437         if (error)
438                 return error;
439
440         if (GET_HSTMODE(ts->xy_data.hst_mode))
441                 return -EIO;
442
443         enable_irq(ts->irq);
444
445         return 0;
446 }
447
448 static int cyttsp_disable(struct cyttsp *ts)
449 {
450         int error;
451
452         error = ttsp_send_command(ts, CY_LOW_POWER_MODE);
453         if (error)
454                 return error;
455
456         disable_irq(ts->irq);
457
458         return 0;
459 }
460
461 #ifdef CONFIG_PM_SLEEP
462 static int cyttsp_suspend(struct device *dev)
463 {
464         struct cyttsp *ts = dev_get_drvdata(dev);
465         int retval = 0;
466
467         mutex_lock(&ts->input->mutex);
468
469         if (ts->input->users) {
470                 retval = cyttsp_disable(ts);
471                 if (retval == 0)
472                         ts->suspended = true;
473         }
474
475         mutex_unlock(&ts->input->mutex);
476
477         return retval;
478 }
479
480 static int cyttsp_resume(struct device *dev)
481 {
482         struct cyttsp *ts = dev_get_drvdata(dev);
483
484         mutex_lock(&ts->input->mutex);
485
486         if (ts->input->users)
487                 cyttsp_enable(ts);
488
489         ts->suspended = false;
490
491         mutex_unlock(&ts->input->mutex);
492
493         return 0;
494 }
495
496 #endif
497
498 SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume);
499 EXPORT_SYMBOL_GPL(cyttsp_pm_ops);
500
501 static int cyttsp_open(struct input_dev *dev)
502 {
503         struct cyttsp *ts = input_get_drvdata(dev);
504         int retval = 0;
505
506         if (!ts->suspended)
507                 retval = cyttsp_enable(ts);
508
509         return retval;
510 }
511
512 static void cyttsp_close(struct input_dev *dev)
513 {
514         struct cyttsp *ts = input_get_drvdata(dev);
515
516         if (!ts->suspended)
517                 cyttsp_disable(ts);
518 }
519
520 struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
521                             struct device *dev, int irq, size_t xfer_buf_size)
522 {
523         const struct cyttsp_platform_data *pdata = dev->platform_data;
524         struct cyttsp *ts;
525         struct input_dev *input_dev;
526         int error;
527
528         if (!pdata || !pdata->name || irq <= 0) {
529                 error = -EINVAL;
530                 goto err_out;
531         }
532
533         ts = kzalloc(sizeof(*ts) + xfer_buf_size, GFP_KERNEL);
534         input_dev = input_allocate_device();
535         if (!ts || !input_dev) {
536                 error = -ENOMEM;
537                 goto err_free_mem;
538         }
539
540         ts->dev = dev;
541         ts->input = input_dev;
542         ts->pdata = dev->platform_data;
543         ts->bus_ops = bus_ops;
544         ts->irq = irq;
545
546         init_completion(&ts->bl_ready);
547         snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
548
549         if (pdata->init) {
550                 error = pdata->init();
551                 if (error) {
552                         dev_err(ts->dev, "platform init failed, err: %d\n",
553                                 error);
554                         goto err_free_mem;
555                 }
556         }
557
558         input_dev->name = pdata->name;
559         input_dev->phys = ts->phys;
560         input_dev->id.bustype = bus_ops->bustype;
561         input_dev->dev.parent = ts->dev;
562
563         input_dev->open = cyttsp_open;
564         input_dev->close = cyttsp_close;
565
566         input_set_drvdata(input_dev, ts);
567
568         __set_bit(EV_ABS, input_dev->evbit);
569         input_set_abs_params(input_dev, ABS_MT_POSITION_X,
570                              0, pdata->maxx, 0, 0);
571         input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
572                              0, pdata->maxy, 0, 0);
573         input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
574                              0, CY_MAXZ, 0, 0);
575
576         input_mt_init_slots(input_dev, CY_MAX_ID, 0);
577
578         error = request_threaded_irq(ts->irq, NULL, cyttsp_irq,
579                                      IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
580                                      pdata->name, ts);
581         if (error) {
582                 dev_err(ts->dev, "failed to request IRQ %d, err: %d\n",
583                         ts->irq, error);
584                 goto err_platform_exit;
585         }
586
587         disable_irq(ts->irq);
588
589         error = cyttsp_power_on(ts);
590         if (error)
591                 goto err_free_irq;
592
593         error = input_register_device(input_dev);
594         if (error) {
595                 dev_err(ts->dev, "failed to register input device: %d\n",
596                         error);
597                 goto err_free_irq;
598         }
599
600         return ts;
601
602 err_free_irq:
603         free_irq(ts->irq, ts);
604 err_platform_exit:
605         if (pdata->exit)
606                 pdata->exit();
607 err_free_mem:
608         input_free_device(input_dev);
609         kfree(ts);
610 err_out:
611         return ERR_PTR(error);
612 }
613 EXPORT_SYMBOL_GPL(cyttsp_probe);
614
615 void cyttsp_remove(struct cyttsp *ts)
616 {
617         free_irq(ts->irq, ts);
618         input_unregister_device(ts->input);
619         if (ts->pdata->exit)
620                 ts->pdata->exit();
621         kfree(ts);
622 }
623 EXPORT_SYMBOL_GPL(cyttsp_remove);
624
625 MODULE_LICENSE("GPL");
626 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen driver core");
627 MODULE_AUTHOR("Cypress");