2 * DEC VSXXX-AA and VSXXX-GA mouse driver.
4 * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
6 * The packet format was taken from a patch to GPM which is (C) 2001
7 * by Karsten Merker <merker@linuxtag.org>
8 * and Maciej W. Rozycki <macro@ds2.pg.gda.pl>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Building an adaptor to DB9 / DB25 RS232
29 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for
32 * anything if you break your mouse, your computer or whatever!
34 * In theory, this mouse is a simple RS232 device. In practice, it has got
35 * a quite uncommon plug and the requirement to additionally get a power
36 * supply at +5V and -12V.
38 * If you look at the socket/jack (_not_ at the plug), we use this pin
46 * DEC socket DB9 DB25 Note
50 * 4 (-12V) - - Somewhere from the PSU. At ATX, it's
51 * the thin blue wire at pin 12 of the
52 * ATX power connector. Only required for
54 * 5 (+5V) - - PSU (red wires of ATX power connector
55 * on pin 4, 6, 19 or 20) or HDD power
56 * connector (also red wire).
57 * 6 (+12V) - - HDD power connector, yellow wire. Only
58 * required for VSXXX-AB digitizer.
59 * 7 (dev. avail.) - - The mouse shorts this one to pin 1.
60 * This way, the host computer can detect
61 * the mouse. To use it with the adaptor,
62 * simply don't connect this pin.
64 * So to get a working adaptor, you need to connect the mouse with three
65 * wires to a RS232 port and two or three additional wires for +5V, +12V and
68 * Flow specification for the link is 4800, 8o1.
70 * The mice and tablet are described in "VCB02 Video Subsystem - Technical
71 * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
72 * specific for DEC documentation. Try
73 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
76 #include <linux/delay.h>
77 #include <linux/module.h>
78 #include <linux/slab.h>
79 #include <linux/interrupt.h>
80 #include <linux/input.h>
81 #include <linux/config.h>
82 #include <linux/serio.h>
83 #include <linux/init.h>
85 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
86 MODULE_DESCRIPTION ("Serial DEC VSXXX-AA/GA mouse / DEC tablet driver");
87 MODULE_LICENSE ("GPL");
91 #define DBG(x...) printk (x)
93 #define DBG(x...) do {} while (0)
96 #define VSXXXAA_INTRO_MASK 0x80
97 #define VSXXXAA_INTRO_HEAD 0x80
98 #define IS_HDR_BYTE(x) (((x) & VSXXXAA_INTRO_MASK) \
99 == VSXXXAA_INTRO_HEAD)
101 #define VSXXXAA_PACKET_MASK 0xe0
102 #define VSXXXAA_PACKET_REL 0x80
103 #define VSXXXAA_PACKET_ABS 0xc0
104 #define VSXXXAA_PACKET_POR 0xa0
105 #define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == type)
110 struct input_dev dev;
112 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
113 unsigned char buf[BUFLEN];
115 unsigned char version;
116 unsigned char country;
123 vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num)
125 if (num >= mouse->count)
128 memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num);
134 vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
136 if (mouse->count == BUFLEN) {
137 printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
138 mouse->name, mouse->phys);
139 vsxxxaa_drop_bytes (mouse, 1);
141 DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
143 mouse->buf[mouse->count++] = byte;
147 vsxxxaa_detection_done (struct vsxxxaa *mouse)
149 switch (mouse->type) {
151 sprintf (mouse->name, "DEC VSXXX-AA/GA mouse");
155 sprintf (mouse->name, "DEC VSXXX-AB digitizer");
159 sprintf (mouse->name, "unknown DEC pointer device");
163 printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x "
164 "on port %s\n", mouse->name, mouse->version,
165 mouse->country, mouse->phys);
169 * Returns number of bytes to be dropped, 0 if packet is okay.
172 vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
176 /* First byte must be a header byte */
177 if (!IS_HDR_BYTE (mouse->buf[0])) {
178 DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
182 /* Check all following bytes */
183 if (packet_len > 1) {
184 for (i = 1; i < packet_len; i++) {
185 if (IS_HDR_BYTE (mouse->buf[i])) {
186 printk (KERN_ERR "Need to drop %d bytes "
187 "of a broken packet.\n",
189 DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
190 packet_len, i, mouse->buf[i]);
199 static __inline__ int
200 vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
202 return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
206 vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
208 struct input_dev *dev = &mouse->dev;
209 unsigned char *buf = mouse->buf;
210 int left, middle, right;
214 * Check for normal stream packets. This is three bytes,
215 * with the first byte's 3 MSB set to 100.
217 * [0]: 1 0 0 SignX SignY Left Middle Right
218 * [1]: 0 dx dx dx dx dx dx dx
219 * [2]: 0 dy dy dy dy dy dy dy
223 * Low 7 bit of byte 1 are abs(dx), bit 7 is
224 * 0, bit 4 of byte 0 is direction.
227 dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
230 * Low 7 bit of byte 2 are abs(dy), bit 7 is
231 * 0, bit 3 of byte 0 is direction.
234 dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
237 * Get button state. It's the low three bits
238 * (for three buttons) of byte 0.
240 left = (buf[0] & 0x04)? 1: 0;
241 middle = (buf[0] & 0x02)? 1: 0;
242 right = (buf[0] & 0x01)? 1: 0;
244 vsxxxaa_drop_bytes (mouse, 3);
246 DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
247 mouse->name, mouse->phys, dx, dy,
248 left? "L": "l", middle? "M": "m", right? "R": "r");
251 * Report what we've found so far...
253 input_regs (dev, regs);
254 input_report_key (dev, BTN_LEFT, left);
255 input_report_key (dev, BTN_MIDDLE, middle);
256 input_report_key (dev, BTN_RIGHT, right);
257 input_report_key (dev, BTN_TOUCH, 0);
258 input_report_rel (dev, REL_X, dx);
259 input_report_rel (dev, REL_Y, dy);
264 vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
266 struct input_dev *dev = &mouse->dev;
267 unsigned char *buf = mouse->buf;
268 int left, middle, right, touch;
272 * Tablet position / button packet
274 * [0]: 1 1 0 B4 B3 B2 B1 Pr
275 * [1]: 0 0 X5 X4 X3 X2 X1 X0
276 * [2]: 0 0 X11 X10 X9 X8 X7 X6
277 * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0
278 * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6
282 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
283 * counts down->top while monitor counts top->bottom.
285 x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
286 y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
290 * Get button state. It's bits <4..1> of byte 0.
292 left = (buf[0] & 0x02)? 1: 0;
293 middle = (buf[0] & 0x04)? 1: 0;
294 right = (buf[0] & 0x08)? 1: 0;
295 touch = (buf[0] & 0x10)? 1: 0;
297 vsxxxaa_drop_bytes (mouse, 5);
299 DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
300 mouse->name, mouse->phys, x, y,
301 left? "L": "l", middle? "M": "m",
302 right? "R": "r", touch? "T": "t");
305 * Report what we've found so far...
307 input_regs (dev, regs);
308 input_report_key (dev, BTN_LEFT, left);
309 input_report_key (dev, BTN_MIDDLE, middle);
310 input_report_key (dev, BTN_RIGHT, right);
311 input_report_key (dev, BTN_TOUCH, touch);
312 input_report_abs (dev, ABS_X, x);
313 input_report_abs (dev, ABS_Y, y);
318 vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
320 struct input_dev *dev = &mouse->dev;
321 unsigned char *buf = mouse->buf;
322 int left, middle, right;
326 * Check for Power-On-Reset packets. These are sent out
327 * after plugging the mouse in, or when explicitely
328 * requested by sending 'T'.
330 * [0]: 1 0 1 0 R3 R2 R1 R0
331 * [1]: 0 M2 M1 M0 D3 D2 D1 D0
332 * [2]: 0 E6 E5 E4 E3 E2 E1 E0
333 * [3]: 0 0 0 0 0 Left Middle Right
335 * M: manufacturer location code
337 * E: Error code. I'm not sure about these, but gpm's sources,
338 * which support this mouse, too, tell about them:
339 * E = [0x00 .. 0x1f]: no error, byte #3 is button state
340 * E = 0x3d: button error, byte #3 tells which one.
341 * E = <else>: other error
342 * D: <0010> == mouse, <0100> == tablet
346 mouse->version = buf[0] & 0x0f;
347 mouse->country = (buf[1] >> 4) & 0x07;
348 mouse->type = buf[1] & 0x0f;
349 error = buf[2] & 0x7f;
352 * Get button state. It's the low three bits
353 * (for three buttons) of byte 0. Maybe even the bit <3>
354 * has some meaning if a tablet is attached.
356 left = (buf[0] & 0x04)? 1: 0;
357 middle = (buf[0] & 0x02)? 1: 0;
358 right = (buf[0] & 0x01)? 1: 0;
360 vsxxxaa_drop_bytes (mouse, 4);
361 vsxxxaa_detection_done (mouse);
364 /* No error. Report buttons */
365 input_regs (dev, regs);
366 input_report_key (dev, BTN_LEFT, left);
367 input_report_key (dev, BTN_MIDDLE, middle);
368 input_report_key (dev, BTN_RIGHT, right);
369 input_report_key (dev, BTN_TOUCH, 0);
372 printk (KERN_ERR "Your %s on %s reports an undefined error, "
373 "please check it...\n", mouse->name,
378 * If the mouse was hot-plugged, we need to force differential mode
379 * now... However, give it a second to recover from it's reset.
381 printk (KERN_NOTICE "%s on %s: Forceing standard packet format and "
382 "streaming mode\n", mouse->name, mouse->phys);
383 mouse->serio->write (mouse->serio, 'S');
385 mouse->serio->write (mouse->serio, 'R');
389 vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
391 unsigned char *buf = mouse->buf;
395 * Parse buffer to death...
399 * Out of sync? Throw away what we don't understand. Each
400 * packet starts with a byte whose bit 7 is set. Unhandled
401 * packets (ie. which we don't know about or simply b0rk3d
402 * data...) will get shifted out of the buffer after some
403 * activity on the mouse.
405 while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
406 printk (KERN_ERR "%s on %s: Dropping a byte to regain "
407 "sync with mouse data stream...\n",
408 mouse->name, mouse->phys);
409 vsxxxaa_drop_bytes (mouse, 1);
413 * Check for packets we know about.
416 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
417 /* Check for broken packet */
418 stray_bytes = vsxxxaa_check_packet (mouse, 3);
419 if (stray_bytes > 0) {
420 printk (KERN_ERR "Dropping %d bytes now...\n",
422 vsxxxaa_drop_bytes (mouse, stray_bytes);
426 vsxxxaa_handle_REL_packet (mouse, regs);
427 continue; /* More to parse? */
430 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
431 /* Check for broken packet */
432 stray_bytes = vsxxxaa_check_packet (mouse, 5);
433 if (stray_bytes > 0) {
434 printk (KERN_ERR "Dropping %d bytes now...\n",
436 vsxxxaa_drop_bytes (mouse, stray_bytes);
440 vsxxxaa_handle_ABS_packet (mouse, regs);
441 continue; /* More to parse? */
444 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
445 /* Check for broken packet */
446 stray_bytes = vsxxxaa_check_packet (mouse, 4);
447 if (stray_bytes > 0) {
448 printk (KERN_ERR "Dropping %d bytes now...\n",
450 vsxxxaa_drop_bytes (mouse, stray_bytes);
454 vsxxxaa_handle_POR_packet (mouse, regs);
455 continue; /* More to parse? */
458 break; /* No REL, ABS or POR packet found */
463 vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
464 struct pt_regs *regs)
466 struct vsxxxaa *mouse = serio->private;
468 vsxxxaa_queue_byte (mouse, data);
469 vsxxxaa_parse_buffer (mouse, regs);
475 vsxxxaa_disconnect (struct serio *serio)
477 struct vsxxxaa *mouse = serio->private;
479 input_unregister_device (&mouse->dev);
485 vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
487 struct vsxxxaa *mouse;
489 if ((serio->type & SERIO_TYPE) != SERIO_RS232)
491 if ((serio->type & SERIO_PROTO) != SERIO_VSXXXAA)
494 if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
497 memset (mouse, 0, sizeof (struct vsxxxaa));
499 init_input_dev (&mouse->dev);
500 set_bit (EV_KEY, mouse->dev.evbit); /* We have buttons */
501 set_bit (EV_REL, mouse->dev.evbit);
502 set_bit (EV_ABS, mouse->dev.evbit);
503 set_bit (BTN_LEFT, mouse->dev.keybit); /* We have 3 buttons */
504 set_bit (BTN_MIDDLE, mouse->dev.keybit);
505 set_bit (BTN_RIGHT, mouse->dev.keybit);
506 set_bit (BTN_TOUCH, mouse->dev.keybit); /* ...and Tablet */
507 set_bit (REL_X, mouse->dev.relbit);
508 set_bit (REL_Y, mouse->dev.relbit);
509 set_bit (ABS_X, mouse->dev.absbit);
510 set_bit (ABS_Y, mouse->dev.absbit);
512 mouse->dev.absmin[ABS_X] = 0;
513 mouse->dev.absmax[ABS_X] = 1023;
514 mouse->dev.absmin[ABS_Y] = 0;
515 mouse->dev.absmax[ABS_Y] = 1023;
517 mouse->dev.private = mouse;
518 serio->private = mouse;
520 sprintf (mouse->name, "DEC VSXXX-AA/GA mouse or VSXXX-AB digitizer");
521 sprintf (mouse->phys, "%s/input0", serio->phys);
522 mouse->dev.name = mouse->name;
523 mouse->dev.phys = mouse->phys;
524 mouse->dev.id.bustype = BUS_RS232;
525 mouse->serio = serio;
527 if (serio_open (serio, dev)) {
533 * Request selftest. Standard packet format and differential
534 * mode will be requested after the device ID'ed successfully.
536 mouse->serio->write (mouse->serio, 'T'); /* Test */
538 input_register_device (&mouse->dev);
540 printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
543 static struct serio_dev vsxxxaa_dev = {
544 .connect = vsxxxaa_connect,
545 .interrupt = vsxxxaa_interrupt,
546 .disconnect = vsxxxaa_disconnect,
552 serio_register_device (&vsxxxaa_dev);
559 serio_unregister_device (&vsxxxaa_dev);
562 module_init (vsxxxaa_init);
563 module_exit (vsxxxaa_exit);