2 * Copyright (C) 2016, Jelle van der Waa <jelle@vdwaa.nl>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include <linux/delay.h>
16 #include <linux/i2c.h>
17 #include <linux/input.h>
18 #include <linux/input/mt.h>
19 #include <linux/input/touchscreen.h>
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
22 #include <linux/regulator/consumer.h>
23 #include <asm/unaligned.h>
25 #define ZET6223_MAX_FINGERS 16
26 #define ZET6223_MAX_PKT_SIZE (3 + 4 * ZET6223_MAX_FINGERS)
28 #define ZET6223_CMD_INFO 0xB2
29 #define ZET6223_CMD_INFO_LENGTH 17
30 #define ZET6223_VALID_PACKET 0x3c
32 #define ZET6223_POWER_ON_DELAY_MSEC 30
35 struct i2c_client
*client
;
36 struct input_dev
*input
;
37 struct regulator
*vcc
;
38 struct regulator
*vio
;
39 struct touchscreen_properties prop
;
40 struct regulator_bulk_data supplies
[2];
46 static int zet6223_start(struct input_dev
*dev
)
48 struct zet6223_ts
*ts
= input_get_drvdata(dev
);
50 enable_irq(ts
->client
->irq
);
55 static void zet6223_stop(struct input_dev
*dev
)
57 struct zet6223_ts
*ts
= input_get_drvdata(dev
);
59 disable_irq(ts
->client
->irq
);
62 static irqreturn_t
zet6223_irq(int irq
, void *dev_id
)
64 struct zet6223_ts
*ts
= dev_id
;
68 * First 3 bytes are an identifier, two bytes of finger data.
69 * X, Y data per finger is 4 bytes.
71 u8 bufsize
= 3 + 4 * ts
->fingernum
;
72 u8 buf
[ZET6223_MAX_PKT_SIZE
];
77 ret
= i2c_master_recv(ts
->client
, buf
, bufsize
);
79 error
= ret
< 0 ? ret
: -EIO
;
80 dev_err_ratelimited(&ts
->client
->dev
,
81 "Error reading input data: %d\n", error
);
85 if (buf
[0] != ZET6223_VALID_PACKET
)
88 finger_bits
= get_unaligned_be16(buf
+ 1);
89 for (i
= 0; i
< ts
->fingernum
; i
++) {
90 if (!(finger_bits
& BIT(15 - i
)))
93 input_mt_slot(ts
->input
, i
);
94 input_mt_report_slot_state(ts
->input
, MT_TOOL_FINGER
, true);
95 input_event(ts
->input
, EV_ABS
, ABS_MT_POSITION_X
,
96 ((buf
[i
+ 3] >> 4) << 8) + buf
[i
+ 4]);
97 input_event(ts
->input
, EV_ABS
, ABS_MT_POSITION_Y
,
98 ((buf
[i
+ 3] & 0xF) << 8) + buf
[i
+ 5]);
101 input_mt_sync_frame(ts
->input
);
102 input_sync(ts
->input
);
107 static void zet6223_power_off(void *_ts
)
109 struct zet6223_ts
*ts
= _ts
;
111 regulator_bulk_disable(ARRAY_SIZE(ts
->supplies
), ts
->supplies
);
114 static int zet6223_power_on(struct zet6223_ts
*ts
)
116 struct device
*dev
= &ts
->client
->dev
;
119 ts
->supplies
[0].supply
= "vio";
120 ts
->supplies
[1].supply
= "vcc";
122 error
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(ts
->supplies
),
127 error
= regulator_bulk_enable(ARRAY_SIZE(ts
->supplies
), ts
->supplies
);
131 msleep(ZET6223_POWER_ON_DELAY_MSEC
);
133 error
= devm_add_action_or_reset(dev
, zet6223_power_off
, ts
);
135 dev_err(dev
, "failed to install poweroff action: %d\n", error
);
142 static int zet6223_query_device(struct zet6223_ts
*ts
)
144 u8 buf
[ZET6223_CMD_INFO_LENGTH
];
145 u8 cmd
= ZET6223_CMD_INFO
;
149 ret
= i2c_master_send(ts
->client
, &cmd
, sizeof(cmd
));
150 if (ret
!= sizeof(cmd
)) {
151 error
= ret
< 0 ? ret
: -EIO
;
152 dev_err(&ts
->client
->dev
,
153 "touchpanel info cmd failed: %d\n", error
);
157 ret
= i2c_master_recv(ts
->client
, buf
, sizeof(buf
));
158 if (ret
!= sizeof(buf
)) {
159 error
= ret
< 0 ? ret
: -EIO
;
160 dev_err(&ts
->client
->dev
,
161 "failed to retrieve touchpanel info: %d\n", error
);
165 ts
->fingernum
= buf
[15] & 0x7F;
166 if (ts
->fingernum
> ZET6223_MAX_FINGERS
) {
167 dev_warn(&ts
->client
->dev
,
168 "touchpanel reports %d fingers, limiting to %d\n",
169 ts
->fingernum
, ZET6223_MAX_FINGERS
);
170 ts
->fingernum
= ZET6223_MAX_FINGERS
;
173 ts
->max_x
= get_unaligned_le16(&buf
[8]);
174 ts
->max_y
= get_unaligned_le16(&buf
[10]);
179 static int zet6223_probe(struct i2c_client
*client
,
180 const struct i2c_device_id
*id
)
182 struct device
*dev
= &client
->dev
;
183 struct zet6223_ts
*ts
;
184 struct input_dev
*input
;
188 dev_err(dev
, "no irq specified\n");
192 ts
= devm_kzalloc(dev
, sizeof(*ts
), GFP_KERNEL
);
198 error
= zet6223_power_on(ts
);
202 error
= zet6223_query_device(ts
);
206 ts
->input
= input
= devm_input_allocate_device(dev
);
210 input_set_drvdata(input
, ts
);
212 input
->name
= client
->name
;
213 input
->id
.bustype
= BUS_I2C
;
214 input
->open
= zet6223_start
;
215 input
->close
= zet6223_stop
;
217 input_set_abs_params(input
, ABS_MT_POSITION_X
, 0, ts
->max_x
, 0, 0);
218 input_set_abs_params(input
, ABS_MT_POSITION_Y
, 0, ts
->max_y
, 0, 0);
220 touchscreen_parse_properties(input
, true, &ts
->prop
);
222 error
= input_mt_init_slots(input
, ts
->fingernum
,
223 INPUT_MT_DIRECT
| INPUT_MT_DROP_UNUSED
);
227 error
= devm_request_threaded_irq(dev
, client
->irq
, NULL
, zet6223_irq
,
228 IRQF_ONESHOT
, client
->name
, ts
);
230 dev_err(dev
, "failed to request irq %d: %d\n",
237 error
= input_register_device(input
);
244 static const struct of_device_id zet6223_of_match
[] = {
245 { .compatible
= "zeitec,zet6223" },
248 MODULE_DEVICE_TABLE(of
, zet6223_of_match
);
250 static const struct i2c_device_id zet6223_id
[] = {
254 MODULE_DEVICE_TABLE(i2c
, zet6223_id
);
256 static struct i2c_driver zet6223_driver
= {
259 .of_match_table
= zet6223_of_match
,
261 .probe
= zet6223_probe
,
262 .id_table
= zet6223_id
264 module_i2c_driver(zet6223_driver
);
266 MODULE_AUTHOR("Jelle van der Waa <jelle@vdwaa.nl>");
267 MODULE_DESCRIPTION("ZEITEC zet622x I2C touchscreen driver");
268 MODULE_LICENSE("GPL");