hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/input/touchscreen/sx8654.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for Semtech SX8654 I2C touchscreen controller.
34 *
....@@ -21,18 +22,18 @@
2122 * Copyright (C) 2002 MontaVista Software
2223 * Copyright (C) 2004 Texas Instruments
2324 * 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.
2825 */
2926
30
-#include <linux/input.h>
31
-#include <linux/module.h>
32
-#include <linux/of.h>
27
+#include <linux/bitops.h>
28
+#include <linux/delay.h>
29
+#include <linux/gpio/consumer.h>
3330 #include <linux/i2c.h>
31
+#include <linux/input.h>
32
+#include <linux/input/touchscreen.h>
3433 #include <linux/interrupt.h>
3534 #include <linux/irq.h>
35
+#include <linux/module.h>
36
+#include <linux/of.h>
3637
3738 /* register addresses */
3839 #define I2C_REG_TOUCH0 0x00
....@@ -42,25 +43,28 @@
4243 #define I2C_REG_IRQSRC 0x23
4344 #define I2C_REG_SOFTRESET 0x3f
4445
46
+#define I2C_REG_SX8650_STAT 0x05
47
+#define SX8650_STAT_CONVIRQ BIT(7)
48
+
4549 /* commands */
4650 #define CMD_READ_REGISTER 0x40
47
-#define CMD_MANUAL 0xc0
4851 #define CMD_PENTRG 0xe0
4952
5053 /* value for I2C_REG_SOFTRESET */
5154 #define SOFTRESET_VALUE 0xde
5255
5356 /* bits for I2C_REG_IRQSRC */
54
-#define IRQ_PENTOUCH_TOUCHCONVDONE 0x08
55
-#define IRQ_PENRELEASE 0x04
57
+#define IRQ_PENTOUCH_TOUCHCONVDONE BIT(3)
58
+#define IRQ_PENRELEASE BIT(2)
5659
5760 /* bits for RegTouch1 */
5861 #define CONDIRQ 0x20
62
+#define RPDNT_100K 0x00
5963 #define FILT_7SA 0x03
6064
6165 /* bits for I2C_REG_CHANMASK */
62
-#define CONV_X 0x80
63
-#define CONV_Y 0x40
66
+#define CONV_X BIT(7)
67
+#define CONV_Y BIT(6)
6468
6569 /* coordinates rate: higher nibble of CTRL0 register */
6670 #define RATE_MANUAL 0x00
....@@ -69,12 +73,121 @@
6973 /* power delay: lower nibble of CTRL0 register */
7074 #define POWDLY_1_1MS 0x0b
7175
76
+/* for sx8650, as we have no pen release IRQ there: timeout in ns following the
77
+ * last PENIRQ after which we assume the pen is lifted.
78
+ */
79
+#define SX8650_PENIRQ_TIMEOUT msecs_to_jiffies(10)
80
+
7281 #define MAX_12BIT ((1 << 12) - 1)
82
+#define MAX_I2C_READ_LEN 10 /* see datasheet section 5.1.5 */
83
+
84
+/* channel definition */
85
+#define CH_X 0x00
86
+#define CH_Y 0x01
87
+
88
+struct sx865x_data {
89
+ u8 cmd_manual;
90
+ u8 chan_mask;
91
+ bool has_irq_penrelease;
92
+ bool has_reg_irqmask;
93
+ irq_handler_t irqh;
94
+};
7395
7496 struct sx8654 {
7597 struct input_dev *input;
7698 struct i2c_client *client;
99
+ struct gpio_desc *gpio_reset;
100
+
101
+ spinlock_t lock; /* for input reporting from irq/timer */
102
+ struct timer_list timer;
103
+
104
+ struct touchscreen_properties props;
105
+
106
+ const struct sx865x_data *data;
77107 };
108
+
109
+static inline void sx865x_penrelease(struct sx8654 *ts)
110
+{
111
+ struct input_dev *input_dev = ts->input;
112
+
113
+ input_report_key(input_dev, BTN_TOUCH, 0);
114
+ input_sync(input_dev);
115
+}
116
+
117
+static void sx865x_penrelease_timer_handler(struct timer_list *t)
118
+{
119
+ struct sx8654 *ts = from_timer(ts, t, timer);
120
+ unsigned long flags;
121
+
122
+ spin_lock_irqsave(&ts->lock, flags);
123
+ sx865x_penrelease(ts);
124
+ spin_unlock_irqrestore(&ts->lock, flags);
125
+ dev_dbg(&ts->client->dev, "penrelease by timer\n");
126
+}
127
+
128
+static irqreturn_t sx8650_irq(int irq, void *handle)
129
+{
130
+ struct sx8654 *ts = handle;
131
+ struct device *dev = &ts->client->dev;
132
+ int len, i;
133
+ unsigned long flags;
134
+ u8 stat;
135
+ u16 x, y;
136
+ u16 ch;
137
+ u16 chdata;
138
+ __be16 data[MAX_I2C_READ_LEN / sizeof(__be16)];
139
+ u8 nchan = hweight32(ts->data->chan_mask);
140
+ u8 readlen = nchan * sizeof(*data);
141
+
142
+ stat = i2c_smbus_read_byte_data(ts->client, CMD_READ_REGISTER
143
+ | I2C_REG_SX8650_STAT);
144
+
145
+ if (!(stat & SX8650_STAT_CONVIRQ)) {
146
+ dev_dbg(dev, "%s ignore stat [0x%02x]", __func__, stat);
147
+ return IRQ_HANDLED;
148
+ }
149
+
150
+ len = i2c_master_recv(ts->client, (u8 *)data, readlen);
151
+ if (len != readlen) {
152
+ dev_dbg(dev, "ignore short recv (%d)\n", len);
153
+ return IRQ_HANDLED;
154
+ }
155
+
156
+ spin_lock_irqsave(&ts->lock, flags);
157
+
158
+ x = 0;
159
+ y = 0;
160
+ for (i = 0; i < nchan; i++) {
161
+ chdata = be16_to_cpu(data[i]);
162
+
163
+ if (unlikely(chdata == 0xFFFF)) {
164
+ dev_dbg(dev, "invalid qualified data @ %d\n", i);
165
+ continue;
166
+ } else if (unlikely(chdata & 0x8000)) {
167
+ dev_warn(dev, "hibit @ %d [0x%04x]\n", i, chdata);
168
+ continue;
169
+ }
170
+
171
+ ch = chdata >> 12;
172
+ if (ch == CH_X)
173
+ x = chdata & MAX_12BIT;
174
+ else if (ch == CH_Y)
175
+ y = chdata & MAX_12BIT;
176
+ else
177
+ dev_warn(dev, "unknown channel %d [0x%04x]\n", ch,
178
+ chdata);
179
+ }
180
+
181
+ touchscreen_report_pos(ts->input, &ts->props, x, y, false);
182
+ input_report_key(ts->input, BTN_TOUCH, 1);
183
+ input_sync(ts->input);
184
+ dev_dbg(dev, "point(%4d,%4d)\n", x, y);
185
+
186
+ mod_timer(&ts->timer, jiffies + SX8650_PENIRQ_TIMEOUT);
187
+ spin_unlock_irqrestore(&ts->lock, flags);
188
+
189
+ return IRQ_HANDLED;
190
+}
78191
79192 static irqreturn_t sx8654_irq(int irq, void *handle)
80193 {
....@@ -112,8 +225,8 @@
112225 x = ((data[0] & 0xf) << 8) | (data[1]);
113226 y = ((data[2] & 0xf) << 8) | (data[3]);
114227
115
- input_report_abs(sx8654->input, ABS_X, x);
116
- input_report_abs(sx8654->input, ABS_Y, y);
228
+ touchscreen_report_pos(sx8654->input, &sx8654->props, x, y,
229
+ false);
117230 input_report_key(sx8654->input, BTN_TOUCH, 1);
118231 input_sync(sx8654->input);
119232
....@@ -122,6 +235,25 @@
122235
123236 out:
124237 return IRQ_HANDLED;
238
+}
239
+
240
+static int sx8654_reset(struct sx8654 *ts)
241
+{
242
+ int err;
243
+
244
+ if (ts->gpio_reset) {
245
+ gpiod_set_value_cansleep(ts->gpio_reset, 1);
246
+ udelay(2); /* Tpulse > 1µs */
247
+ gpiod_set_value_cansleep(ts->gpio_reset, 0);
248
+ } else {
249
+ dev_dbg(&ts->client->dev, "NRST unavailable, try softreset\n");
250
+ err = i2c_smbus_write_byte_data(ts->client, I2C_REG_SOFTRESET,
251
+ SOFTRESET_VALUE);
252
+ if (err)
253
+ return err;
254
+ }
255
+
256
+ return 0;
125257 }
126258
127259 static int sx8654_open(struct input_dev *dev)
....@@ -157,14 +289,17 @@
157289
158290 disable_irq(client->irq);
159291
292
+ if (!sx8654->data->has_irq_penrelease)
293
+ del_timer_sync(&sx8654->timer);
294
+
160295 /* enable manual mode mode */
161
- error = i2c_smbus_write_byte(client, CMD_MANUAL);
296
+ error = i2c_smbus_write_byte(client, sx8654->data->cmd_manual);
162297 if (error) {
163298 dev_err(&client->dev, "writing command CMD_MANUAL failed");
164299 return;
165300 }
166301
167
- error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, 0);
302
+ error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, RATE_MANUAL);
168303 if (error) {
169304 dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed");
170305 return;
....@@ -186,6 +321,31 @@
186321 if (!sx8654)
187322 return -ENOMEM;
188323
324
+ sx8654->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
325
+ GPIOD_OUT_HIGH);
326
+ if (IS_ERR(sx8654->gpio_reset)) {
327
+ error = PTR_ERR(sx8654->gpio_reset);
328
+ if (error != -EPROBE_DEFER)
329
+ dev_err(&client->dev, "unable to get reset-gpio: %d\n",
330
+ error);
331
+ return error;
332
+ }
333
+ dev_dbg(&client->dev, "got GPIO reset pin\n");
334
+
335
+ sx8654->data = device_get_match_data(&client->dev);
336
+ if (!sx8654->data)
337
+ sx8654->data = (const struct sx865x_data *)id->driver_data;
338
+ if (!sx8654->data) {
339
+ dev_err(&client->dev, "invalid or missing device data\n");
340
+ return -EINVAL;
341
+ }
342
+
343
+ if (!sx8654->data->has_irq_penrelease) {
344
+ dev_dbg(&client->dev, "use timer for penrelease\n");
345
+ timer_setup(&sx8654->timer, sx865x_penrelease_timer_handler, 0);
346
+ spin_lock_init(&sx8654->lock);
347
+ }
348
+
189349 input = devm_input_allocate_device(&client->dev);
190350 if (!input)
191351 return -ENOMEM;
....@@ -201,43 +361,46 @@
201361 input_set_abs_params(input, ABS_X, 0, MAX_12BIT, 0, 0);
202362 input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, 0, 0);
203363
364
+ touchscreen_parse_properties(input, false, &sx8654->props);
365
+
204366 sx8654->client = client;
205367 sx8654->input = input;
206368
207369 input_set_drvdata(sx8654->input, sx8654);
208370
209
- error = i2c_smbus_write_byte_data(client, I2C_REG_SOFTRESET,
210
- SOFTRESET_VALUE);
371
+ error = sx8654_reset(sx8654);
211372 if (error) {
212
- dev_err(&client->dev, "writing softreset value failed");
373
+ dev_err(&client->dev, "reset failed");
213374 return error;
214375 }
215376
216377 error = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK,
217
- CONV_X | CONV_Y);
378
+ sx8654->data->chan_mask);
218379 if (error) {
219380 dev_err(&client->dev, "writing to I2C_REG_CHANMASK failed");
220381 return error;
221382 }
222383
223
- error = i2c_smbus_write_byte_data(client, I2C_REG_IRQMASK,
224
- IRQ_PENTOUCH_TOUCHCONVDONE |
225
- IRQ_PENRELEASE);
226
- if (error) {
227
- dev_err(&client->dev, "writing to I2C_REG_IRQMASK failed");
228
- return error;
384
+ if (sx8654->data->has_reg_irqmask) {
385
+ error = i2c_smbus_write_byte_data(client, I2C_REG_IRQMASK,
386
+ IRQ_PENTOUCH_TOUCHCONVDONE |
387
+ IRQ_PENRELEASE);
388
+ if (error) {
389
+ dev_err(&client->dev, "writing I2C_REG_IRQMASK failed");
390
+ return error;
391
+ }
229392 }
230393
231394 error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH1,
232
- CONDIRQ | FILT_7SA);
395
+ CONDIRQ | RPDNT_100K | FILT_7SA);
233396 if (error) {
234397 dev_err(&client->dev, "writing to I2C_REG_TOUCH1 failed");
235398 return error;
236399 }
237400
238401 error = devm_request_threaded_irq(&client->dev, client->irq,
239
- NULL, sx8654_irq,
240
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
402
+ NULL, sx8654->data->irqh,
403
+ IRQF_ONESHOT,
241404 client->name, sx8654);
242405 if (error) {
243406 dev_err(&client->dev,
....@@ -256,17 +419,48 @@
256419 return 0;
257420 }
258421
422
+static const struct sx865x_data sx8650_data = {
423
+ .cmd_manual = 0xb0,
424
+ .has_irq_penrelease = false,
425
+ .has_reg_irqmask = false,
426
+ .chan_mask = (CONV_X | CONV_Y),
427
+ .irqh = sx8650_irq,
428
+};
429
+
430
+static const struct sx865x_data sx8654_data = {
431
+ .cmd_manual = 0xc0,
432
+ .has_irq_penrelease = true,
433
+ .has_reg_irqmask = true,
434
+ .chan_mask = (CONV_X | CONV_Y),
435
+ .irqh = sx8654_irq,
436
+};
437
+
259438 #ifdef CONFIG_OF
260439 static const struct of_device_id sx8654_of_match[] = {
261
- { .compatible = "semtech,sx8654", },
262
- { },
440
+ {
441
+ .compatible = "semtech,sx8650",
442
+ .data = &sx8650_data,
443
+ }, {
444
+ .compatible = "semtech,sx8654",
445
+ .data = &sx8654_data,
446
+ }, {
447
+ .compatible = "semtech,sx8655",
448
+ .data = &sx8654_data,
449
+ }, {
450
+ .compatible = "semtech,sx8656",
451
+ .data = &sx8654_data,
452
+ },
453
+ { }
263454 };
264455 MODULE_DEVICE_TABLE(of, sx8654_of_match);
265456 #endif
266457
267458 static const struct i2c_device_id sx8654_id_table[] = {
268
- { "semtech_sx8654", 0 },
269
- { },
459
+ { .name = "semtech_sx8650", .driver_data = (long)&sx8650_data },
460
+ { .name = "semtech_sx8654", .driver_data = (long)&sx8654_data },
461
+ { .name = "semtech_sx8655", .driver_data = (long)&sx8654_data },
462
+ { .name = "semtech_sx8656", .driver_data = (long)&sx8654_data },
463
+ { }
270464 };
271465 MODULE_DEVICE_TABLE(i2c, sx8654_id_table);
272466