1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de>
4*4882a593Smuzhiyun * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support)
5*4882a593Smuzhiyun * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun * This is a driver for the EDT "Polytouch" family of touch controllers
10*4882a593Smuzhiyun * based on the FocalTech FT5x06 line of chips.
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * Development of this driver has been sponsored by Glyn:
13*4882a593Smuzhiyun * http://www.glyn.com/Products/Displays
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/debugfs.h>
17*4882a593Smuzhiyun #include <linux/delay.h>
18*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
19*4882a593Smuzhiyun #include <linux/i2c.h>
20*4882a593Smuzhiyun #include <linux/interrupt.h>
21*4882a593Smuzhiyun #include <linux/input.h>
22*4882a593Smuzhiyun #include <linux/input/mt.h>
23*4882a593Smuzhiyun #include <linux/input/touchscreen.h>
24*4882a593Smuzhiyun #include <linux/irq.h>
25*4882a593Smuzhiyun #include <linux/kernel.h>
26*4882a593Smuzhiyun #include <linux/module.h>
27*4882a593Smuzhiyun #include <linux/ratelimit.h>
28*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
29*4882a593Smuzhiyun #include <linux/slab.h>
30*4882a593Smuzhiyun #include <linux/uaccess.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include <asm/unaligned.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define WORK_REGISTER_THRESHOLD 0x00
35*4882a593Smuzhiyun #define WORK_REGISTER_REPORT_RATE 0x08
36*4882a593Smuzhiyun #define WORK_REGISTER_GAIN 0x30
37*4882a593Smuzhiyun #define WORK_REGISTER_OFFSET 0x31
38*4882a593Smuzhiyun #define WORK_REGISTER_NUM_X 0x33
39*4882a593Smuzhiyun #define WORK_REGISTER_NUM_Y 0x34
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #define PMOD_REGISTER_ACTIVE 0x00
42*4882a593Smuzhiyun #define PMOD_REGISTER_HIBERNATE 0x03
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define M09_REGISTER_THRESHOLD 0x80
45*4882a593Smuzhiyun #define M09_REGISTER_GAIN 0x92
46*4882a593Smuzhiyun #define M09_REGISTER_OFFSET 0x93
47*4882a593Smuzhiyun #define M09_REGISTER_NUM_X 0x94
48*4882a593Smuzhiyun #define M09_REGISTER_NUM_Y 0x95
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun #define EV_REGISTER_THRESHOLD 0x40
51*4882a593Smuzhiyun #define EV_REGISTER_GAIN 0x41
52*4882a593Smuzhiyun #define EV_REGISTER_OFFSET_Y 0x45
53*4882a593Smuzhiyun #define EV_REGISTER_OFFSET_X 0x46
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #define NO_REGISTER 0xff
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define WORK_REGISTER_OPMODE 0x3c
58*4882a593Smuzhiyun #define FACTORY_REGISTER_OPMODE 0x01
59*4882a593Smuzhiyun #define PMOD_REGISTER_OPMODE 0xa5
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #define TOUCH_EVENT_DOWN 0x00
62*4882a593Smuzhiyun #define TOUCH_EVENT_UP 0x01
63*4882a593Smuzhiyun #define TOUCH_EVENT_ON 0x02
64*4882a593Smuzhiyun #define TOUCH_EVENT_RESERVED 0x03
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun #define EDT_NAME_LEN 23
67*4882a593Smuzhiyun #define EDT_SWITCH_MODE_RETRIES 10
68*4882a593Smuzhiyun #define EDT_SWITCH_MODE_DELAY 5 /* msec */
69*4882a593Smuzhiyun #define EDT_RAW_DATA_RETRIES 100
70*4882a593Smuzhiyun #define EDT_RAW_DATA_DELAY 1000 /* usec */
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun enum edt_pmode {
73*4882a593Smuzhiyun EDT_PMODE_NOT_SUPPORTED,
74*4882a593Smuzhiyun EDT_PMODE_HIBERNATE,
75*4882a593Smuzhiyun EDT_PMODE_POWEROFF,
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun enum edt_ver {
79*4882a593Smuzhiyun EDT_M06,
80*4882a593Smuzhiyun EDT_M09,
81*4882a593Smuzhiyun EDT_M12,
82*4882a593Smuzhiyun EV_FT,
83*4882a593Smuzhiyun GENERIC_FT,
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun struct edt_reg_addr {
87*4882a593Smuzhiyun int reg_threshold;
88*4882a593Smuzhiyun int reg_report_rate;
89*4882a593Smuzhiyun int reg_gain;
90*4882a593Smuzhiyun int reg_offset;
91*4882a593Smuzhiyun int reg_offset_x;
92*4882a593Smuzhiyun int reg_offset_y;
93*4882a593Smuzhiyun int reg_num_x;
94*4882a593Smuzhiyun int reg_num_y;
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun struct edt_ft5x06_ts_data {
98*4882a593Smuzhiyun struct i2c_client *client;
99*4882a593Smuzhiyun struct input_dev *input;
100*4882a593Smuzhiyun struct touchscreen_properties prop;
101*4882a593Smuzhiyun u16 num_x;
102*4882a593Smuzhiyun u16 num_y;
103*4882a593Smuzhiyun struct regulator *vcc;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun struct gpio_desc *reset_gpio;
106*4882a593Smuzhiyun struct gpio_desc *wake_gpio;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS)
109*4882a593Smuzhiyun struct dentry *debug_dir;
110*4882a593Smuzhiyun u8 *raw_buffer;
111*4882a593Smuzhiyun size_t raw_bufsize;
112*4882a593Smuzhiyun #endif
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun struct mutex mutex;
115*4882a593Smuzhiyun bool factory_mode;
116*4882a593Smuzhiyun enum edt_pmode suspend_mode;
117*4882a593Smuzhiyun int threshold;
118*4882a593Smuzhiyun int gain;
119*4882a593Smuzhiyun int offset;
120*4882a593Smuzhiyun int offset_x;
121*4882a593Smuzhiyun int offset_y;
122*4882a593Smuzhiyun int report_rate;
123*4882a593Smuzhiyun int max_support_points;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun char name[EDT_NAME_LEN];
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun struct edt_reg_addr reg_addr;
128*4882a593Smuzhiyun enum edt_ver version;
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun struct edt_i2c_chip_data {
132*4882a593Smuzhiyun int max_support_points;
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun
edt_ft5x06_ts_readwrite(struct i2c_client * client,u16 wr_len,u8 * wr_buf,u16 rd_len,u8 * rd_buf)135*4882a593Smuzhiyun static int edt_ft5x06_ts_readwrite(struct i2c_client *client,
136*4882a593Smuzhiyun u16 wr_len, u8 *wr_buf,
137*4882a593Smuzhiyun u16 rd_len, u8 *rd_buf)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun struct i2c_msg wrmsg[2];
140*4882a593Smuzhiyun int i = 0;
141*4882a593Smuzhiyun int ret;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun if (wr_len) {
144*4882a593Smuzhiyun wrmsg[i].addr = client->addr;
145*4882a593Smuzhiyun wrmsg[i].flags = 0;
146*4882a593Smuzhiyun wrmsg[i].len = wr_len;
147*4882a593Smuzhiyun wrmsg[i].buf = wr_buf;
148*4882a593Smuzhiyun i++;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun if (rd_len) {
151*4882a593Smuzhiyun wrmsg[i].addr = client->addr;
152*4882a593Smuzhiyun wrmsg[i].flags = I2C_M_RD;
153*4882a593Smuzhiyun wrmsg[i].len = rd_len;
154*4882a593Smuzhiyun wrmsg[i].buf = rd_buf;
155*4882a593Smuzhiyun i++;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun ret = i2c_transfer(client->adapter, wrmsg, i);
159*4882a593Smuzhiyun if (ret < 0)
160*4882a593Smuzhiyun return ret;
161*4882a593Smuzhiyun if (ret != i)
162*4882a593Smuzhiyun return -EIO;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun return 0;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data * tsdata,u8 * buf,int buflen)167*4882a593Smuzhiyun static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
168*4882a593Smuzhiyun u8 *buf, int buflen)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun int i;
171*4882a593Smuzhiyun u8 crc = 0;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun for (i = 0; i < buflen - 1; i++)
174*4882a593Smuzhiyun crc ^= buf[i];
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun if (crc != buf[buflen-1]) {
177*4882a593Smuzhiyun dev_err_ratelimited(&tsdata->client->dev,
178*4882a593Smuzhiyun "crc error: 0x%02x expected, got 0x%02x\n",
179*4882a593Smuzhiyun crc, buf[buflen-1]);
180*4882a593Smuzhiyun return false;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun return true;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
edt_ft5x06_ts_isr(int irq,void * dev_id)186*4882a593Smuzhiyun static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = dev_id;
189*4882a593Smuzhiyun struct device *dev = &tsdata->client->dev;
190*4882a593Smuzhiyun u8 cmd;
191*4882a593Smuzhiyun u8 rdbuf[63];
192*4882a593Smuzhiyun int i, type, x, y, id;
193*4882a593Smuzhiyun int offset, tplen, datalen, crclen;
194*4882a593Smuzhiyun int error;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun switch (tsdata->version) {
197*4882a593Smuzhiyun case EDT_M06:
198*4882a593Smuzhiyun cmd = 0xf9; /* tell the controller to send touch data */
199*4882a593Smuzhiyun offset = 5; /* where the actual touch data starts */
200*4882a593Smuzhiyun tplen = 4; /* data comes in so called frames */
201*4882a593Smuzhiyun crclen = 1; /* length of the crc data */
202*4882a593Smuzhiyun break;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun case EDT_M09:
205*4882a593Smuzhiyun case EDT_M12:
206*4882a593Smuzhiyun case EV_FT:
207*4882a593Smuzhiyun case GENERIC_FT:
208*4882a593Smuzhiyun cmd = 0x0;
209*4882a593Smuzhiyun offset = 3;
210*4882a593Smuzhiyun tplen = 6;
211*4882a593Smuzhiyun crclen = 0;
212*4882a593Smuzhiyun break;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun default:
215*4882a593Smuzhiyun goto out;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun memset(rdbuf, 0, sizeof(rdbuf));
219*4882a593Smuzhiyun datalen = tplen * tsdata->max_support_points + offset + crclen;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(tsdata->client,
222*4882a593Smuzhiyun sizeof(cmd), &cmd,
223*4882a593Smuzhiyun datalen, rdbuf);
224*4882a593Smuzhiyun if (error) {
225*4882a593Smuzhiyun dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
226*4882a593Smuzhiyun error);
227*4882a593Smuzhiyun goto out;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* M09/M12 does not send header or CRC */
231*4882a593Smuzhiyun if (tsdata->version == EDT_M06) {
232*4882a593Smuzhiyun if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
233*4882a593Smuzhiyun rdbuf[2] != datalen) {
234*4882a593Smuzhiyun dev_err_ratelimited(dev,
235*4882a593Smuzhiyun "Unexpected header: %02x%02x%02x!\n",
236*4882a593Smuzhiyun rdbuf[0], rdbuf[1], rdbuf[2]);
237*4882a593Smuzhiyun goto out;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen))
241*4882a593Smuzhiyun goto out;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun for (i = 0; i < tsdata->max_support_points; i++) {
245*4882a593Smuzhiyun u8 *buf = &rdbuf[i * tplen + offset];
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun type = buf[0] >> 6;
248*4882a593Smuzhiyun /* ignore Reserved events */
249*4882a593Smuzhiyun if (type == TOUCH_EVENT_RESERVED)
250*4882a593Smuzhiyun continue;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* M06 sometimes sends bogus coordinates in TOUCH_DOWN */
253*4882a593Smuzhiyun if (tsdata->version == EDT_M06 && type == TOUCH_EVENT_DOWN)
254*4882a593Smuzhiyun continue;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun x = get_unaligned_be16(buf) & 0x0fff;
257*4882a593Smuzhiyun y = get_unaligned_be16(buf + 2) & 0x0fff;
258*4882a593Smuzhiyun /* The FT5x26 send the y coordinate first */
259*4882a593Smuzhiyun if (tsdata->version == EV_FT)
260*4882a593Smuzhiyun swap(x, y);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun id = (buf[2] >> 4) & 0x0f;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun input_mt_slot(tsdata->input, id);
265*4882a593Smuzhiyun if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
266*4882a593Smuzhiyun type != TOUCH_EVENT_UP))
267*4882a593Smuzhiyun touchscreen_report_pos(tsdata->input, &tsdata->prop,
268*4882a593Smuzhiyun x, y, true);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun input_mt_report_pointer_emulation(tsdata->input, true);
272*4882a593Smuzhiyun input_sync(tsdata->input);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun out:
275*4882a593Smuzhiyun return IRQ_HANDLED;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
edt_ft5x06_register_write(struct edt_ft5x06_ts_data * tsdata,u8 addr,u8 value)278*4882a593Smuzhiyun static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
279*4882a593Smuzhiyun u8 addr, u8 value)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun u8 wrbuf[4];
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun switch (tsdata->version) {
284*4882a593Smuzhiyun case EDT_M06:
285*4882a593Smuzhiyun wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
286*4882a593Smuzhiyun wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
287*4882a593Smuzhiyun wrbuf[2] = value;
288*4882a593Smuzhiyun wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
289*4882a593Smuzhiyun return edt_ft5x06_ts_readwrite(tsdata->client, 4,
290*4882a593Smuzhiyun wrbuf, 0, NULL);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun case EDT_M09:
293*4882a593Smuzhiyun case EDT_M12:
294*4882a593Smuzhiyun case EV_FT:
295*4882a593Smuzhiyun case GENERIC_FT:
296*4882a593Smuzhiyun wrbuf[0] = addr;
297*4882a593Smuzhiyun wrbuf[1] = value;
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun return edt_ft5x06_ts_readwrite(tsdata->client, 2,
300*4882a593Smuzhiyun wrbuf, 0, NULL);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun default:
303*4882a593Smuzhiyun return -EINVAL;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
edt_ft5x06_register_read(struct edt_ft5x06_ts_data * tsdata,u8 addr)307*4882a593Smuzhiyun static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
308*4882a593Smuzhiyun u8 addr)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun u8 wrbuf[2], rdbuf[2];
311*4882a593Smuzhiyun int error;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun switch (tsdata->version) {
314*4882a593Smuzhiyun case EDT_M06:
315*4882a593Smuzhiyun wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
316*4882a593Smuzhiyun wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
317*4882a593Smuzhiyun wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
320*4882a593Smuzhiyun rdbuf);
321*4882a593Smuzhiyun if (error)
322*4882a593Smuzhiyun return error;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
325*4882a593Smuzhiyun dev_err(&tsdata->client->dev,
326*4882a593Smuzhiyun "crc error: 0x%02x expected, got 0x%02x\n",
327*4882a593Smuzhiyun wrbuf[0] ^ wrbuf[1] ^ rdbuf[0],
328*4882a593Smuzhiyun rdbuf[1]);
329*4882a593Smuzhiyun return -EIO;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun break;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun case EDT_M09:
334*4882a593Smuzhiyun case EDT_M12:
335*4882a593Smuzhiyun case EV_FT:
336*4882a593Smuzhiyun case GENERIC_FT:
337*4882a593Smuzhiyun wrbuf[0] = addr;
338*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
339*4882a593Smuzhiyun wrbuf, 1, rdbuf);
340*4882a593Smuzhiyun if (error)
341*4882a593Smuzhiyun return error;
342*4882a593Smuzhiyun break;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun default:
345*4882a593Smuzhiyun return -EINVAL;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun return rdbuf[0];
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun struct edt_ft5x06_attribute {
352*4882a593Smuzhiyun struct device_attribute dattr;
353*4882a593Smuzhiyun size_t field_offset;
354*4882a593Smuzhiyun u8 limit_low;
355*4882a593Smuzhiyun u8 limit_high;
356*4882a593Smuzhiyun u8 addr_m06;
357*4882a593Smuzhiyun u8 addr_m09;
358*4882a593Smuzhiyun u8 addr_ev;
359*4882a593Smuzhiyun };
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun #define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, _addr_ev, \
362*4882a593Smuzhiyun _limit_low, _limit_high) \
363*4882a593Smuzhiyun struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
364*4882a593Smuzhiyun .dattr = __ATTR(_field, _mode, \
365*4882a593Smuzhiyun edt_ft5x06_setting_show, \
366*4882a593Smuzhiyun edt_ft5x06_setting_store), \
367*4882a593Smuzhiyun .field_offset = offsetof(struct edt_ft5x06_ts_data, _field), \
368*4882a593Smuzhiyun .addr_m06 = _addr_m06, \
369*4882a593Smuzhiyun .addr_m09 = _addr_m09, \
370*4882a593Smuzhiyun .addr_ev = _addr_ev, \
371*4882a593Smuzhiyun .limit_low = _limit_low, \
372*4882a593Smuzhiyun .limit_high = _limit_high, \
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
edt_ft5x06_setting_show(struct device * dev,struct device_attribute * dattr,char * buf)375*4882a593Smuzhiyun static ssize_t edt_ft5x06_setting_show(struct device *dev,
376*4882a593Smuzhiyun struct device_attribute *dattr,
377*4882a593Smuzhiyun char *buf)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
380*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
381*4882a593Smuzhiyun struct edt_ft5x06_attribute *attr =
382*4882a593Smuzhiyun container_of(dattr, struct edt_ft5x06_attribute, dattr);
383*4882a593Smuzhiyun u8 *field = (u8 *)tsdata + attr->field_offset;
384*4882a593Smuzhiyun int val;
385*4882a593Smuzhiyun size_t count = 0;
386*4882a593Smuzhiyun int error = 0;
387*4882a593Smuzhiyun u8 addr;
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun mutex_lock(&tsdata->mutex);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun if (tsdata->factory_mode) {
392*4882a593Smuzhiyun error = -EIO;
393*4882a593Smuzhiyun goto out;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun switch (tsdata->version) {
397*4882a593Smuzhiyun case EDT_M06:
398*4882a593Smuzhiyun addr = attr->addr_m06;
399*4882a593Smuzhiyun break;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun case EDT_M09:
402*4882a593Smuzhiyun case EDT_M12:
403*4882a593Smuzhiyun case GENERIC_FT:
404*4882a593Smuzhiyun addr = attr->addr_m09;
405*4882a593Smuzhiyun break;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun case EV_FT:
408*4882a593Smuzhiyun addr = attr->addr_ev;
409*4882a593Smuzhiyun break;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun default:
412*4882a593Smuzhiyun error = -ENODEV;
413*4882a593Smuzhiyun goto out;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun if (addr != NO_REGISTER) {
417*4882a593Smuzhiyun val = edt_ft5x06_register_read(tsdata, addr);
418*4882a593Smuzhiyun if (val < 0) {
419*4882a593Smuzhiyun error = val;
420*4882a593Smuzhiyun dev_err(&tsdata->client->dev,
421*4882a593Smuzhiyun "Failed to fetch attribute %s, error %d\n",
422*4882a593Smuzhiyun dattr->attr.name, error);
423*4882a593Smuzhiyun goto out;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun } else {
426*4882a593Smuzhiyun val = *field;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun if (val != *field) {
430*4882a593Smuzhiyun dev_warn(&tsdata->client->dev,
431*4882a593Smuzhiyun "%s: read (%d) and stored value (%d) differ\n",
432*4882a593Smuzhiyun dattr->attr.name, val, *field);
433*4882a593Smuzhiyun *field = val;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun count = scnprintf(buf, PAGE_SIZE, "%d\n", val);
437*4882a593Smuzhiyun out:
438*4882a593Smuzhiyun mutex_unlock(&tsdata->mutex);
439*4882a593Smuzhiyun return error ?: count;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
edt_ft5x06_setting_store(struct device * dev,struct device_attribute * dattr,const char * buf,size_t count)442*4882a593Smuzhiyun static ssize_t edt_ft5x06_setting_store(struct device *dev,
443*4882a593Smuzhiyun struct device_attribute *dattr,
444*4882a593Smuzhiyun const char *buf, size_t count)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
447*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
448*4882a593Smuzhiyun struct edt_ft5x06_attribute *attr =
449*4882a593Smuzhiyun container_of(dattr, struct edt_ft5x06_attribute, dattr);
450*4882a593Smuzhiyun u8 *field = (u8 *)tsdata + attr->field_offset;
451*4882a593Smuzhiyun unsigned int val;
452*4882a593Smuzhiyun int error;
453*4882a593Smuzhiyun u8 addr;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun mutex_lock(&tsdata->mutex);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun if (tsdata->factory_mode) {
458*4882a593Smuzhiyun error = -EIO;
459*4882a593Smuzhiyun goto out;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun error = kstrtouint(buf, 0, &val);
463*4882a593Smuzhiyun if (error)
464*4882a593Smuzhiyun goto out;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun if (val < attr->limit_low || val > attr->limit_high) {
467*4882a593Smuzhiyun error = -ERANGE;
468*4882a593Smuzhiyun goto out;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun switch (tsdata->version) {
472*4882a593Smuzhiyun case EDT_M06:
473*4882a593Smuzhiyun addr = attr->addr_m06;
474*4882a593Smuzhiyun break;
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun case EDT_M09:
477*4882a593Smuzhiyun case EDT_M12:
478*4882a593Smuzhiyun case GENERIC_FT:
479*4882a593Smuzhiyun addr = attr->addr_m09;
480*4882a593Smuzhiyun break;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun case EV_FT:
483*4882a593Smuzhiyun addr = attr->addr_ev;
484*4882a593Smuzhiyun break;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun default:
487*4882a593Smuzhiyun error = -ENODEV;
488*4882a593Smuzhiyun goto out;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun if (addr != NO_REGISTER) {
492*4882a593Smuzhiyun error = edt_ft5x06_register_write(tsdata, addr, val);
493*4882a593Smuzhiyun if (error) {
494*4882a593Smuzhiyun dev_err(&tsdata->client->dev,
495*4882a593Smuzhiyun "Failed to update attribute %s, error: %d\n",
496*4882a593Smuzhiyun dattr->attr.name, error);
497*4882a593Smuzhiyun goto out;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun *field = val;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun out:
503*4882a593Smuzhiyun mutex_unlock(&tsdata->mutex);
504*4882a593Smuzhiyun return error ?: count;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun /* m06, m09: range 0-31, m12: range 0-5 */
508*4882a593Smuzhiyun static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
509*4882a593Smuzhiyun M09_REGISTER_GAIN, EV_REGISTER_GAIN, 0, 31);
510*4882a593Smuzhiyun /* m06, m09: range 0-31, m12: range 0-16 */
511*4882a593Smuzhiyun static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
512*4882a593Smuzhiyun M09_REGISTER_OFFSET, NO_REGISTER, 0, 31);
513*4882a593Smuzhiyun /* m06, m09, m12: no supported, ev_ft: range 0-80 */
514*4882a593Smuzhiyun static EDT_ATTR(offset_x, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
515*4882a593Smuzhiyun EV_REGISTER_OFFSET_X, 0, 80);
516*4882a593Smuzhiyun /* m06, m09, m12: no supported, ev_ft: range 0-80 */
517*4882a593Smuzhiyun static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
518*4882a593Smuzhiyun EV_REGISTER_OFFSET_Y, 0, 80);
519*4882a593Smuzhiyun /* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
520*4882a593Smuzhiyun static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
521*4882a593Smuzhiyun M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
522*4882a593Smuzhiyun /* m06: range 3 to 14, m12: (0x64: 100Hz) */
523*4882a593Smuzhiyun static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
524*4882a593Smuzhiyun NO_REGISTER, NO_REGISTER, 0, 255);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun static struct attribute *edt_ft5x06_attrs[] = {
527*4882a593Smuzhiyun &edt_ft5x06_attr_gain.dattr.attr,
528*4882a593Smuzhiyun &edt_ft5x06_attr_offset.dattr.attr,
529*4882a593Smuzhiyun &edt_ft5x06_attr_offset_x.dattr.attr,
530*4882a593Smuzhiyun &edt_ft5x06_attr_offset_y.dattr.attr,
531*4882a593Smuzhiyun &edt_ft5x06_attr_threshold.dattr.attr,
532*4882a593Smuzhiyun &edt_ft5x06_attr_report_rate.dattr.attr,
533*4882a593Smuzhiyun NULL
534*4882a593Smuzhiyun };
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun static const struct attribute_group edt_ft5x06_attr_group = {
537*4882a593Smuzhiyun .attrs = edt_ft5x06_attrs,
538*4882a593Smuzhiyun };
539*4882a593Smuzhiyun
edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data * tsdata)540*4882a593Smuzhiyun static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
545*4882a593Smuzhiyun tsdata->threshold);
546*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
547*4882a593Smuzhiyun tsdata->gain);
548*4882a593Smuzhiyun if (reg_addr->reg_offset != NO_REGISTER)
549*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
550*4882a593Smuzhiyun tsdata->offset);
551*4882a593Smuzhiyun if (reg_addr->reg_offset_x != NO_REGISTER)
552*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x,
553*4882a593Smuzhiyun tsdata->offset_x);
554*4882a593Smuzhiyun if (reg_addr->reg_offset_y != NO_REGISTER)
555*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y,
556*4882a593Smuzhiyun tsdata->offset_y);
557*4882a593Smuzhiyun if (reg_addr->reg_report_rate != NO_REGISTER)
558*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
559*4882a593Smuzhiyun tsdata->report_rate);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data * tsdata)564*4882a593Smuzhiyun static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun struct i2c_client *client = tsdata->client;
567*4882a593Smuzhiyun int retries = EDT_SWITCH_MODE_RETRIES;
568*4882a593Smuzhiyun int ret;
569*4882a593Smuzhiyun int error;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun if (tsdata->version != EDT_M06) {
572*4882a593Smuzhiyun dev_err(&client->dev,
573*4882a593Smuzhiyun "No factory mode support for non-M06 devices\n");
574*4882a593Smuzhiyun return -EINVAL;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun disable_irq(client->irq);
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun if (!tsdata->raw_buffer) {
580*4882a593Smuzhiyun tsdata->raw_bufsize = tsdata->num_x * tsdata->num_y *
581*4882a593Smuzhiyun sizeof(u16);
582*4882a593Smuzhiyun tsdata->raw_buffer = kzalloc(tsdata->raw_bufsize, GFP_KERNEL);
583*4882a593Smuzhiyun if (!tsdata->raw_buffer) {
584*4882a593Smuzhiyun error = -ENOMEM;
585*4882a593Smuzhiyun goto err_out;
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun /* mode register is 0x3c when in the work mode */
590*4882a593Smuzhiyun error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
591*4882a593Smuzhiyun if (error) {
592*4882a593Smuzhiyun dev_err(&client->dev,
593*4882a593Smuzhiyun "failed to switch to factory mode, error %d\n", error);
594*4882a593Smuzhiyun goto err_out;
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun tsdata->factory_mode = true;
598*4882a593Smuzhiyun do {
599*4882a593Smuzhiyun mdelay(EDT_SWITCH_MODE_DELAY);
600*4882a593Smuzhiyun /* mode register is 0x01 when in factory mode */
601*4882a593Smuzhiyun ret = edt_ft5x06_register_read(tsdata, FACTORY_REGISTER_OPMODE);
602*4882a593Smuzhiyun if (ret == 0x03)
603*4882a593Smuzhiyun break;
604*4882a593Smuzhiyun } while (--retries > 0);
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun if (retries == 0) {
607*4882a593Smuzhiyun dev_err(&client->dev, "not in factory mode after %dms.\n",
608*4882a593Smuzhiyun EDT_SWITCH_MODE_RETRIES * EDT_SWITCH_MODE_DELAY);
609*4882a593Smuzhiyun error = -EIO;
610*4882a593Smuzhiyun goto err_out;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun return 0;
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun err_out:
616*4882a593Smuzhiyun kfree(tsdata->raw_buffer);
617*4882a593Smuzhiyun tsdata->raw_buffer = NULL;
618*4882a593Smuzhiyun tsdata->factory_mode = false;
619*4882a593Smuzhiyun enable_irq(client->irq);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun return error;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun
edt_ft5x06_work_mode(struct edt_ft5x06_ts_data * tsdata)624*4882a593Smuzhiyun static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
625*4882a593Smuzhiyun {
626*4882a593Smuzhiyun struct i2c_client *client = tsdata->client;
627*4882a593Smuzhiyun int retries = EDT_SWITCH_MODE_RETRIES;
628*4882a593Smuzhiyun int ret;
629*4882a593Smuzhiyun int error;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun /* mode register is 0x01 when in the factory mode */
632*4882a593Smuzhiyun error = edt_ft5x06_register_write(tsdata, FACTORY_REGISTER_OPMODE, 0x1);
633*4882a593Smuzhiyun if (error) {
634*4882a593Smuzhiyun dev_err(&client->dev,
635*4882a593Smuzhiyun "failed to switch to work mode, error: %d\n", error);
636*4882a593Smuzhiyun return error;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun tsdata->factory_mode = false;
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun do {
642*4882a593Smuzhiyun mdelay(EDT_SWITCH_MODE_DELAY);
643*4882a593Smuzhiyun /* mode register is 0x01 when in factory mode */
644*4882a593Smuzhiyun ret = edt_ft5x06_register_read(tsdata, WORK_REGISTER_OPMODE);
645*4882a593Smuzhiyun if (ret == 0x01)
646*4882a593Smuzhiyun break;
647*4882a593Smuzhiyun } while (--retries > 0);
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun if (retries == 0) {
650*4882a593Smuzhiyun dev_err(&client->dev, "not in work mode after %dms.\n",
651*4882a593Smuzhiyun EDT_SWITCH_MODE_RETRIES * EDT_SWITCH_MODE_DELAY);
652*4882a593Smuzhiyun tsdata->factory_mode = true;
653*4882a593Smuzhiyun return -EIO;
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun kfree(tsdata->raw_buffer);
657*4882a593Smuzhiyun tsdata->raw_buffer = NULL;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun edt_ft5x06_restore_reg_parameters(tsdata);
660*4882a593Smuzhiyun enable_irq(client->irq);
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun return 0;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun
edt_ft5x06_debugfs_mode_get(void * data,u64 * mode)665*4882a593Smuzhiyun static int edt_ft5x06_debugfs_mode_get(void *data, u64 *mode)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = data;
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun *mode = tsdata->factory_mode;
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun return 0;
672*4882a593Smuzhiyun };
673*4882a593Smuzhiyun
edt_ft5x06_debugfs_mode_set(void * data,u64 mode)674*4882a593Smuzhiyun static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = data;
677*4882a593Smuzhiyun int retval = 0;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun if (mode > 1)
680*4882a593Smuzhiyun return -ERANGE;
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun mutex_lock(&tsdata->mutex);
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun if (mode != tsdata->factory_mode) {
685*4882a593Smuzhiyun retval = mode ? edt_ft5x06_factory_mode(tsdata) :
686*4882a593Smuzhiyun edt_ft5x06_work_mode(tsdata);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun mutex_unlock(&tsdata->mutex);
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun return retval;
692*4882a593Smuzhiyun };
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun DEFINE_SIMPLE_ATTRIBUTE(debugfs_mode_fops, edt_ft5x06_debugfs_mode_get,
695*4882a593Smuzhiyun edt_ft5x06_debugfs_mode_set, "%llu\n");
696*4882a593Smuzhiyun
edt_ft5x06_debugfs_raw_data_read(struct file * file,char __user * buf,size_t count,loff_t * off)697*4882a593Smuzhiyun static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
698*4882a593Smuzhiyun char __user *buf, size_t count, loff_t *off)
699*4882a593Smuzhiyun {
700*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = file->private_data;
701*4882a593Smuzhiyun struct i2c_client *client = tsdata->client;
702*4882a593Smuzhiyun int retries = EDT_RAW_DATA_RETRIES;
703*4882a593Smuzhiyun int val, i, error;
704*4882a593Smuzhiyun size_t read = 0;
705*4882a593Smuzhiyun int colbytes;
706*4882a593Smuzhiyun char wrbuf[3];
707*4882a593Smuzhiyun u8 *rdbuf;
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun if (*off < 0 || *off >= tsdata->raw_bufsize)
710*4882a593Smuzhiyun return 0;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun mutex_lock(&tsdata->mutex);
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun if (!tsdata->factory_mode || !tsdata->raw_buffer) {
715*4882a593Smuzhiyun error = -EIO;
716*4882a593Smuzhiyun goto out;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun error = edt_ft5x06_register_write(tsdata, 0x08, 0x01);
720*4882a593Smuzhiyun if (error) {
721*4882a593Smuzhiyun dev_dbg(&client->dev,
722*4882a593Smuzhiyun "failed to write 0x08 register, error %d\n", error);
723*4882a593Smuzhiyun goto out;
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun do {
727*4882a593Smuzhiyun usleep_range(EDT_RAW_DATA_DELAY, EDT_RAW_DATA_DELAY + 100);
728*4882a593Smuzhiyun val = edt_ft5x06_register_read(tsdata, 0x08);
729*4882a593Smuzhiyun if (val < 1)
730*4882a593Smuzhiyun break;
731*4882a593Smuzhiyun } while (--retries > 0);
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun if (val < 0) {
734*4882a593Smuzhiyun error = val;
735*4882a593Smuzhiyun dev_dbg(&client->dev,
736*4882a593Smuzhiyun "failed to read 0x08 register, error %d\n", error);
737*4882a593Smuzhiyun goto out;
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun if (retries == 0) {
741*4882a593Smuzhiyun dev_dbg(&client->dev,
742*4882a593Smuzhiyun "timed out waiting for register to settle\n");
743*4882a593Smuzhiyun error = -ETIMEDOUT;
744*4882a593Smuzhiyun goto out;
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun rdbuf = tsdata->raw_buffer;
748*4882a593Smuzhiyun colbytes = tsdata->num_y * sizeof(u16);
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun wrbuf[0] = 0xf5;
751*4882a593Smuzhiyun wrbuf[1] = 0x0e;
752*4882a593Smuzhiyun for (i = 0; i < tsdata->num_x; i++) {
753*4882a593Smuzhiyun wrbuf[2] = i; /* column index */
754*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(tsdata->client,
755*4882a593Smuzhiyun sizeof(wrbuf), wrbuf,
756*4882a593Smuzhiyun colbytes, rdbuf);
757*4882a593Smuzhiyun if (error)
758*4882a593Smuzhiyun goto out;
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun rdbuf += colbytes;
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun read = min_t(size_t, count, tsdata->raw_bufsize - *off);
764*4882a593Smuzhiyun if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) {
765*4882a593Smuzhiyun error = -EFAULT;
766*4882a593Smuzhiyun goto out;
767*4882a593Smuzhiyun }
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun *off += read;
770*4882a593Smuzhiyun out:
771*4882a593Smuzhiyun mutex_unlock(&tsdata->mutex);
772*4882a593Smuzhiyun return error ?: read;
773*4882a593Smuzhiyun };
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun static const struct file_operations debugfs_raw_data_fops = {
776*4882a593Smuzhiyun .open = simple_open,
777*4882a593Smuzhiyun .read = edt_ft5x06_debugfs_raw_data_read,
778*4882a593Smuzhiyun };
779*4882a593Smuzhiyun
edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data * tsdata,const char * debugfs_name)780*4882a593Smuzhiyun static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
781*4882a593Smuzhiyun const char *debugfs_name)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun tsdata->debug_dir = debugfs_create_dir(debugfs_name, NULL);
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun debugfs_create_u16("num_x", S_IRUSR, tsdata->debug_dir, &tsdata->num_x);
786*4882a593Smuzhiyun debugfs_create_u16("num_y", S_IRUSR, tsdata->debug_dir, &tsdata->num_y);
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun debugfs_create_file("mode", S_IRUSR | S_IWUSR,
789*4882a593Smuzhiyun tsdata->debug_dir, tsdata, &debugfs_mode_fops);
790*4882a593Smuzhiyun debugfs_create_file("raw_data", S_IRUSR,
791*4882a593Smuzhiyun tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun
edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data * tsdata)794*4882a593Smuzhiyun static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
795*4882a593Smuzhiyun {
796*4882a593Smuzhiyun debugfs_remove_recursive(tsdata->debug_dir);
797*4882a593Smuzhiyun kfree(tsdata->raw_buffer);
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun #else
801*4882a593Smuzhiyun
edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data * tsdata)802*4882a593Smuzhiyun static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
803*4882a593Smuzhiyun {
804*4882a593Smuzhiyun return -ENOSYS;
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun
edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data * tsdata,const char * debugfs_name)807*4882a593Smuzhiyun static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
808*4882a593Smuzhiyun const char *debugfs_name)
809*4882a593Smuzhiyun {
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun
edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data * tsdata)812*4882a593Smuzhiyun static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
813*4882a593Smuzhiyun {
814*4882a593Smuzhiyun }
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun #endif /* CONFIG_DEBUGFS */
817*4882a593Smuzhiyun
edt_ft5x06_ts_identify(struct i2c_client * client,struct edt_ft5x06_ts_data * tsdata,char * fw_version)818*4882a593Smuzhiyun static int edt_ft5x06_ts_identify(struct i2c_client *client,
819*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata,
820*4882a593Smuzhiyun char *fw_version)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun u8 rdbuf[EDT_NAME_LEN];
823*4882a593Smuzhiyun char *p;
824*4882a593Smuzhiyun int error;
825*4882a593Smuzhiyun char *model_name = tsdata->name;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun /* see what we find if we assume it is a M06 *
828*4882a593Smuzhiyun * if we get less than EDT_NAME_LEN, we don't want
829*4882a593Smuzhiyun * to have garbage in there
830*4882a593Smuzhiyun */
831*4882a593Smuzhiyun memset(rdbuf, 0, sizeof(rdbuf));
832*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(client, 1, "\xBB",
833*4882a593Smuzhiyun EDT_NAME_LEN - 1, rdbuf);
834*4882a593Smuzhiyun if (error)
835*4882a593Smuzhiyun return error;
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun /* Probe content for something consistent.
838*4882a593Smuzhiyun * M06 starts with a response byte, M12 gives the data directly.
839*4882a593Smuzhiyun * M09/Generic does not provide model number information.
840*4882a593Smuzhiyun */
841*4882a593Smuzhiyun if (!strncasecmp(rdbuf + 1, "EP0", 3)) {
842*4882a593Smuzhiyun tsdata->version = EDT_M06;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun /* remove last '$' end marker */
845*4882a593Smuzhiyun rdbuf[EDT_NAME_LEN - 1] = '\0';
846*4882a593Smuzhiyun if (rdbuf[EDT_NAME_LEN - 2] == '$')
847*4882a593Smuzhiyun rdbuf[EDT_NAME_LEN - 2] = '\0';
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun /* look for Model/Version separator */
850*4882a593Smuzhiyun p = strchr(rdbuf, '*');
851*4882a593Smuzhiyun if (p)
852*4882a593Smuzhiyun *p++ = '\0';
853*4882a593Smuzhiyun strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
854*4882a593Smuzhiyun strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
855*4882a593Smuzhiyun } else if (!strncasecmp(rdbuf, "EP0", 3)) {
856*4882a593Smuzhiyun tsdata->version = EDT_M12;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun /* remove last '$' end marker */
859*4882a593Smuzhiyun rdbuf[EDT_NAME_LEN - 2] = '\0';
860*4882a593Smuzhiyun if (rdbuf[EDT_NAME_LEN - 3] == '$')
861*4882a593Smuzhiyun rdbuf[EDT_NAME_LEN - 3] = '\0';
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun /* look for Model/Version separator */
864*4882a593Smuzhiyun p = strchr(rdbuf, '*');
865*4882a593Smuzhiyun if (p)
866*4882a593Smuzhiyun *p++ = '\0';
867*4882a593Smuzhiyun strlcpy(model_name, rdbuf, EDT_NAME_LEN);
868*4882a593Smuzhiyun strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
869*4882a593Smuzhiyun } else {
870*4882a593Smuzhiyun /* If it is not an EDT M06/M12 touchscreen, then the model
871*4882a593Smuzhiyun * detection is a bit hairy. The different ft5x06
872*4882a593Smuzhiyun * firmares around don't reliably implement the
873*4882a593Smuzhiyun * identification registers. Well, we'll take a shot.
874*4882a593Smuzhiyun *
875*4882a593Smuzhiyun * The main difference between generic focaltec based
876*4882a593Smuzhiyun * touches and EDT M09 is that we know how to retrieve
877*4882a593Smuzhiyun * the max coordinates for the latter.
878*4882a593Smuzhiyun */
879*4882a593Smuzhiyun tsdata->version = GENERIC_FT;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
882*4882a593Smuzhiyun 2, rdbuf);
883*4882a593Smuzhiyun if (error)
884*4882a593Smuzhiyun return error;
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun strlcpy(fw_version, rdbuf, 2);
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(client, 1, "\xA8",
889*4882a593Smuzhiyun 1, rdbuf);
890*4882a593Smuzhiyun if (error)
891*4882a593Smuzhiyun return error;
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun /* This "model identification" is not exact. Unfortunately
894*4882a593Smuzhiyun * not all firmwares for the ft5x06 put useful values in
895*4882a593Smuzhiyun * the identification registers.
896*4882a593Smuzhiyun */
897*4882a593Smuzhiyun switch (rdbuf[0]) {
898*4882a593Smuzhiyun case 0x35: /* EDT EP0350M09 */
899*4882a593Smuzhiyun case 0x43: /* EDT EP0430M09 */
900*4882a593Smuzhiyun case 0x50: /* EDT EP0500M09 */
901*4882a593Smuzhiyun case 0x57: /* EDT EP0570M09 */
902*4882a593Smuzhiyun case 0x70: /* EDT EP0700M09 */
903*4882a593Smuzhiyun tsdata->version = EDT_M09;
904*4882a593Smuzhiyun snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
905*4882a593Smuzhiyun rdbuf[0] >> 4, rdbuf[0] & 0x0F);
906*4882a593Smuzhiyun break;
907*4882a593Smuzhiyun case 0xa1: /* EDT EP1010ML00 */
908*4882a593Smuzhiyun tsdata->version = EDT_M09;
909*4882a593Smuzhiyun snprintf(model_name, EDT_NAME_LEN, "EP%i%i0ML00",
910*4882a593Smuzhiyun rdbuf[0] >> 4, rdbuf[0] & 0x0F);
911*4882a593Smuzhiyun break;
912*4882a593Smuzhiyun case 0x5a: /* Solomon Goldentek Display */
913*4882a593Smuzhiyun snprintf(model_name, EDT_NAME_LEN, "GKTW50SCED1R0");
914*4882a593Smuzhiyun break;
915*4882a593Smuzhiyun case 0x59: /* Evervision Display with FT5xx6 TS */
916*4882a593Smuzhiyun tsdata->version = EV_FT;
917*4882a593Smuzhiyun error = edt_ft5x06_ts_readwrite(client, 1, "\x53",
918*4882a593Smuzhiyun 1, rdbuf);
919*4882a593Smuzhiyun if (error)
920*4882a593Smuzhiyun return error;
921*4882a593Smuzhiyun strlcpy(fw_version, rdbuf, 1);
922*4882a593Smuzhiyun snprintf(model_name, EDT_NAME_LEN,
923*4882a593Smuzhiyun "EVERVISION-FT5726NEi");
924*4882a593Smuzhiyun break;
925*4882a593Smuzhiyun default:
926*4882a593Smuzhiyun snprintf(model_name, EDT_NAME_LEN,
927*4882a593Smuzhiyun "generic ft5x06 (%02x)",
928*4882a593Smuzhiyun rdbuf[0]);
929*4882a593Smuzhiyun break;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun
933*4882a593Smuzhiyun return 0;
934*4882a593Smuzhiyun }
935*4882a593Smuzhiyun
edt_ft5x06_ts_get_defaults(struct device * dev,struct edt_ft5x06_ts_data * tsdata)936*4882a593Smuzhiyun static void edt_ft5x06_ts_get_defaults(struct device *dev,
937*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata)
938*4882a593Smuzhiyun {
939*4882a593Smuzhiyun struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
940*4882a593Smuzhiyun u32 val;
941*4882a593Smuzhiyun int error;
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun error = device_property_read_u32(dev, "threshold", &val);
944*4882a593Smuzhiyun if (!error) {
945*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold, val);
946*4882a593Smuzhiyun tsdata->threshold = val;
947*4882a593Smuzhiyun }
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun error = device_property_read_u32(dev, "gain", &val);
950*4882a593Smuzhiyun if (!error) {
951*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata, reg_addr->reg_gain, val);
952*4882a593Smuzhiyun tsdata->gain = val;
953*4882a593Smuzhiyun }
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun error = device_property_read_u32(dev, "offset", &val);
956*4882a593Smuzhiyun if (!error) {
957*4882a593Smuzhiyun if (reg_addr->reg_offset != NO_REGISTER)
958*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata,
959*4882a593Smuzhiyun reg_addr->reg_offset, val);
960*4882a593Smuzhiyun tsdata->offset = val;
961*4882a593Smuzhiyun }
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun error = device_property_read_u32(dev, "offset-x", &val);
964*4882a593Smuzhiyun if (!error) {
965*4882a593Smuzhiyun if (reg_addr->reg_offset_x != NO_REGISTER)
966*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata,
967*4882a593Smuzhiyun reg_addr->reg_offset_x, val);
968*4882a593Smuzhiyun tsdata->offset_x = val;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun error = device_property_read_u32(dev, "offset-y", &val);
972*4882a593Smuzhiyun if (!error) {
973*4882a593Smuzhiyun if (reg_addr->reg_offset_y != NO_REGISTER)
974*4882a593Smuzhiyun edt_ft5x06_register_write(tsdata,
975*4882a593Smuzhiyun reg_addr->reg_offset_y, val);
976*4882a593Smuzhiyun tsdata->offset_y = val;
977*4882a593Smuzhiyun }
978*4882a593Smuzhiyun }
979*4882a593Smuzhiyun
980*4882a593Smuzhiyun static void
edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data * tsdata)981*4882a593Smuzhiyun edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
982*4882a593Smuzhiyun {
983*4882a593Smuzhiyun struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun tsdata->threshold = edt_ft5x06_register_read(tsdata,
986*4882a593Smuzhiyun reg_addr->reg_threshold);
987*4882a593Smuzhiyun tsdata->gain = edt_ft5x06_register_read(tsdata, reg_addr->reg_gain);
988*4882a593Smuzhiyun if (reg_addr->reg_offset != NO_REGISTER)
989*4882a593Smuzhiyun tsdata->offset =
990*4882a593Smuzhiyun edt_ft5x06_register_read(tsdata, reg_addr->reg_offset);
991*4882a593Smuzhiyun if (reg_addr->reg_offset_x != NO_REGISTER)
992*4882a593Smuzhiyun tsdata->offset_x = edt_ft5x06_register_read(tsdata,
993*4882a593Smuzhiyun reg_addr->reg_offset_x);
994*4882a593Smuzhiyun if (reg_addr->reg_offset_y != NO_REGISTER)
995*4882a593Smuzhiyun tsdata->offset_y = edt_ft5x06_register_read(tsdata,
996*4882a593Smuzhiyun reg_addr->reg_offset_y);
997*4882a593Smuzhiyun if (reg_addr->reg_report_rate != NO_REGISTER)
998*4882a593Smuzhiyun tsdata->report_rate = edt_ft5x06_register_read(tsdata,
999*4882a593Smuzhiyun reg_addr->reg_report_rate);
1000*4882a593Smuzhiyun if (tsdata->version == EDT_M06 ||
1001*4882a593Smuzhiyun tsdata->version == EDT_M09 ||
1002*4882a593Smuzhiyun tsdata->version == EDT_M12) {
1003*4882a593Smuzhiyun tsdata->num_x = edt_ft5x06_register_read(tsdata,
1004*4882a593Smuzhiyun reg_addr->reg_num_x);
1005*4882a593Smuzhiyun tsdata->num_y = edt_ft5x06_register_read(tsdata,
1006*4882a593Smuzhiyun reg_addr->reg_num_y);
1007*4882a593Smuzhiyun } else {
1008*4882a593Smuzhiyun tsdata->num_x = -1;
1009*4882a593Smuzhiyun tsdata->num_y = -1;
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun }
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun static void
edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data * tsdata)1014*4882a593Smuzhiyun edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
1015*4882a593Smuzhiyun {
1016*4882a593Smuzhiyun struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun switch (tsdata->version) {
1019*4882a593Smuzhiyun case EDT_M06:
1020*4882a593Smuzhiyun reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD;
1021*4882a593Smuzhiyun reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE;
1022*4882a593Smuzhiyun reg_addr->reg_gain = WORK_REGISTER_GAIN;
1023*4882a593Smuzhiyun reg_addr->reg_offset = WORK_REGISTER_OFFSET;
1024*4882a593Smuzhiyun reg_addr->reg_offset_x = NO_REGISTER;
1025*4882a593Smuzhiyun reg_addr->reg_offset_y = NO_REGISTER;
1026*4882a593Smuzhiyun reg_addr->reg_num_x = WORK_REGISTER_NUM_X;
1027*4882a593Smuzhiyun reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
1028*4882a593Smuzhiyun break;
1029*4882a593Smuzhiyun
1030*4882a593Smuzhiyun case EDT_M09:
1031*4882a593Smuzhiyun case EDT_M12:
1032*4882a593Smuzhiyun reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
1033*4882a593Smuzhiyun reg_addr->reg_report_rate = NO_REGISTER;
1034*4882a593Smuzhiyun reg_addr->reg_gain = M09_REGISTER_GAIN;
1035*4882a593Smuzhiyun reg_addr->reg_offset = M09_REGISTER_OFFSET;
1036*4882a593Smuzhiyun reg_addr->reg_offset_x = NO_REGISTER;
1037*4882a593Smuzhiyun reg_addr->reg_offset_y = NO_REGISTER;
1038*4882a593Smuzhiyun reg_addr->reg_num_x = M09_REGISTER_NUM_X;
1039*4882a593Smuzhiyun reg_addr->reg_num_y = M09_REGISTER_NUM_Y;
1040*4882a593Smuzhiyun break;
1041*4882a593Smuzhiyun
1042*4882a593Smuzhiyun case EV_FT:
1043*4882a593Smuzhiyun reg_addr->reg_threshold = EV_REGISTER_THRESHOLD;
1044*4882a593Smuzhiyun reg_addr->reg_gain = EV_REGISTER_GAIN;
1045*4882a593Smuzhiyun reg_addr->reg_offset = NO_REGISTER;
1046*4882a593Smuzhiyun reg_addr->reg_offset_x = EV_REGISTER_OFFSET_X;
1047*4882a593Smuzhiyun reg_addr->reg_offset_y = EV_REGISTER_OFFSET_Y;
1048*4882a593Smuzhiyun reg_addr->reg_num_x = NO_REGISTER;
1049*4882a593Smuzhiyun reg_addr->reg_num_y = NO_REGISTER;
1050*4882a593Smuzhiyun reg_addr->reg_report_rate = NO_REGISTER;
1051*4882a593Smuzhiyun break;
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun case GENERIC_FT:
1054*4882a593Smuzhiyun /* this is a guesswork */
1055*4882a593Smuzhiyun reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
1056*4882a593Smuzhiyun reg_addr->reg_gain = M09_REGISTER_GAIN;
1057*4882a593Smuzhiyun reg_addr->reg_offset = M09_REGISTER_OFFSET;
1058*4882a593Smuzhiyun reg_addr->reg_offset_x = NO_REGISTER;
1059*4882a593Smuzhiyun reg_addr->reg_offset_y = NO_REGISTER;
1060*4882a593Smuzhiyun break;
1061*4882a593Smuzhiyun }
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun
edt_ft5x06_disable_regulator(void * arg)1064*4882a593Smuzhiyun static void edt_ft5x06_disable_regulator(void *arg)
1065*4882a593Smuzhiyun {
1066*4882a593Smuzhiyun struct edt_ft5x06_ts_data *data = arg;
1067*4882a593Smuzhiyun
1068*4882a593Smuzhiyun regulator_disable(data->vcc);
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun
edt_ft5x06_ts_probe(struct i2c_client * client,const struct i2c_device_id * id)1071*4882a593Smuzhiyun static int edt_ft5x06_ts_probe(struct i2c_client *client,
1072*4882a593Smuzhiyun const struct i2c_device_id *id)
1073*4882a593Smuzhiyun {
1074*4882a593Smuzhiyun const struct edt_i2c_chip_data *chip_data;
1075*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata;
1076*4882a593Smuzhiyun u8 buf[2] = { 0xfc, 0x00 };
1077*4882a593Smuzhiyun struct input_dev *input;
1078*4882a593Smuzhiyun unsigned long irq_flags;
1079*4882a593Smuzhiyun int error;
1080*4882a593Smuzhiyun char fw_version[EDT_NAME_LEN];
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
1085*4882a593Smuzhiyun if (!tsdata) {
1086*4882a593Smuzhiyun dev_err(&client->dev, "failed to allocate driver data.\n");
1087*4882a593Smuzhiyun return -ENOMEM;
1088*4882a593Smuzhiyun }
1089*4882a593Smuzhiyun
1090*4882a593Smuzhiyun chip_data = device_get_match_data(&client->dev);
1091*4882a593Smuzhiyun if (!chip_data)
1092*4882a593Smuzhiyun chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
1093*4882a593Smuzhiyun if (!chip_data || !chip_data->max_support_points) {
1094*4882a593Smuzhiyun dev_err(&client->dev, "invalid or missing chip data\n");
1095*4882a593Smuzhiyun return -EINVAL;
1096*4882a593Smuzhiyun }
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun tsdata->max_support_points = chip_data->max_support_points;
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
1101*4882a593Smuzhiyun if (IS_ERR(tsdata->vcc)) {
1102*4882a593Smuzhiyun error = PTR_ERR(tsdata->vcc);
1103*4882a593Smuzhiyun if (error != -EPROBE_DEFER)
1104*4882a593Smuzhiyun dev_err(&client->dev,
1105*4882a593Smuzhiyun "failed to request regulator: %d\n", error);
1106*4882a593Smuzhiyun return error;
1107*4882a593Smuzhiyun }
1108*4882a593Smuzhiyun
1109*4882a593Smuzhiyun error = regulator_enable(tsdata->vcc);
1110*4882a593Smuzhiyun if (error < 0) {
1111*4882a593Smuzhiyun dev_err(&client->dev, "failed to enable vcc: %d\n", error);
1112*4882a593Smuzhiyun return error;
1113*4882a593Smuzhiyun }
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun error = devm_add_action_or_reset(&client->dev,
1116*4882a593Smuzhiyun edt_ft5x06_disable_regulator,
1117*4882a593Smuzhiyun tsdata);
1118*4882a593Smuzhiyun if (error)
1119*4882a593Smuzhiyun return error;
1120*4882a593Smuzhiyun
1121*4882a593Smuzhiyun tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev,
1122*4882a593Smuzhiyun "reset", GPIOD_OUT_HIGH);
1123*4882a593Smuzhiyun if (IS_ERR(tsdata->reset_gpio)) {
1124*4882a593Smuzhiyun error = PTR_ERR(tsdata->reset_gpio);
1125*4882a593Smuzhiyun dev_err(&client->dev,
1126*4882a593Smuzhiyun "Failed to request GPIO reset pin, error %d\n", error);
1127*4882a593Smuzhiyun return error;
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun
1130*4882a593Smuzhiyun tsdata->wake_gpio = devm_gpiod_get_optional(&client->dev,
1131*4882a593Smuzhiyun "wake", GPIOD_OUT_LOW);
1132*4882a593Smuzhiyun if (IS_ERR(tsdata->wake_gpio)) {
1133*4882a593Smuzhiyun error = PTR_ERR(tsdata->wake_gpio);
1134*4882a593Smuzhiyun dev_err(&client->dev,
1135*4882a593Smuzhiyun "Failed to request GPIO wake pin, error %d\n", error);
1136*4882a593Smuzhiyun return error;
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun /*
1140*4882a593Smuzhiyun * Check which sleep modes we can support. Power-off requieres the
1141*4882a593Smuzhiyun * reset-pin to ensure correct power-down/power-up behaviour. Start with
1142*4882a593Smuzhiyun * the EDT_PMODE_POWEROFF test since this is the deepest possible sleep
1143*4882a593Smuzhiyun * mode.
1144*4882a593Smuzhiyun */
1145*4882a593Smuzhiyun if (tsdata->reset_gpio)
1146*4882a593Smuzhiyun tsdata->suspend_mode = EDT_PMODE_POWEROFF;
1147*4882a593Smuzhiyun else if (tsdata->wake_gpio)
1148*4882a593Smuzhiyun tsdata->suspend_mode = EDT_PMODE_HIBERNATE;
1149*4882a593Smuzhiyun else
1150*4882a593Smuzhiyun tsdata->suspend_mode = EDT_PMODE_NOT_SUPPORTED;
1151*4882a593Smuzhiyun
1152*4882a593Smuzhiyun if (tsdata->wake_gpio) {
1153*4882a593Smuzhiyun usleep_range(5000, 6000);
1154*4882a593Smuzhiyun gpiod_set_value_cansleep(tsdata->wake_gpio, 1);
1155*4882a593Smuzhiyun }
1156*4882a593Smuzhiyun
1157*4882a593Smuzhiyun if (tsdata->reset_gpio) {
1158*4882a593Smuzhiyun usleep_range(5000, 6000);
1159*4882a593Smuzhiyun gpiod_set_value_cansleep(tsdata->reset_gpio, 0);
1160*4882a593Smuzhiyun msleep(300);
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun input = devm_input_allocate_device(&client->dev);
1164*4882a593Smuzhiyun if (!input) {
1165*4882a593Smuzhiyun dev_err(&client->dev, "failed to allocate input device.\n");
1166*4882a593Smuzhiyun return -ENOMEM;
1167*4882a593Smuzhiyun }
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun mutex_init(&tsdata->mutex);
1170*4882a593Smuzhiyun tsdata->client = client;
1171*4882a593Smuzhiyun tsdata->input = input;
1172*4882a593Smuzhiyun tsdata->factory_mode = false;
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
1175*4882a593Smuzhiyun if (error) {
1176*4882a593Smuzhiyun dev_err(&client->dev, "touchscreen probe failed\n");
1177*4882a593Smuzhiyun return error;
1178*4882a593Smuzhiyun }
1179*4882a593Smuzhiyun
1180*4882a593Smuzhiyun /*
1181*4882a593Smuzhiyun * Dummy read access. EP0700MLP1 returns bogus data on the first
1182*4882a593Smuzhiyun * register read access and ignores writes.
1183*4882a593Smuzhiyun */
1184*4882a593Smuzhiyun edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
1185*4882a593Smuzhiyun
1186*4882a593Smuzhiyun edt_ft5x06_ts_set_regs(tsdata);
1187*4882a593Smuzhiyun edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
1188*4882a593Smuzhiyun edt_ft5x06_ts_get_parameters(tsdata);
1189*4882a593Smuzhiyun
1190*4882a593Smuzhiyun dev_dbg(&client->dev,
1191*4882a593Smuzhiyun "Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
1192*4882a593Smuzhiyun tsdata->name, fw_version, tsdata->num_x, tsdata->num_y);
1193*4882a593Smuzhiyun
1194*4882a593Smuzhiyun input->name = tsdata->name;
1195*4882a593Smuzhiyun input->id.bustype = BUS_I2C;
1196*4882a593Smuzhiyun input->dev.parent = &client->dev;
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun if (tsdata->version == EDT_M06 ||
1199*4882a593Smuzhiyun tsdata->version == EDT_M09 ||
1200*4882a593Smuzhiyun tsdata->version == EDT_M12) {
1201*4882a593Smuzhiyun input_set_abs_params(input, ABS_MT_POSITION_X,
1202*4882a593Smuzhiyun 0, tsdata->num_x * 64 - 1, 0, 0);
1203*4882a593Smuzhiyun input_set_abs_params(input, ABS_MT_POSITION_Y,
1204*4882a593Smuzhiyun 0, tsdata->num_y * 64 - 1, 0, 0);
1205*4882a593Smuzhiyun } else {
1206*4882a593Smuzhiyun /* Unknown maximum values. Specify via devicetree */
1207*4882a593Smuzhiyun input_set_abs_params(input, ABS_MT_POSITION_X,
1208*4882a593Smuzhiyun 0, 65535, 0, 0);
1209*4882a593Smuzhiyun input_set_abs_params(input, ABS_MT_POSITION_Y,
1210*4882a593Smuzhiyun 0, 65535, 0, 0);
1211*4882a593Smuzhiyun }
1212*4882a593Smuzhiyun
1213*4882a593Smuzhiyun touchscreen_parse_properties(input, true, &tsdata->prop);
1214*4882a593Smuzhiyun
1215*4882a593Smuzhiyun error = input_mt_init_slots(input, tsdata->max_support_points,
1216*4882a593Smuzhiyun INPUT_MT_DIRECT);
1217*4882a593Smuzhiyun if (error) {
1218*4882a593Smuzhiyun dev_err(&client->dev, "Unable to init MT slots.\n");
1219*4882a593Smuzhiyun return error;
1220*4882a593Smuzhiyun }
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun i2c_set_clientdata(client, tsdata);
1223*4882a593Smuzhiyun
1224*4882a593Smuzhiyun irq_flags = irq_get_trigger_type(client->irq);
1225*4882a593Smuzhiyun if (irq_flags == IRQF_TRIGGER_NONE)
1226*4882a593Smuzhiyun irq_flags = IRQF_TRIGGER_FALLING;
1227*4882a593Smuzhiyun irq_flags |= IRQF_ONESHOT;
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun error = devm_request_threaded_irq(&client->dev, client->irq,
1230*4882a593Smuzhiyun NULL, edt_ft5x06_ts_isr, irq_flags,
1231*4882a593Smuzhiyun client->name, tsdata);
1232*4882a593Smuzhiyun if (error) {
1233*4882a593Smuzhiyun dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
1234*4882a593Smuzhiyun return error;
1235*4882a593Smuzhiyun }
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group);
1238*4882a593Smuzhiyun if (error)
1239*4882a593Smuzhiyun return error;
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun error = input_register_device(input);
1242*4882a593Smuzhiyun if (error)
1243*4882a593Smuzhiyun return error;
1244*4882a593Smuzhiyun
1245*4882a593Smuzhiyun edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
1246*4882a593Smuzhiyun
1247*4882a593Smuzhiyun dev_dbg(&client->dev,
1248*4882a593Smuzhiyun "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
1249*4882a593Smuzhiyun client->irq,
1250*4882a593Smuzhiyun tsdata->wake_gpio ? desc_to_gpio(tsdata->wake_gpio) : -1,
1251*4882a593Smuzhiyun tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1);
1252*4882a593Smuzhiyun
1253*4882a593Smuzhiyun return 0;
1254*4882a593Smuzhiyun }
1255*4882a593Smuzhiyun
edt_ft5x06_ts_remove(struct i2c_client * client)1256*4882a593Smuzhiyun static int edt_ft5x06_ts_remove(struct i2c_client *client)
1257*4882a593Smuzhiyun {
1258*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun edt_ft5x06_ts_teardown_debugfs(tsdata);
1261*4882a593Smuzhiyun
1262*4882a593Smuzhiyun return 0;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun
edt_ft5x06_ts_suspend(struct device * dev)1265*4882a593Smuzhiyun static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
1266*4882a593Smuzhiyun {
1267*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
1268*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
1269*4882a593Smuzhiyun struct gpio_desc *reset_gpio = tsdata->reset_gpio;
1270*4882a593Smuzhiyun int ret;
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun if (device_may_wakeup(dev))
1273*4882a593Smuzhiyun return 0;
1274*4882a593Smuzhiyun
1275*4882a593Smuzhiyun if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
1276*4882a593Smuzhiyun return 0;
1277*4882a593Smuzhiyun
1278*4882a593Smuzhiyun /* Enter hibernate mode. */
1279*4882a593Smuzhiyun ret = edt_ft5x06_register_write(tsdata, PMOD_REGISTER_OPMODE,
1280*4882a593Smuzhiyun PMOD_REGISTER_HIBERNATE);
1281*4882a593Smuzhiyun if (ret)
1282*4882a593Smuzhiyun dev_warn(dev, "Failed to set hibernate mode\n");
1283*4882a593Smuzhiyun
1284*4882a593Smuzhiyun if (tsdata->suspend_mode == EDT_PMODE_HIBERNATE)
1285*4882a593Smuzhiyun return 0;
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun /*
1288*4882a593Smuzhiyun * Power-off according the datasheet. Cut the power may leaf the irq
1289*4882a593Smuzhiyun * line in an undefined state depending on the host pull resistor
1290*4882a593Smuzhiyun * settings. Disable the irq to avoid adjusting each host till the
1291*4882a593Smuzhiyun * device is back in a full functional state.
1292*4882a593Smuzhiyun */
1293*4882a593Smuzhiyun disable_irq(tsdata->client->irq);
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun gpiod_set_value_cansleep(reset_gpio, 1);
1296*4882a593Smuzhiyun usleep_range(1000, 2000);
1297*4882a593Smuzhiyun
1298*4882a593Smuzhiyun ret = regulator_disable(tsdata->vcc);
1299*4882a593Smuzhiyun if (ret)
1300*4882a593Smuzhiyun dev_warn(dev, "Failed to disable vcc\n");
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun return 0;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun
edt_ft5x06_ts_resume(struct device * dev)1305*4882a593Smuzhiyun static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
1306*4882a593Smuzhiyun {
1307*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
1308*4882a593Smuzhiyun struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
1309*4882a593Smuzhiyun int ret = 0;
1310*4882a593Smuzhiyun
1311*4882a593Smuzhiyun if (device_may_wakeup(dev))
1312*4882a593Smuzhiyun return 0;
1313*4882a593Smuzhiyun
1314*4882a593Smuzhiyun if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
1315*4882a593Smuzhiyun return 0;
1316*4882a593Smuzhiyun
1317*4882a593Smuzhiyun if (tsdata->suspend_mode == EDT_PMODE_POWEROFF) {
1318*4882a593Smuzhiyun struct gpio_desc *reset_gpio = tsdata->reset_gpio;
1319*4882a593Smuzhiyun
1320*4882a593Smuzhiyun /*
1321*4882a593Smuzhiyun * We can't check if the regulator is a dummy or a real
1322*4882a593Smuzhiyun * regulator. So we need to specify the 5ms reset time (T_rst)
1323*4882a593Smuzhiyun * here instead of the 100us T_rtp time. We also need to wait
1324*4882a593Smuzhiyun * 300ms in case it was a real supply and the power was cutted
1325*4882a593Smuzhiyun * of. Toggle the reset pin is also a way to exit the hibernate
1326*4882a593Smuzhiyun * mode.
1327*4882a593Smuzhiyun */
1328*4882a593Smuzhiyun gpiod_set_value_cansleep(reset_gpio, 1);
1329*4882a593Smuzhiyun usleep_range(5000, 6000);
1330*4882a593Smuzhiyun
1331*4882a593Smuzhiyun ret = regulator_enable(tsdata->vcc);
1332*4882a593Smuzhiyun if (ret) {
1333*4882a593Smuzhiyun dev_err(dev, "Failed to enable vcc\n");
1334*4882a593Smuzhiyun return ret;
1335*4882a593Smuzhiyun }
1336*4882a593Smuzhiyun
1337*4882a593Smuzhiyun usleep_range(1000, 2000);
1338*4882a593Smuzhiyun gpiod_set_value_cansleep(reset_gpio, 0);
1339*4882a593Smuzhiyun msleep(300);
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun edt_ft5x06_restore_reg_parameters(tsdata);
1342*4882a593Smuzhiyun enable_irq(tsdata->client->irq);
1343*4882a593Smuzhiyun
1344*4882a593Smuzhiyun if (tsdata->factory_mode)
1345*4882a593Smuzhiyun ret = edt_ft5x06_factory_mode(tsdata);
1346*4882a593Smuzhiyun } else {
1347*4882a593Smuzhiyun struct gpio_desc *wake_gpio = tsdata->wake_gpio;
1348*4882a593Smuzhiyun
1349*4882a593Smuzhiyun gpiod_set_value_cansleep(wake_gpio, 0);
1350*4882a593Smuzhiyun usleep_range(5000, 6000);
1351*4882a593Smuzhiyun gpiod_set_value_cansleep(wake_gpio, 1);
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun return ret;
1356*4882a593Smuzhiyun }
1357*4882a593Smuzhiyun
1358*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
1359*4882a593Smuzhiyun edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
1360*4882a593Smuzhiyun
1361*4882a593Smuzhiyun static const struct edt_i2c_chip_data edt_ft5x06_data = {
1362*4882a593Smuzhiyun .max_support_points = 5,
1363*4882a593Smuzhiyun };
1364*4882a593Smuzhiyun
1365*4882a593Smuzhiyun static const struct edt_i2c_chip_data edt_ft5506_data = {
1366*4882a593Smuzhiyun .max_support_points = 10,
1367*4882a593Smuzhiyun };
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun static const struct edt_i2c_chip_data edt_ft6236_data = {
1370*4882a593Smuzhiyun .max_support_points = 2,
1371*4882a593Smuzhiyun };
1372*4882a593Smuzhiyun
1373*4882a593Smuzhiyun static const struct i2c_device_id edt_ft5x06_ts_id[] = {
1374*4882a593Smuzhiyun { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
1375*4882a593Smuzhiyun { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
1376*4882a593Smuzhiyun { .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
1377*4882a593Smuzhiyun /* Note no edt- prefix for compatibility with the ft6236.c driver */
1378*4882a593Smuzhiyun { .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
1379*4882a593Smuzhiyun { /* sentinel */ }
1380*4882a593Smuzhiyun };
1381*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
1382*4882a593Smuzhiyun
1383*4882a593Smuzhiyun static const struct of_device_id edt_ft5x06_of_match[] = {
1384*4882a593Smuzhiyun { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data },
1385*4882a593Smuzhiyun { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data },
1386*4882a593Smuzhiyun { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
1387*4882a593Smuzhiyun { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
1388*4882a593Smuzhiyun { .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
1389*4882a593Smuzhiyun /* Note focaltech vendor prefix for compatibility with ft6236.c */
1390*4882a593Smuzhiyun { .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
1391*4882a593Smuzhiyun { /* sentinel */ }
1392*4882a593Smuzhiyun };
1393*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
1394*4882a593Smuzhiyun
1395*4882a593Smuzhiyun static struct i2c_driver edt_ft5x06_ts_driver = {
1396*4882a593Smuzhiyun .driver = {
1397*4882a593Smuzhiyun .name = "edt_ft5x06",
1398*4882a593Smuzhiyun .of_match_table = edt_ft5x06_of_match,
1399*4882a593Smuzhiyun .pm = &edt_ft5x06_ts_pm_ops,
1400*4882a593Smuzhiyun .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1401*4882a593Smuzhiyun },
1402*4882a593Smuzhiyun .id_table = edt_ft5x06_ts_id,
1403*4882a593Smuzhiyun .probe = edt_ft5x06_ts_probe,
1404*4882a593Smuzhiyun .remove = edt_ft5x06_ts_remove,
1405*4882a593Smuzhiyun };
1406*4882a593Smuzhiyun
1407*4882a593Smuzhiyun module_i2c_driver(edt_ft5x06_ts_driver);
1408*4882a593Smuzhiyun
1409*4882a593Smuzhiyun MODULE_AUTHOR("Simon Budig <simon.budig@kernelconcepts.de>");
1410*4882a593Smuzhiyun MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver");
1411*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1412