xref: /linux/drivers/input/mouse/vsxxxaa.c (revision 858259cf7d1c443c836a2022b78cb281f0a9b95e)
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/config.h>
85 #include <linux/serio.h>
86 #include <linux/init.h>
87 
88 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
89 
90 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
91 MODULE_DESCRIPTION (DRIVER_DESC);
92 MODULE_LICENSE ("GPL");
93 
94 #undef VSXXXAA_DEBUG
95 #ifdef VSXXXAA_DEBUG
96 #define DBG(x...) printk (x)
97 #else
98 #define DBG(x...) do {} while (0)
99 #endif
100 
101 #define VSXXXAA_INTRO_MASK	0x80
102 #define VSXXXAA_INTRO_HEAD	0x80
103 #define IS_HDR_BYTE(x)		(((x) & VSXXXAA_INTRO_MASK)	\
104 					== VSXXXAA_INTRO_HEAD)
105 
106 #define VSXXXAA_PACKET_MASK	0xe0
107 #define VSXXXAA_PACKET_REL	0x80
108 #define VSXXXAA_PACKET_ABS	0xc0
109 #define VSXXXAA_PACKET_POR	0xa0
110 #define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == (type))
111 
112 
113 
114 struct vsxxxaa {
115 	struct input_dev *dev;
116 	struct serio *serio;
117 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
118 	unsigned char buf[BUFLEN];
119 	unsigned char count;
120 	unsigned char version;
121 	unsigned char country;
122 	unsigned char type;
123 	char name[64];
124 	char phys[32];
125 };
126 
127 static void
128 vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num)
129 {
130 	if (num >= mouse->count)
131 		mouse->count = 0;
132 	else {
133 		memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num);
134 		mouse->count -= num;
135 	}
136 }
137 
138 static void
139 vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
140 {
141 	if (mouse->count == BUFLEN) {
142 		printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
143 				mouse->name, mouse->phys);
144 		vsxxxaa_drop_bytes (mouse, 1);
145 	}
146 	DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
147 
148 	mouse->buf[mouse->count++] = byte;
149 }
150 
151 static void
152 vsxxxaa_detection_done (struct vsxxxaa *mouse)
153 {
154 	switch (mouse->type) {
155 		case 0x02:
156 			sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse");
157 			break;
158 
159 		case 0x04:
160 			sprintf (mouse->name, "DEC VSXXX-AB digitizer");
161 			break;
162 
163 		default:
164 			sprintf (mouse->name, "unknown DEC pointer device "
165 					"(type = 0x%02x)", mouse->type);
166 			break;
167 	}
168 
169 	printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x "
170 			"on port %s\n", mouse->name, mouse->version,
171 			mouse->country, mouse->phys);
172 }
173 
174 /*
175  * Returns number of bytes to be dropped, 0 if packet is okay.
176  */
177 static int
178 vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
179 {
180 	int i;
181 
182 	/* First byte must be a header byte */
183 	if (!IS_HDR_BYTE (mouse->buf[0])) {
184 		DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
185 		return 1;
186 	}
187 
188 	/* Check all following bytes */
189 	if (packet_len > 1) {
190 		for (i = 1; i < packet_len; i++) {
191 			if (IS_HDR_BYTE (mouse->buf[i])) {
192 				printk (KERN_ERR "Need to drop %d bytes "
193 						"of a broken packet.\n",
194 						i - 1);
195 				DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
196 						packet_len, i, mouse->buf[i]);
197 				return i - 1;
198 			}
199 		}
200 	}
201 
202 	return 0;
203 }
204 
205 static __inline__ int
206 vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
207 {
208 	return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
209 }
210 
211 static void
212 vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
213 {
214 	struct input_dev *dev = mouse->dev;
215 	unsigned char *buf = mouse->buf;
216 	int left, middle, right;
217 	int dx, dy;
218 
219 	/*
220 	 * Check for normal stream packets. This is three bytes,
221 	 * with the first byte's 3 MSB set to 100.
222 	 *
223 	 * [0]:	1	0	0	SignX	SignY	Left	Middle	Right
224 	 * [1]: 0	dx	dx	dx	dx	dx	dx	dx
225 	 * [2]:	0	dy	dy	dy	dy	dy	dy	dy
226 	 */
227 
228 	/*
229 	 * Low 7 bit of byte 1 are abs(dx), bit 7 is
230 	 * 0, bit 4 of byte 0 is direction.
231 	 */
232 	dx = buf[1] & 0x7f;
233 	dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
234 
235 	/*
236 	 * Low 7 bit of byte 2 are abs(dy), bit 7 is
237 	 * 0, bit 3 of byte 0 is direction.
238 	 */
239 	dy = buf[2] & 0x7f;
240 	dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
241 
242 	/*
243 	 * Get button state. It's the low three bits
244 	 * (for three buttons) of byte 0.
245 	 */
246 	left	= (buf[0] & 0x04)? 1: 0;
247 	middle	= (buf[0] & 0x02)? 1: 0;
248 	right	= (buf[0] & 0x01)? 1: 0;
249 
250 	vsxxxaa_drop_bytes (mouse, 3);
251 
252 	DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
253 			mouse->name, mouse->phys, dx, dy,
254 			left? "L": "l", middle? "M": "m", right? "R": "r");
255 
256 	/*
257 	 * Report what we've found so far...
258 	 */
259 	input_regs (dev, regs);
260 	input_report_key (dev, BTN_LEFT, left);
261 	input_report_key (dev, BTN_MIDDLE, middle);
262 	input_report_key (dev, BTN_RIGHT, right);
263 	input_report_key (dev, BTN_TOUCH, 0);
264 	input_report_rel (dev, REL_X, dx);
265 	input_report_rel (dev, REL_Y, dy);
266 	input_sync (dev);
267 }
268 
269 static void
270 vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
271 {
272 	struct input_dev *dev = mouse->dev;
273 	unsigned char *buf = mouse->buf;
274 	int left, middle, right, touch;
275 	int x, y;
276 
277 	/*
278 	 * Tablet position / button packet
279 	 *
280 	 * [0]:	1	1	0	B4	B3	B2	B1	Pr
281 	 * [1]:	0	0	X5	X4	X3	X2	X1	X0
282 	 * [2]:	0	0	X11	X10	X9	X8	X7	X6
283 	 * [3]:	0	0	Y5	Y4	Y3	Y2	Y1	Y0
284 	 * [4]:	0	0	Y11	Y10	Y9	Y8	Y7	Y6
285 	 */
286 
287 	/*
288 	 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
289 	 * counts down->top while monitor counts top->bottom.
290 	 */
291 	x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
292 	y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
293 	y = 1023 - y;
294 
295 	/*
296 	 * Get button state. It's bits <4..1> of byte 0.
297 	 */
298 	left	= (buf[0] & 0x02)? 1: 0;
299 	middle	= (buf[0] & 0x04)? 1: 0;
300 	right	= (buf[0] & 0x08)? 1: 0;
301 	touch	= (buf[0] & 0x10)? 1: 0;
302 
303 	vsxxxaa_drop_bytes (mouse, 5);
304 
305 	DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
306 			mouse->name, mouse->phys, x, y,
307 			left? "L": "l", middle? "M": "m",
308 			right? "R": "r", touch? "T": "t");
309 
310 	/*
311 	 * Report what we've found so far...
312 	 */
313 	input_regs (dev, regs);
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, struct pt_regs *regs)
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_regs (dev, regs);
369 		input_report_key (dev, BTN_LEFT, left);
370 		input_report_key (dev, BTN_MIDDLE, middle);
371 		input_report_key (dev, BTN_RIGHT, right);
372 		input_report_key (dev, BTN_TOUCH, 0);
373 		input_sync (dev);
374 
375 		if (error != 0)
376 			printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
377 					mouse->name, mouse->phys, error);
378 
379 	}
380 
381 	/*
382 	 * If the mouse was hot-plugged, we need to force differential mode
383 	 * now... However, give it a second to recover from it's reset.
384 	 */
385 	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
386 			"incremental streaming mode and 72 samples/sec\n",
387 			mouse->name, mouse->phys);
388 	mouse->serio->write (mouse->serio, 'S');	/* Standard format */
389 	mdelay (50);
390 	mouse->serio->write (mouse->serio, 'R');	/* Incremental */
391 	mdelay (50);
392 	mouse->serio->write (mouse->serio, 'L');	/* 72 samples/sec */
393 }
394 
395 static void
396 vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
397 {
398 	unsigned char *buf = mouse->buf;
399 	int stray_bytes;
400 
401 	/*
402 	 * Parse buffer to death...
403 	 */
404 	do {
405 		/*
406 		 * Out of sync? Throw away what we don't understand. Each
407 		 * packet starts with a byte whose bit 7 is set. Unhandled
408 		 * packets (ie. which we don't know about or simply b0rk3d
409 		 * data...) will get shifted out of the buffer after some
410 		 * activity on the mouse.
411 		 */
412 		while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
413 			printk (KERN_ERR "%s on %s: Dropping a byte to regain "
414 					"sync with mouse data stream...\n",
415 					mouse->name, mouse->phys);
416 			vsxxxaa_drop_bytes (mouse, 1);
417 		}
418 
419 		/*
420 		 * Check for packets we know about.
421 		 */
422 
423 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
424 			/* Check for broken packet */
425 			stray_bytes = vsxxxaa_check_packet (mouse, 3);
426 			if (stray_bytes > 0) {
427 				printk (KERN_ERR "Dropping %d bytes now...\n",
428 						stray_bytes);
429 				vsxxxaa_drop_bytes (mouse, stray_bytes);
430 				continue;
431 			}
432 
433 			vsxxxaa_handle_REL_packet (mouse, regs);
434 			continue; /* More to parse? */
435 		}
436 
437 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
438 			/* Check for broken packet */
439 			stray_bytes = vsxxxaa_check_packet (mouse, 5);
440 			if (stray_bytes > 0) {
441 				printk (KERN_ERR "Dropping %d bytes now...\n",
442 						stray_bytes);
443 				vsxxxaa_drop_bytes (mouse, stray_bytes);
444 				continue;
445 			}
446 
447 			vsxxxaa_handle_ABS_packet (mouse, regs);
448 			continue; /* More to parse? */
449 		}
450 
451 		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
452 			/* Check for broken packet */
453 			stray_bytes = vsxxxaa_check_packet (mouse, 4);
454 			if (stray_bytes > 0) {
455 				printk (KERN_ERR "Dropping %d bytes now...\n",
456 						stray_bytes);
457 				vsxxxaa_drop_bytes (mouse, stray_bytes);
458 				continue;
459 			}
460 
461 			vsxxxaa_handle_POR_packet (mouse, regs);
462 			continue; /* More to parse? */
463 		}
464 
465 		break; /* No REL, ABS or POR packet found */
466 	} while (1);
467 }
468 
469 static irqreturn_t
470 vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
471 		struct pt_regs *regs)
472 {
473 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
474 
475 	vsxxxaa_queue_byte (mouse, data);
476 	vsxxxaa_parse_buffer (mouse, regs);
477 
478 	return IRQ_HANDLED;
479 }
480 
481 static void
482 vsxxxaa_disconnect (struct serio *serio)
483 {
484 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
485 
486 	serio_close (serio);
487 	serio_set_drvdata (serio, NULL);
488 	input_unregister_device (mouse->dev);
489 	kfree (mouse);
490 }
491 
492 static int
493 vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
494 {
495 	struct vsxxxaa *mouse;
496 	struct input_dev *input_dev;
497 	int err = -ENOMEM;
498 
499 	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
500 	input_dev = input_allocate_device ();
501 	if (!mouse || !input_dev)
502 		goto fail;
503 
504 	mouse->dev = input_dev;
505 	mouse->serio = serio;
506 	sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
507 	sprintf (mouse->phys, "%s/input0", serio->phys);
508 
509 	input_dev->name = mouse->name;
510 	input_dev->phys = mouse->phys;
511 	input_dev->id.bustype = BUS_RS232;
512 	input_dev->cdev.dev = &serio->dev;
513 	input_dev->private = mouse;
514 
515 	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
516 	set_bit (EV_REL, input_dev->evbit);
517 	set_bit (EV_ABS, input_dev->evbit);
518 	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
519 	set_bit (BTN_MIDDLE, input_dev->keybit);
520 	set_bit (BTN_RIGHT, input_dev->keybit);
521 	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
522 	set_bit (REL_X, input_dev->relbit);
523 	set_bit (REL_Y, input_dev->relbit);
524 	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
525 	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
526 
527 	serio_set_drvdata (serio, mouse);
528 
529 	err = serio_open (serio, drv);
530 	if (err)
531 		goto fail;
532 
533 	/*
534 	 * Request selftest. Standard packet format and differential
535 	 * mode will be requested after the device ID'ed successfully.
536 	 */
537 	serio->write (serio, 'T'); /* Test */
538 
539 	input_register_device (input_dev);
540 
541 	return 0;
542 
543  fail:	serio_set_drvdata (serio, NULL);
544 	input_free_device (input_dev);
545 	kfree (mouse);
546 	return err;
547 }
548 
549 static struct serio_device_id vsxxaa_serio_ids[] = {
550 	{
551 		.type	= SERIO_RS232,
552 		.proto	= SERIO_VSXXXAA,
553 		.id	= SERIO_ANY,
554 		.extra	= SERIO_ANY,
555 	},
556 	{ 0 }
557 };
558 
559 MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
560 
561 static struct serio_driver vsxxxaa_drv = {
562 	.driver		= {
563 		.name	= "vsxxxaa",
564 	},
565 	.description	= DRIVER_DESC,
566 	.id_table	= vsxxaa_serio_ids,
567 	.connect	= vsxxxaa_connect,
568 	.interrupt	= vsxxxaa_interrupt,
569 	.disconnect	= vsxxxaa_disconnect,
570 };
571 
572 static int __init
573 vsxxxaa_init (void)
574 {
575 	serio_register_driver(&vsxxxaa_drv);
576 	return 0;
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