xref: /openbmc/linux/drivers/input/mouse/vsxxxaa.c (revision 96de0e252cedffad61b3cb5e05662c591898e69a)
1 /*
2  * Driver for	DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers)
3  *		DEC VSXXX-GA mouse (rectangular mouse, with ball)
4  *		DEC VSXXX-AB tablet (digitizer with hair cross or stylus)
5  *
6  * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
7  *
8  * The packet format was initially taken from a patch to GPM which is (C) 2001
9  * by	Karsten Merker <merker@linuxtag.org>
10  * and	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
11  * Later on, I had access to the device's documentation (referenced below).
12  */
13 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  */
29 
30 /*
31  * Building an adaptor to DE9 / DB25 RS232
32  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33  *
34  * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for
35  * anything if you break your mouse, your computer or whatever!
36  *
37  * In theory, this mouse is a simple RS232 device. In practice, it has got
38  * a quite uncommon plug and the requirement to additionally get a power
39  * supply at +5V and -12V.
40  *
41  * If you look at the socket/jack (_not_ at the plug), we use this pin
42  * numbering:
43  *    _______
44  *   / 7 6 5 \
45  *  | 4 --- 3 |
46  *   \  2 1  /
47  *    -------
48  *
49  *	DEC socket	DE9	DB25	Note
50  *	1 (GND)		5	7	-
51  *	2 (RxD)		2	3	-
52  *	3 (TxD)		3	2	-
53  *	4 (-12V)	-	-	Somewhere from the PSU. At ATX, it's
54  *					the thin blue wire at pin 12 of the
55  *					ATX power connector. Only required for
56  *					VSXXX-AA/-GA mice.
57  *	5 (+5V)		-	-	PSU (red wires of ATX power connector
58  *					on pin 4, 6, 19 or 20) or HDD power
59  *					connector (also red wire).
60  *	6 (+12V)	-	-	HDD power connector, yellow wire. Only
61  *					required for VSXXX-AB digitizer.
62  *	7 (dev. avail.)	-	-	The mouse shorts this one to pin 1.
63  *					This way, the host computer can detect
64  *					the mouse. To use it with the adaptor,
65  *					simply don't connect this pin.
66  *
67  * So to get a working adaptor, you need to connect the mouse with three
68  * wires to a RS232 port and two or three additional wires for +5V, +12V and
69  * -12V to the PSU.
70  *
71  * Flow specification for the link is 4800, 8o1.
72  *
73  * The mice and tablet are described in "VCB02 Video Subsystem - Technical
74  * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
75  * specific for DEC documentation. Try
76  * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
77  */
78 
79 #include <linux/delay.h>
80 #include <linux/module.h>
81 #include <linux/slab.h>
82 #include <linux/interrupt.h>
83 #include <linux/input.h>
84 #include <linux/serio.h>
85 #include <linux/init.h>
86 
87 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
88 
89 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
90 MODULE_DESCRIPTION (DRIVER_DESC);
91 MODULE_LICENSE ("GPL");
92 
93 #undef VSXXXAA_DEBUG
94 #ifdef VSXXXAA_DEBUG
95 #define DBG(x...) printk (x)
96 #else
97 #define DBG(x...) do {} while (0)
98 #endif
99 
100 #define VSXXXAA_INTRO_MASK	0x80
101 #define VSXXXAA_INTRO_HEAD	0x80
102 #define IS_HDR_BYTE(x)		(((x) & VSXXXAA_INTRO_MASK)	\
103 					== VSXXXAA_INTRO_HEAD)
104 
105 #define VSXXXAA_PACKET_MASK	0xe0
106 #define VSXXXAA_PACKET_REL	0x80
107 #define VSXXXAA_PACKET_ABS	0xc0
108 #define VSXXXAA_PACKET_POR	0xa0
109 #define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == (type))
110 
111 
112 
113 struct vsxxxaa {
114 	struct input_dev *dev;
115 	struct serio *serio;
116 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
117 	unsigned char buf[BUFLEN];
118 	unsigned char count;
119 	unsigned char version;
120 	unsigned char country;
121 	unsigned char type;
122 	char name[64];
123 	char phys[32];
124 };
125 
126 static void
127 vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num)
128 {
129 	if (num >= mouse->count)
130 		mouse->count = 0;
131 	else {
132 		memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num);
133 		mouse->count -= num;
134 	}
135 }
136 
137 static void
138 vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
139 {
140 	if (mouse->count == BUFLEN) {
141 		printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
142 				mouse->name, mouse->phys);
143 		vsxxxaa_drop_bytes (mouse, 1);
144 	}
145 	DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
146 
147 	mouse->buf[mouse->count++] = byte;
148 }
149 
150 static void
151 vsxxxaa_detection_done (struct vsxxxaa *mouse)
152 {
153 	switch (mouse->type) {
154 		case 0x02:
155 			strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse",
156 				 sizeof (mouse->name));
157 			break;
158 
159 		case 0x04:
160 			strlcpy (mouse->name, "DEC VSXXX-AB digitizer",
161 				 sizeof (mouse->name));
162 			break;
163 
164 		default:
165 			snprintf (mouse->name, sizeof (mouse->name),
166 				  "unknown DEC pointer device (type = 0x%02x)",
167 				  mouse->type);
168 			break;
169 	}
170 
171 	printk (KERN_INFO
172 		"Found %s version 0x%02x from country 0x%02x on port %s\n",
173 		mouse->name, mouse->version, mouse->country, mouse->phys);
174 }
175 
176 /*
177  * Returns number of bytes to be dropped, 0 if packet is okay.
178  */
179 static int
180 vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
181 {
182 	int i;
183 
184 	/* First byte must be a header byte */
185 	if (!IS_HDR_BYTE (mouse->buf[0])) {
186 		DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
187 		return 1;
188 	}
189 
190 	/* Check all following bytes */
191 	if (packet_len > 1) {
192 		for (i = 1; i < packet_len; i++) {
193 			if (IS_HDR_BYTE (mouse->buf[i])) {
194 				printk (KERN_ERR "Need to drop %d bytes "
195 						"of a broken packet.\n",
196 						i - 1);
197 				DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
198 						packet_len, i, mouse->buf[i]);
199 				return i - 1;
200 			}
201 		}
202 	}
203 
204 	return 0;
205 }
206 
207 static __inline__ int
208 vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
209 {
210 	return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
211 }
212 
213 static void
214 vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse)
215 {
216 	struct input_dev *dev = mouse->dev;
217 	unsigned char *buf = mouse->buf;
218 	int left, middle, right;
219 	int dx, dy;
220 
221 	/*
222 	 * Check for normal stream packets. This is three bytes,
223 	 * with the first byte's 3 MSB set to 100.
224 	 *
225 	 * [0]:	1	0	0	SignX	SignY	Left	Middle	Right
226 	 * [1]: 0	dx	dx	dx	dx	dx	dx	dx
227 	 * [2]:	0	dy	dy	dy	dy	dy	dy	dy
228 	 */
229 
230 	/*
231 	 * Low 7 bit of byte 1 are abs(dx), bit 7 is
232 	 * 0, bit 4 of byte 0 is direction.
233 	 */
234 	dx = buf[1] & 0x7f;
235 	dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
236 
237 	/*
238 	 * Low 7 bit of byte 2 are abs(dy), bit 7 is
239 	 * 0, bit 3 of byte 0 is direction.
240 	 */
241 	dy = buf[2] & 0x7f;
242 	dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
243 
244 	/*
245 	 * Get button state. It's the low three bits
246 	 * (for three buttons) of byte 0.
247 	 */
248 	left	= (buf[0] & 0x04)? 1: 0;
249 	middle	= (buf[0] & 0x02)? 1: 0;
250 	right	= (buf[0] & 0x01)? 1: 0;
251 
252 	vsxxxaa_drop_bytes (mouse, 3);
253 
254 	DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
255 			mouse->name, mouse->phys, dx, dy,
256 			left? "L": "l", middle? "M": "m", right? "R": "r");
257 
258 	/*
259 	 * Report what we've found so far...
260 	 */
261 	input_report_key (dev, BTN_LEFT, left);
262 	input_report_key (dev, BTN_MIDDLE, middle);
263 	input_report_key (dev, BTN_RIGHT, right);
264 	input_report_key (dev, BTN_TOUCH, 0);
265 	input_report_rel (dev, REL_X, dx);
266 	input_report_rel (dev, REL_Y, dy);
267 	input_sync (dev);
268 }
269 
270 static void
271 vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse)
272 {
273 	struct input_dev *dev = mouse->dev;
274 	unsigned char *buf = mouse->buf;
275 	int left, middle, right, touch;
276 	int x, y;
277 
278 	/*
279 	 * Tablet position / button packet
280 	 *
281 	 * [0]:	1	1	0	B4	B3	B2	B1	Pr
282 	 * [1]:	0	0	X5	X4	X3	X2	X1	X0
283 	 * [2]:	0	0	X11	X10	X9	X8	X7	X6
284 	 * [3]:	0	0	Y5	Y4	Y3	Y2	Y1	Y0
285 	 * [4]:	0	0	Y11	Y10	Y9	Y8	Y7	Y6
286 	 */
287 
288 	/*
289 	 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
290 	 * counts down->top while monitor counts top->bottom.
291 	 */
292 	x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
293 	y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
294 	y = 1023 - y;
295 
296 	/*
297 	 * Get button state. It's bits <4..1> of byte 0.
298 	 */
299 	left	= (buf[0] & 0x02)? 1: 0;
300 	middle	= (buf[0] & 0x04)? 1: 0;
301 	right	= (buf[0] & 0x08)? 1: 0;
302 	touch	= (buf[0] & 0x10)? 1: 0;
303 
304 	vsxxxaa_drop_bytes (mouse, 5);
305 
306 	DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
307 			mouse->name, mouse->phys, x, y,
308 			left? "L": "l", middle? "M": "m",
309 			right? "R": "r", touch? "T": "t");
310 
311 	/*
312 	 * Report what we've found so far...
313 	 */
314 	input_report_key (dev, BTN_LEFT, left);
315 	input_report_key (dev, BTN_MIDDLE, middle);
316 	input_report_key (dev, BTN_RIGHT, right);
317 	input_report_key (dev, BTN_TOUCH, touch);
318 	input_report_abs (dev, ABS_X, x);
319 	input_report_abs (dev, ABS_Y, y);
320 	input_sync (dev);
321 }
322 
323 static void
324 vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
325 {
326 	struct input_dev *dev = mouse->dev;
327 	unsigned char *buf = mouse->buf;
328 	int left, middle, right;
329 	unsigned char error;
330 
331 	/*
332 	 * Check for Power-On-Reset packets. These are sent out
333 	 * after plugging the mouse in, or when explicitely
334 	 * requested by sending 'T'.
335 	 *
336 	 * [0]:	1	0	1	0	R3	R2	R1	R0
337 	 * [1]:	0	M2	M1	M0	D3	D2	D1	D0
338 	 * [2]:	0	E6	E5	E4	E3	E2	E1	E0
339 	 * [3]:	0	0	0	0	0	Left	Middle	Right
340 	 *
341 	 * M: manufacturer location code
342 	 * R: revision code
343 	 * E: Error code. If it's in the range of 0x00..0x1f, only some
344 	 *    minor problem occured. Errors >= 0x20 are considered bad
345 	 *    and the device may not work properly...
346 	 * D: <0010> == mouse, <0100> == tablet
347 	 */
348 
349 	mouse->version = buf[0] & 0x0f;
350 	mouse->country = (buf[1] >> 4) & 0x07;
351 	mouse->type = buf[1] & 0x0f;
352 	error = buf[2] & 0x7f;
353 
354 	/*
355 	 * Get button state. It's the low three bits
356 	 * (for three buttons) of byte 0. Maybe even the bit <3>
357 	 * has some meaning if a tablet is attached.
358 	 */
359 	left	= (buf[0] & 0x04)? 1: 0;
360 	middle	= (buf[0] & 0x02)? 1: 0;
361 	right	= (buf[0] & 0x01)? 1: 0;
362 
363 	vsxxxaa_drop_bytes (mouse, 4);
364 	vsxxxaa_detection_done (mouse);
365 
366 	if (error <= 0x1f) {
367 		/* No (serious) error. Report buttons */
368 		input_report_key (dev, BTN_LEFT, left);
369 		input_report_key (dev, BTN_MIDDLE, middle);
370 		input_report_key (dev, BTN_RIGHT, right);
371 		input_report_key (dev, BTN_TOUCH, 0);
372 		input_sync (dev);
373 
374 		if (error != 0)
375 			printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
376 					mouse->name, mouse->phys, error);
377 
378 	}
379 
380 	/*
381 	 * If the mouse was hot-plugged, we need to force differential mode
382 	 * now... However, give it a second to recover from it's reset.
383 	 */
384 	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
385 			"incremental streaming mode and 72 samples/sec\n",
386 			mouse->name, mouse->phys);
387 	mouse->serio->write (mouse->serio, 'S');	/* Standard format */
388 	mdelay (50);
389 	mouse->serio->write (mouse->serio, 'R');	/* Incremental */
390 	mdelay (50);
391 	mouse->serio->write (mouse->serio, 'L');	/* 72 samples/sec */
392 }
393 
394 static void
395 vsxxxaa_parse_buffer (struct vsxxxaa *mouse)
396 {
397 	unsigned char *buf = mouse->buf;
398 	int stray_bytes;
399 
400 	/*
401 	 * Parse buffer to death...
402 	 */
403 	do {
404 		/*
405 		 * Out of sync? Throw away what we don't understand. Each
406 		 * packet starts with a byte whose bit 7 is set. Unhandled
407 		 * packets (ie. which we don't know about or simply b0rk3d
408 		 * data...) will get shifted out of the buffer after some
409 		 * activity on the mouse.
410 		 */
411 		while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
412 			printk (KERN_ERR "%s on %s: Dropping a byte to regain "
413 					"sync with mouse data stream...\n",
414 					mouse->name, mouse->phys);
415 			vsxxxaa_drop_bytes (mouse, 1);
416 		}
417 
418 		/*
419 		 * Check for packets we know about.
420 		 */
421 
422 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
423 			/* Check for broken packet */
424 			stray_bytes = vsxxxaa_check_packet (mouse, 3);
425 			if (stray_bytes > 0) {
426 				printk (KERN_ERR "Dropping %d bytes now...\n",
427 						stray_bytes);
428 				vsxxxaa_drop_bytes (mouse, stray_bytes);
429 				continue;
430 			}
431 
432 			vsxxxaa_handle_REL_packet (mouse);
433 			continue; /* More to parse? */
434 		}
435 
436 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
437 			/* Check for broken packet */
438 			stray_bytes = vsxxxaa_check_packet (mouse, 5);
439 			if (stray_bytes > 0) {
440 				printk (KERN_ERR "Dropping %d bytes now...\n",
441 						stray_bytes);
442 				vsxxxaa_drop_bytes (mouse, stray_bytes);
443 				continue;
444 			}
445 
446 			vsxxxaa_handle_ABS_packet (mouse);
447 			continue; /* More to parse? */
448 		}
449 
450 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
451 			/* Check for broken packet */
452 			stray_bytes = vsxxxaa_check_packet (mouse, 4);
453 			if (stray_bytes > 0) {
454 				printk (KERN_ERR "Dropping %d bytes now...\n",
455 						stray_bytes);
456 				vsxxxaa_drop_bytes (mouse, stray_bytes);
457 				continue;
458 			}
459 
460 			vsxxxaa_handle_POR_packet (mouse);
461 			continue; /* More to parse? */
462 		}
463 
464 		break; /* No REL, ABS or POR packet found */
465 	} while (1);
466 }
467 
468 static irqreturn_t
469 vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
470 {
471 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
472 
473 	vsxxxaa_queue_byte (mouse, data);
474 	vsxxxaa_parse_buffer (mouse);
475 
476 	return IRQ_HANDLED;
477 }
478 
479 static void
480 vsxxxaa_disconnect (struct serio *serio)
481 {
482 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
483 
484 	serio_close (serio);
485 	serio_set_drvdata (serio, NULL);
486 	input_unregister_device (mouse->dev);
487 	kfree (mouse);
488 }
489 
490 static int
491 vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
492 {
493 	struct vsxxxaa *mouse;
494 	struct input_dev *input_dev;
495 	int err = -ENOMEM;
496 
497 	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
498 	input_dev = input_allocate_device ();
499 	if (!mouse || !input_dev)
500 		goto fail1;
501 
502 	mouse->dev = input_dev;
503 	mouse->serio = serio;
504 	strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
505 		 sizeof (mouse->name));
506 	snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys);
507 
508 	input_dev->name = mouse->name;
509 	input_dev->phys = mouse->phys;
510 	input_dev->id.bustype = BUS_RS232;
511 	input_dev->dev.parent = &serio->dev;
512 
513 	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
514 	set_bit (EV_REL, input_dev->evbit);
515 	set_bit (EV_ABS, input_dev->evbit);
516 	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
517 	set_bit (BTN_MIDDLE, input_dev->keybit);
518 	set_bit (BTN_RIGHT, input_dev->keybit);
519 	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
520 	set_bit (REL_X, input_dev->relbit);
521 	set_bit (REL_Y, input_dev->relbit);
522 	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
523 	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
524 
525 	serio_set_drvdata (serio, mouse);
526 
527 	err = serio_open (serio, drv);
528 	if (err)
529 		goto fail2;
530 
531 	/*
532 	 * Request selftest. Standard packet format and differential
533 	 * mode will be requested after the device ID'ed successfully.
534 	 */
535 	serio->write (serio, 'T'); /* Test */
536 
537 	err = input_register_device (input_dev);
538 	if (err)
539 		goto fail3;
540 
541 	return 0;
542 
543  fail3:	serio_close (serio);
544  fail2:	serio_set_drvdata (serio, NULL);
545  fail1:	input_free_device (input_dev);
546 	kfree (mouse);
547 	return err;
548 }
549 
550 static struct serio_device_id vsxxaa_serio_ids[] = {
551 	{
552 		.type	= SERIO_RS232,
553 		.proto	= SERIO_VSXXXAA,
554 		.id	= SERIO_ANY,
555 		.extra	= SERIO_ANY,
556 	},
557 	{ 0 }
558 };
559 
560 MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
561 
562 static struct serio_driver vsxxxaa_drv = {
563 	.driver		= {
564 		.name	= "vsxxxaa",
565 	},
566 	.description	= DRIVER_DESC,
567 	.id_table	= vsxxaa_serio_ids,
568 	.connect	= vsxxxaa_connect,
569 	.interrupt	= vsxxxaa_interrupt,
570 	.disconnect	= vsxxxaa_disconnect,
571 };
572 
573 static int __init
574 vsxxxaa_init (void)
575 {
576 	return serio_register_driver(&vsxxxaa_drv);
577 }
578 
579 static void __exit
580 vsxxxaa_exit (void)
581 {
582 	serio_unregister_driver(&vsxxxaa_drv);
583 }
584 
585 module_init (vsxxxaa_init);
586 module_exit (vsxxxaa_exit);
587 
588