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