]> Git Repo - linux.git/blob - drivers/input/touchscreen/sx8654.c
Merge tag 'lkdtm-next' of https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux...
[linux.git] / drivers / input / touchscreen / sx8654.c
1 /*
2  * Driver for Semtech SX8654 I2C touchscreen controller.
3  *
4  * Copyright (c) 2015 Armadeus Systems
5  *      Sébastien Szymanski <[email protected]>
6  *
7  * Using code from:
8  *  - sx865x.c
9  *      Copyright (c) 2013 U-MoBo Srl
10  *      Pierluigi Passaro <[email protected]>
11  *  - sx8650.c
12  *      Copyright (c) 2009 Wayne Roberts
13  *  - tsc2007.c
14  *      Copyright (c) 2008 Kwangwoo Lee
15  *  - ads7846.c
16  *      Copyright (c) 2005 David Brownell
17  *      Copyright (c) 2006 Nokia Corporation
18  *  - corgi_ts.c
19  *      Copyright (C) 2004-2005 Richard Purdie
20  *  - omap_ts.[hc], ads7846.h, ts_osk.c
21  *      Copyright (C) 2002 MontaVista Software
22  *      Copyright (C) 2004 Texas Instruments
23  *      Copyright (C) 2005 Dirk Behme
24  *
25  *  This program is free software; you can redistribute it and/or modify
26  *  it under the terms of the GNU General Public License version 2 as
27  *  published by the Free Software Foundation.
28  */
29
30 #include <linux/bitops.h>
31 #include <linux/delay.h>
32 #include <linux/gpio/consumer.h>
33 #include <linux/i2c.h>
34 #include <linux/input.h>
35 #include <linux/input/touchscreen.h>
36 #include <linux/interrupt.h>
37 #include <linux/irq.h>
38 #include <linux/module.h>
39 #include <linux/of.h>
40
41 /* register addresses */
42 #define I2C_REG_TOUCH0                  0x00
43 #define I2C_REG_TOUCH1                  0x01
44 #define I2C_REG_CHANMASK                0x04
45 #define I2C_REG_IRQMASK                 0x22
46 #define I2C_REG_IRQSRC                  0x23
47 #define I2C_REG_SOFTRESET               0x3f
48
49 #define I2C_REG_SX8650_STAT             0x05
50 #define SX8650_STAT_CONVIRQ             BIT(7)
51
52 /* commands */
53 #define CMD_READ_REGISTER               0x40
54 #define CMD_PENTRG                      0xe0
55
56 /* value for I2C_REG_SOFTRESET */
57 #define SOFTRESET_VALUE                 0xde
58
59 /* bits for I2C_REG_IRQSRC */
60 #define IRQ_PENTOUCH_TOUCHCONVDONE      BIT(3)
61 #define IRQ_PENRELEASE                  BIT(2)
62
63 /* bits for RegTouch1 */
64 #define CONDIRQ                         0x20
65 #define RPDNT_100K                      0x00
66 #define FILT_7SA                        0x03
67
68 /* bits for I2C_REG_CHANMASK */
69 #define CONV_X                          BIT(7)
70 #define CONV_Y                          BIT(6)
71
72 /* coordinates rate: higher nibble of CTRL0 register */
73 #define RATE_MANUAL                     0x00
74 #define RATE_5000CPS                    0xf0
75
76 /* power delay: lower nibble of CTRL0 register */
77 #define POWDLY_1_1MS                    0x0b
78
79 /* for sx8650, as we have no pen release IRQ there: timeout in ns following the
80  * last PENIRQ after which we assume the pen is lifted.
81  */
82 #define SX8650_PENIRQ_TIMEOUT           msecs_to_jiffies(10)
83
84 #define MAX_12BIT                       ((1 << 12) - 1)
85 #define MAX_I2C_READ_LEN                10 /* see datasheet section 5.1.5 */
86
87 /* channel definition */
88 #define CH_X                            0x00
89 #define CH_Y                            0x01
90
91 struct sx865x_data {
92         u8 cmd_manual;
93         u8 chan_mask;
94         bool has_irq_penrelease;
95         bool has_reg_irqmask;
96         irq_handler_t irqh;
97 };
98
99 struct sx8654 {
100         struct input_dev *input;
101         struct i2c_client *client;
102         struct gpio_desc *gpio_reset;
103
104         spinlock_t lock;        /* for input reporting from irq/timer */
105         struct timer_list timer;
106
107         struct touchscreen_properties props;
108
109         const struct sx865x_data *data;
110 };
111
112 static inline void sx865x_penrelease(struct sx8654 *ts)
113 {
114         struct input_dev *input_dev = ts->input;
115
116         input_report_key(input_dev, BTN_TOUCH, 0);
117         input_sync(input_dev);
118 }
119
120 static void sx865x_penrelease_timer_handler(struct timer_list *t)
121 {
122         struct sx8654 *ts = from_timer(ts, t, timer);
123         unsigned long flags;
124
125         spin_lock_irqsave(&ts->lock, flags);
126         sx865x_penrelease(ts);
127         spin_unlock_irqrestore(&ts->lock, flags);
128         dev_dbg(&ts->client->dev, "penrelease by timer\n");
129 }
130
131 static irqreturn_t sx8650_irq(int irq, void *handle)
132 {
133         struct sx8654 *ts = handle;
134         struct device *dev = &ts->client->dev;
135         int len, i;
136         unsigned long flags;
137         u8 stat;
138         u16 x, y;
139         u16 ch;
140         u16 chdata;
141         __be16 data[MAX_I2C_READ_LEN / sizeof(__be16)];
142         u8 nchan = hweight32(ts->data->chan_mask);
143         u8 readlen = nchan * sizeof(*data);
144
145         stat = i2c_smbus_read_byte_data(ts->client, CMD_READ_REGISTER
146                                                     | I2C_REG_SX8650_STAT);
147
148         if (!(stat & SX8650_STAT_CONVIRQ)) {
149                 dev_dbg(dev, "%s ignore stat [0x%02x]", __func__, stat);
150                 return IRQ_HANDLED;
151         }
152
153         len = i2c_master_recv(ts->client, (u8 *)data, readlen);
154         if (len != readlen) {
155                 dev_dbg(dev, "ignore short recv (%d)\n", len);
156                 return IRQ_HANDLED;
157         }
158
159         spin_lock_irqsave(&ts->lock, flags);
160
161         x = 0;
162         y = 0;
163         for (i = 0; i < nchan; i++) {
164                 chdata = be16_to_cpu(data[i]);
165
166                 if (unlikely(chdata == 0xFFFF)) {
167                         dev_dbg(dev, "invalid qualified data @ %d\n", i);
168                         continue;
169                 } else if (unlikely(chdata & 0x8000)) {
170                         dev_warn(dev, "hibit @ %d [0x%04x]\n", i, chdata);
171                         continue;
172                 }
173
174                 ch = chdata >> 12;
175                 if (ch == CH_X)
176                         x = chdata & MAX_12BIT;
177                 else if (ch == CH_Y)
178                         y = chdata & MAX_12BIT;
179                 else
180                         dev_warn(dev, "unknown channel %d [0x%04x]\n", ch,
181                                  chdata);
182         }
183
184         touchscreen_report_pos(ts->input, &ts->props, x, y, false);
185         input_report_key(ts->input, BTN_TOUCH, 1);
186         input_sync(ts->input);
187         dev_dbg(dev, "point(%4d,%4d)\n", x, y);
188
189         mod_timer(&ts->timer, jiffies + SX8650_PENIRQ_TIMEOUT);
190         spin_unlock_irqrestore(&ts->lock, flags);
191
192         return IRQ_HANDLED;
193 }
194
195 static irqreturn_t sx8654_irq(int irq, void *handle)
196 {
197         struct sx8654 *sx8654 = handle;
198         int irqsrc;
199         u8 data[4];
200         unsigned int x, y;
201         int retval;
202
203         irqsrc = i2c_smbus_read_byte_data(sx8654->client,
204                                           CMD_READ_REGISTER | I2C_REG_IRQSRC);
205         dev_dbg(&sx8654->client->dev, "irqsrc = 0x%x", irqsrc);
206
207         if (irqsrc < 0)
208                 goto out;
209
210         if (irqsrc & IRQ_PENRELEASE) {
211                 dev_dbg(&sx8654->client->dev, "pen release interrupt");
212
213                 input_report_key(sx8654->input, BTN_TOUCH, 0);
214                 input_sync(sx8654->input);
215         }
216
217         if (irqsrc & IRQ_PENTOUCH_TOUCHCONVDONE) {
218                 dev_dbg(&sx8654->client->dev, "pen touch interrupt");
219
220                 retval = i2c_master_recv(sx8654->client, data, sizeof(data));
221                 if (retval != sizeof(data))
222                         goto out;
223
224                 /* invalid data */
225                 if (unlikely(data[0] & 0x80 || data[2] & 0x80))
226                         goto out;
227
228                 x = ((data[0] & 0xf) << 8) | (data[1]);
229                 y = ((data[2] & 0xf) << 8) | (data[3]);
230
231                 touchscreen_report_pos(sx8654->input, &sx8654->props, x, y,
232                                        false);
233                 input_report_key(sx8654->input, BTN_TOUCH, 1);
234                 input_sync(sx8654->input);
235
236                 dev_dbg(&sx8654->client->dev, "point(%4d,%4d)\n", x, y);
237         }
238
239 out:
240         return IRQ_HANDLED;
241 }
242
243 static int sx8654_reset(struct sx8654 *ts)
244 {
245         int err;
246
247         if (ts->gpio_reset) {
248                 gpiod_set_value_cansleep(ts->gpio_reset, 1);
249                 udelay(2); /* Tpulse > 1µs */
250                 gpiod_set_value_cansleep(ts->gpio_reset, 0);
251         } else {
252                 dev_dbg(&ts->client->dev, "NRST unavailable, try softreset\n");
253                 err = i2c_smbus_write_byte_data(ts->client, I2C_REG_SOFTRESET,
254                                                 SOFTRESET_VALUE);
255                 if (err)
256                         return err;
257         }
258
259         return 0;
260 }
261
262 static int sx8654_open(struct input_dev *dev)
263 {
264         struct sx8654 *sx8654 = input_get_drvdata(dev);
265         struct i2c_client *client = sx8654->client;
266         int error;
267
268         /* enable pen trigger mode */
269         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0,
270                                           RATE_5000CPS | POWDLY_1_1MS);
271         if (error) {
272                 dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed");
273                 return error;
274         }
275
276         error = i2c_smbus_write_byte(client, CMD_PENTRG);
277         if (error) {
278                 dev_err(&client->dev, "writing command CMD_PENTRG failed");
279                 return error;
280         }
281
282         enable_irq(client->irq);
283
284         return 0;
285 }
286
287 static void sx8654_close(struct input_dev *dev)
288 {
289         struct sx8654 *sx8654 = input_get_drvdata(dev);
290         struct i2c_client *client = sx8654->client;
291         int error;
292
293         disable_irq(client->irq);
294
295         if (!sx8654->data->has_irq_penrelease)
296                 del_timer_sync(&sx8654->timer);
297
298         /* enable manual mode mode */
299         error = i2c_smbus_write_byte(client, sx8654->data->cmd_manual);
300         if (error) {
301                 dev_err(&client->dev, "writing command CMD_MANUAL failed");
302                 return;
303         }
304
305         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, RATE_MANUAL);
306         if (error) {
307                 dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed");
308                 return;
309         }
310 }
311
312 static int sx8654_probe(struct i2c_client *client,
313                         const struct i2c_device_id *id)
314 {
315         struct sx8654 *sx8654;
316         struct input_dev *input;
317         int error;
318
319         if (!i2c_check_functionality(client->adapter,
320                                      I2C_FUNC_SMBUS_READ_WORD_DATA))
321                 return -ENXIO;
322
323         sx8654 = devm_kzalloc(&client->dev, sizeof(*sx8654), GFP_KERNEL);
324         if (!sx8654)
325                 return -ENOMEM;
326
327         sx8654->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
328                                                      GPIOD_OUT_HIGH);
329         if (IS_ERR(sx8654->gpio_reset)) {
330                 error = PTR_ERR(sx8654->gpio_reset);
331                 if (error != -EPROBE_DEFER)
332                         dev_err(&client->dev, "unable to get reset-gpio: %d\n",
333                                 error);
334                 return error;
335         }
336         dev_dbg(&client->dev, "got GPIO reset pin\n");
337
338         sx8654->data = device_get_match_data(&client->dev);
339         if (!sx8654->data)
340                 sx8654->data = (const struct sx865x_data *)id->driver_data;
341         if (!sx8654->data) {
342                 dev_err(&client->dev, "invalid or missing device data\n");
343                 return -EINVAL;
344         }
345
346         if (!sx8654->data->has_irq_penrelease) {
347                 dev_dbg(&client->dev, "use timer for penrelease\n");
348                 timer_setup(&sx8654->timer, sx865x_penrelease_timer_handler, 0);
349                 spin_lock_init(&sx8654->lock);
350         }
351
352         input = devm_input_allocate_device(&client->dev);
353         if (!input)
354                 return -ENOMEM;
355
356         input->name = "SX8654 I2C Touchscreen";
357         input->id.bustype = BUS_I2C;
358         input->dev.parent = &client->dev;
359         input->open = sx8654_open;
360         input->close = sx8654_close;
361
362         __set_bit(INPUT_PROP_DIRECT, input->propbit);
363         input_set_capability(input, EV_KEY, BTN_TOUCH);
364         input_set_abs_params(input, ABS_X, 0, MAX_12BIT, 0, 0);
365         input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, 0, 0);
366
367         touchscreen_parse_properties(input, false, &sx8654->props);
368
369         sx8654->client = client;
370         sx8654->input = input;
371
372         input_set_drvdata(sx8654->input, sx8654);
373
374         error = sx8654_reset(sx8654);
375         if (error) {
376                 dev_err(&client->dev, "reset failed");
377                 return error;
378         }
379
380         error = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK,
381                                           sx8654->data->chan_mask);
382         if (error) {
383                 dev_err(&client->dev, "writing to I2C_REG_CHANMASK failed");
384                 return error;
385         }
386
387         if (sx8654->data->has_reg_irqmask) {
388                 error = i2c_smbus_write_byte_data(client, I2C_REG_IRQMASK,
389                                                   IRQ_PENTOUCH_TOUCHCONVDONE |
390                                                         IRQ_PENRELEASE);
391                 if (error) {
392                         dev_err(&client->dev, "writing I2C_REG_IRQMASK failed");
393                         return error;
394                 }
395         }
396
397         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH1,
398                                           CONDIRQ | RPDNT_100K | FILT_7SA);
399         if (error) {
400                 dev_err(&client->dev, "writing to I2C_REG_TOUCH1 failed");
401                 return error;
402         }
403
404         error = devm_request_threaded_irq(&client->dev, client->irq,
405                                           NULL, sx8654->data->irqh,
406                                           IRQF_ONESHOT,
407                                           client->name, sx8654);
408         if (error) {
409                 dev_err(&client->dev,
410                         "Failed to enable IRQ %d, error: %d\n",
411                         client->irq, error);
412                 return error;
413         }
414
415         /* Disable the IRQ, we'll enable it in sx8654_open() */
416         disable_irq(client->irq);
417
418         error = input_register_device(sx8654->input);
419         if (error)
420                 return error;
421
422         return 0;
423 }
424
425 static const struct sx865x_data sx8650_data = {
426         .cmd_manual             = 0xb0,
427         .has_irq_penrelease     = false,
428         .has_reg_irqmask        = false,
429         .chan_mask              = (CONV_X | CONV_Y),
430         .irqh                   = sx8650_irq,
431 };
432
433 static const struct sx865x_data sx8654_data = {
434         .cmd_manual             = 0xc0,
435         .has_irq_penrelease     = true,
436         .has_reg_irqmask        = true,
437         .chan_mask              = (CONV_X | CONV_Y),
438         .irqh                   = sx8654_irq,
439 };
440
441 #ifdef CONFIG_OF
442 static const struct of_device_id sx8654_of_match[] = {
443         {
444                 .compatible = "semtech,sx8650",
445                 .data = &sx8650_data,
446         }, {
447                 .compatible = "semtech,sx8654",
448                 .data = &sx8654_data,
449         }, {
450                 .compatible = "semtech,sx8655",
451                 .data = &sx8654_data,
452         }, {
453                 .compatible = "semtech,sx8656",
454                 .data = &sx8654_data,
455         },
456         { }
457 };
458 MODULE_DEVICE_TABLE(of, sx8654_of_match);
459 #endif
460
461 static const struct i2c_device_id sx8654_id_table[] = {
462         { .name = "semtech_sx8650", .driver_data = (long)&sx8650_data },
463         { .name = "semtech_sx8654", .driver_data = (long)&sx8654_data },
464         { .name = "semtech_sx8655", .driver_data = (long)&sx8654_data },
465         { .name = "semtech_sx8656", .driver_data = (long)&sx8654_data },
466         { }
467 };
468 MODULE_DEVICE_TABLE(i2c, sx8654_id_table);
469
470 static struct i2c_driver sx8654_driver = {
471         .driver = {
472                 .name = "sx8654",
473                 .of_match_table = of_match_ptr(sx8654_of_match),
474         },
475         .id_table = sx8654_id_table,
476         .probe = sx8654_probe,
477 };
478 module_i2c_driver(sx8654_driver);
479
480 MODULE_AUTHOR("Sébastien Szymanski <[email protected]>");
481 MODULE_DESCRIPTION("Semtech SX8654 I2C Touchscreen Driver");
482 MODULE_LICENSE("GPL");
This page took 0.061764 seconds and 4 git commands to generate.