xref: /openbmc/linux/drivers/input/touchscreen/elo.c (revision 4f3db074)
1 /*
2  * Elo serial touchscreen driver
3  *
4  * Copyright (c) 2004 Vojtech Pavlik
5  */
6 
7 /*
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License version 2 as published by
10  * the Free Software Foundation.
11  */
12 
13 /*
14  * This driver can handle serial Elo touchscreens using either the Elo standard
15  * 'E271-2210' 10-byte protocol, Elo legacy 'E281A-4002' 6-byte protocol, Elo
16  * legacy 'E271-140' 4-byte protocol and Elo legacy 'E261-280' 3-byte protocol.
17  */
18 
19 #include <linux/errno.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/input.h>
24 #include <linux/serio.h>
25 #include <linux/ctype.h>
26 
27 #define DRIVER_DESC	"Elo serial touchscreen driver"
28 
29 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
30 MODULE_DESCRIPTION(DRIVER_DESC);
31 MODULE_LICENSE("GPL");
32 
33 /*
34  * Definitions & global arrays.
35  */
36 
37 #define ELO_MAX_LENGTH		10
38 
39 #define ELO10_PACKET_LEN	8
40 #define ELO10_TOUCH		0x03
41 #define ELO10_PRESSURE		0x80
42 
43 #define ELO10_LEAD_BYTE		'U'
44 
45 #define ELO10_ID_CMD		'i'
46 
47 #define ELO10_TOUCH_PACKET	'T'
48 #define ELO10_ACK_PACKET	'A'
49 #define ELI10_ID_PACKET		'I'
50 
51 /*
52  * Per-touchscreen data.
53  */
54 
55 struct elo {
56 	struct input_dev *dev;
57 	struct serio *serio;
58 	struct mutex cmd_mutex;
59 	struct completion cmd_done;
60 	int id;
61 	int idx;
62 	unsigned char expected_packet;
63 	unsigned char csum;
64 	unsigned char data[ELO_MAX_LENGTH];
65 	unsigned char response[ELO10_PACKET_LEN];
66 	char phys[32];
67 };
68 
69 static void elo_process_data_10(struct elo *elo, unsigned char data)
70 {
71 	struct input_dev *dev = elo->dev;
72 
73 	elo->data[elo->idx] = data;
74 
75 	switch (elo->idx++) {
76 	case 0:
77 		elo->csum = 0xaa;
78 		if (data != ELO10_LEAD_BYTE) {
79 			dev_dbg(&elo->serio->dev,
80 				"unsynchronized data: 0x%02x\n", data);
81 			elo->idx = 0;
82 		}
83 		break;
84 
85 	case 9:
86 		elo->idx = 0;
87 		if (data != elo->csum) {
88 			dev_dbg(&elo->serio->dev,
89 				"bad checksum: 0x%02x, expected 0x%02x\n",
90 				 data, elo->csum);
91 			break;
92 		}
93 		if (elo->data[1] != elo->expected_packet) {
94 			if (elo->data[1] != ELO10_TOUCH_PACKET)
95 				dev_dbg(&elo->serio->dev,
96 					"unexpected packet: 0x%02x\n",
97 					 elo->data[1]);
98 			break;
99 		}
100 		if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
101 			input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
102 			input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
103 			if (elo->data[2] & ELO10_PRESSURE)
104 				input_report_abs(dev, ABS_PRESSURE,
105 						(elo->data[8] << 8) | elo->data[7]);
106 			input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
107 			input_sync(dev);
108 		} else if (elo->data[1] == ELO10_ACK_PACKET) {
109 			if (elo->data[2] == '0')
110 				elo->expected_packet = ELO10_TOUCH_PACKET;
111 			complete(&elo->cmd_done);
112 		} else {
113 			memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
114 			elo->expected_packet = ELO10_ACK_PACKET;
115 		}
116 		break;
117 	}
118 	elo->csum += data;
119 }
120 
121 static void elo_process_data_6(struct elo *elo, unsigned char data)
122 {
123 	struct input_dev *dev = elo->dev;
124 
125 	elo->data[elo->idx] = data;
126 
127 	switch (elo->idx++) {
128 
129 	case 0:
130 		if ((data & 0xc0) != 0xc0)
131 			elo->idx = 0;
132 		break;
133 
134 	case 1:
135 		if ((data & 0xc0) != 0x80)
136 			elo->idx = 0;
137 		break;
138 
139 	case 2:
140 		if ((data & 0xc0) != 0x40)
141 			elo->idx = 0;
142 		break;
143 
144 	case 3:
145 		if (data & 0xc0) {
146 			elo->idx = 0;
147 			break;
148 		}
149 
150 		input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
151 		input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
152 
153 		if (elo->id == 2) {
154 			input_report_key(dev, BTN_TOUCH, 1);
155 			input_sync(dev);
156 			elo->idx = 0;
157 		}
158 
159 		break;
160 
161 	case 4:
162 		if (data) {
163 			input_sync(dev);
164 			elo->idx = 0;
165 		}
166 		break;
167 
168 	case 5:
169 		if ((data & 0xf0) == 0) {
170 			input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
171 			input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
172 		}
173 		input_sync(dev);
174 		elo->idx = 0;
175 		break;
176 	}
177 }
178 
179 static void elo_process_data_3(struct elo *elo, unsigned char data)
180 {
181 	struct input_dev *dev = elo->dev;
182 
183 	elo->data[elo->idx] = data;
184 
185 	switch (elo->idx++) {
186 
187 	case 0:
188 		if ((data & 0x7f) != 0x01)
189 			elo->idx = 0;
190 		break;
191 	case 2:
192 		input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
193 		input_report_abs(dev, ABS_X, elo->data[1]);
194 		input_report_abs(dev, ABS_Y, elo->data[2]);
195 		input_sync(dev);
196 		elo->idx = 0;
197 		break;
198 	}
199 }
200 
201 static irqreturn_t elo_interrupt(struct serio *serio,
202 		unsigned char data, unsigned int flags)
203 {
204 	struct elo *elo = serio_get_drvdata(serio);
205 
206 	switch (elo->id) {
207 	case 0:
208 		elo_process_data_10(elo, data);
209 		break;
210 
211 	case 1:
212 	case 2:
213 		elo_process_data_6(elo, data);
214 		break;
215 
216 	case 3:
217 		elo_process_data_3(elo, data);
218 		break;
219 	}
220 
221 	return IRQ_HANDLED;
222 }
223 
224 static int elo_command_10(struct elo *elo, unsigned char *packet)
225 {
226 	int rc = -1;
227 	int i;
228 	unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
229 
230 	mutex_lock(&elo->cmd_mutex);
231 
232 	serio_pause_rx(elo->serio);
233 	elo->expected_packet = toupper(packet[0]);
234 	init_completion(&elo->cmd_done);
235 	serio_continue_rx(elo->serio);
236 
237 	if (serio_write(elo->serio, ELO10_LEAD_BYTE))
238 		goto out;
239 
240 	for (i = 0; i < ELO10_PACKET_LEN; i++) {
241 		csum += packet[i];
242 		if (serio_write(elo->serio, packet[i]))
243 			goto out;
244 	}
245 
246 	if (serio_write(elo->serio, csum))
247 		goto out;
248 
249 	wait_for_completion_timeout(&elo->cmd_done, HZ);
250 
251 	if (elo->expected_packet == ELO10_TOUCH_PACKET) {
252 		/* We are back in reporting mode, the command was ACKed */
253 		memcpy(packet, elo->response, ELO10_PACKET_LEN);
254 		rc = 0;
255 	}
256 
257  out:
258 	mutex_unlock(&elo->cmd_mutex);
259 	return rc;
260 }
261 
262 static int elo_setup_10(struct elo *elo)
263 {
264 	static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
265 	struct input_dev *dev = elo->dev;
266 	unsigned char packet[ELO10_PACKET_LEN] = { ELO10_ID_CMD };
267 
268 	if (elo_command_10(elo, packet))
269 		return -1;
270 
271 	dev->id.version = (packet[5] << 8) | packet[4];
272 
273 	input_set_abs_params(dev, ABS_X, 96, 4000, 0, 0);
274 	input_set_abs_params(dev, ABS_Y, 96, 4000, 0, 0);
275 	if (packet[3] & ELO10_PRESSURE)
276 		input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
277 
278 	dev_info(&elo->serio->dev,
279 		 "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n",
280 		 elo_types[(packet[1] -'0') & 0x03],
281 		 packet[5], packet[4], packet[3], packet[7]);
282 
283 	return 0;
284 }
285 
286 /*
287  * elo_disconnect() is the opposite of elo_connect()
288  */
289 
290 static void elo_disconnect(struct serio *serio)
291 {
292 	struct elo *elo = serio_get_drvdata(serio);
293 
294 	input_get_device(elo->dev);
295 	input_unregister_device(elo->dev);
296 	serio_close(serio);
297 	serio_set_drvdata(serio, NULL);
298 	input_put_device(elo->dev);
299 	kfree(elo);
300 }
301 
302 /*
303  * elo_connect() is the routine that is called when someone adds a
304  * new serio device that supports Gunze protocol and registers it as
305  * an input device.
306  */
307 
308 static int elo_connect(struct serio *serio, struct serio_driver *drv)
309 {
310 	struct elo *elo;
311 	struct input_dev *input_dev;
312 	int err;
313 
314 	elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
315 	input_dev = input_allocate_device();
316 	if (!elo || !input_dev) {
317 		err = -ENOMEM;
318 		goto fail1;
319 	}
320 
321 	elo->serio = serio;
322 	elo->id = serio->id.id;
323 	elo->dev = input_dev;
324 	elo->expected_packet = ELO10_TOUCH_PACKET;
325 	mutex_init(&elo->cmd_mutex);
326 	init_completion(&elo->cmd_done);
327 	snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
328 
329 	input_dev->name = "Elo Serial TouchScreen";
330 	input_dev->phys = elo->phys;
331 	input_dev->id.bustype = BUS_RS232;
332 	input_dev->id.vendor = SERIO_ELO;
333 	input_dev->id.product = elo->id;
334 	input_dev->id.version = 0x0100;
335 	input_dev->dev.parent = &serio->dev;
336 
337 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
338 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
339 
340 	serio_set_drvdata(serio, elo);
341 	err = serio_open(serio, drv);
342 	if (err)
343 		goto fail2;
344 
345 	switch (elo->id) {
346 
347 	case 0: /* 10-byte protocol */
348 		if (elo_setup_10(elo))
349 			goto fail3;
350 
351 		break;
352 
353 	case 1: /* 6-byte protocol */
354 		input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
355 
356 	case 2: /* 4-byte protocol */
357 		input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
358 		input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
359 		break;
360 
361 	case 3: /* 3-byte protocol */
362 		input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
363 		input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
364 		break;
365 	}
366 
367 	err = input_register_device(elo->dev);
368 	if (err)
369 		goto fail3;
370 
371 	return 0;
372 
373  fail3: serio_close(serio);
374  fail2:	serio_set_drvdata(serio, NULL);
375  fail1:	input_free_device(input_dev);
376 	kfree(elo);
377 	return err;
378 }
379 
380 /*
381  * The serio driver structure.
382  */
383 
384 static struct serio_device_id elo_serio_ids[] = {
385 	{
386 		.type	= SERIO_RS232,
387 		.proto	= SERIO_ELO,
388 		.id	= SERIO_ANY,
389 		.extra	= SERIO_ANY,
390 	},
391 	{ 0 }
392 };
393 
394 MODULE_DEVICE_TABLE(serio, elo_serio_ids);
395 
396 static struct serio_driver elo_drv = {
397 	.driver		= {
398 		.name	= "elo",
399 	},
400 	.description	= DRIVER_DESC,
401 	.id_table	= elo_serio_ids,
402 	.interrupt	= elo_interrupt,
403 	.connect	= elo_connect,
404 	.disconnect	= elo_disconnect,
405 };
406 
407 module_serio_driver(elo_drv);
408