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 #define DRIVER_DESC "Serial DEC VSXXX-AA/GA mouse / DEC tablet driver"
87 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
88 MODULE_DESCRIPTION (DRIVER_DESC
);
89 MODULE_LICENSE ("GPL");
93 #define DBG(x...) printk (x)
95 #define DBG(x...) do {} while (0)
98 #define VSXXXAA_INTRO_MASK 0x80
99 #define VSXXXAA_INTRO_HEAD 0x80
100 #define IS_HDR_BYTE(x) (((x) & VSXXXAA_INTRO_MASK) \
101 == VSXXXAA_INTRO_HEAD)
103 #define VSXXXAA_PACKET_MASK 0xe0
104 #define VSXXXAA_PACKET_REL 0x80
105 #define VSXXXAA_PACKET_ABS 0xc0
106 #define VSXXXAA_PACKET_POR 0xa0
107 #define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == type)
112 struct input_dev dev
;
114 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
115 unsigned char buf
[BUFLEN
];
117 unsigned char version
;
118 unsigned char country
;
125 vsxxxaa_drop_bytes (struct vsxxxaa
*mouse
, int num
)
127 if (num
>= mouse
->count
)
130 memmove (mouse
->buf
, mouse
->buf
+ num
- 1, BUFLEN
- num
);
136 vsxxxaa_queue_byte (struct vsxxxaa
*mouse
, unsigned char byte
)
138 if (mouse
->count
== BUFLEN
) {
139 printk (KERN_ERR
"%s on %s: Dropping a byte of full buffer.\n",
140 mouse
->name
, mouse
->phys
);
141 vsxxxaa_drop_bytes (mouse
, 1);
143 DBG (KERN_INFO
"Queueing byte 0x%02x\n", byte
);
145 mouse
->buf
[mouse
->count
++] = byte
;
149 vsxxxaa_detection_done (struct vsxxxaa
*mouse
)
151 switch (mouse
->type
) {
153 sprintf (mouse
->name
, "DEC VSXXX-AA/GA mouse");
157 sprintf (mouse
->name
, "DEC VSXXX-AB digitizer");
161 sprintf (mouse
->name
, "unknown DEC pointer device");
165 printk (KERN_INFO
"Found %s version 0x%02x from country 0x%02x "
166 "on port %s\n", mouse
->name
, mouse
->version
,
167 mouse
->country
, mouse
->phys
);
171 * Returns number of bytes to be dropped, 0 if packet is okay.
174 vsxxxaa_check_packet (struct vsxxxaa
*mouse
, int packet_len
)
178 /* First byte must be a header byte */
179 if (!IS_HDR_BYTE (mouse
->buf
[0])) {
180 DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len
, mouse
->buf
[0]);
184 /* Check all following bytes */
185 if (packet_len
> 1) {
186 for (i
= 1; i
< packet_len
; i
++) {
187 if (IS_HDR_BYTE (mouse
->buf
[i
])) {
188 printk (KERN_ERR
"Need to drop %d bytes "
189 "of a broken packet.\n",
191 DBG (KERN_INFO
"check: len=%d, b[%d]=0x%02x\n",
192 packet_len
, i
, mouse
->buf
[i
]);
201 static __inline__
int
202 vsxxxaa_smells_like_packet (struct vsxxxaa
*mouse
, unsigned char type
, size_t len
)
204 return (mouse
->count
>= len
) && MATCH_PACKET_TYPE (mouse
->buf
[0], type
);
208 vsxxxaa_handle_REL_packet (struct vsxxxaa
*mouse
, struct pt_regs
*regs
)
210 struct input_dev
*dev
= &mouse
->dev
;
211 unsigned char *buf
= mouse
->buf
;
212 int left
, middle
, right
;
216 * Check for normal stream packets. This is three bytes,
217 * with the first byte's 3 MSB set to 100.
219 * [0]: 1 0 0 SignX SignY Left Middle Right
220 * [1]: 0 dx dx dx dx dx dx dx
221 * [2]: 0 dy dy dy dy dy dy dy
225 * Low 7 bit of byte 1 are abs(dx), bit 7 is
226 * 0, bit 4 of byte 0 is direction.
229 dx
*= ((buf
[0] >> 4) & 0x01)? 1: -1;
232 * Low 7 bit of byte 2 are abs(dy), bit 7 is
233 * 0, bit 3 of byte 0 is direction.
236 dy
*= ((buf
[0] >> 3) & 0x01)? -1: 1;
239 * Get button state. It's the low three bits
240 * (for three buttons) of byte 0.
242 left
= (buf
[0] & 0x04)? 1: 0;
243 middle
= (buf
[0] & 0x02)? 1: 0;
244 right
= (buf
[0] & 0x01)? 1: 0;
246 vsxxxaa_drop_bytes (mouse
, 3);
248 DBG (KERN_INFO
"%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
249 mouse
->name
, mouse
->phys
, dx
, dy
,
250 left
? "L": "l", middle
? "M": "m", right
? "R": "r");
253 * Report what we've found so far...
255 input_regs (dev
, regs
);
256 input_report_key (dev
, BTN_LEFT
, left
);
257 input_report_key (dev
, BTN_MIDDLE
, middle
);
258 input_report_key (dev
, BTN_RIGHT
, right
);
259 input_report_key (dev
, BTN_TOUCH
, 0);
260 input_report_rel (dev
, REL_X
, dx
);
261 input_report_rel (dev
, REL_Y
, dy
);
266 vsxxxaa_handle_ABS_packet (struct vsxxxaa
*mouse
, struct pt_regs
*regs
)
268 struct input_dev
*dev
= &mouse
->dev
;
269 unsigned char *buf
= mouse
->buf
;
270 int left
, middle
, right
, touch
;
274 * Tablet position / button packet
276 * [0]: 1 1 0 B4 B3 B2 B1 Pr
277 * [1]: 0 0 X5 X4 X3 X2 X1 X0
278 * [2]: 0 0 X11 X10 X9 X8 X7 X6
279 * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0
280 * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6
284 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
285 * counts down->top while monitor counts top->bottom.
287 x
= ((buf
[2] & 0x3f) << 6) | (buf
[1] & 0x3f);
288 y
= ((buf
[4] & 0x3f) << 6) | (buf
[3] & 0x3f);
292 * Get button state. It's bits <4..1> of byte 0.
294 left
= (buf
[0] & 0x02)? 1: 0;
295 middle
= (buf
[0] & 0x04)? 1: 0;
296 right
= (buf
[0] & 0x08)? 1: 0;
297 touch
= (buf
[0] & 0x10)? 1: 0;
299 vsxxxaa_drop_bytes (mouse
, 5);
301 DBG (KERN_INFO
"%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
302 mouse
->name
, mouse
->phys
, x
, y
,
303 left
? "L": "l", middle
? "M": "m",
304 right
? "R": "r", touch
? "T": "t");
307 * Report what we've found so far...
309 input_regs (dev
, regs
);
310 input_report_key (dev
, BTN_LEFT
, left
);
311 input_report_key (dev
, BTN_MIDDLE
, middle
);
312 input_report_key (dev
, BTN_RIGHT
, right
);
313 input_report_key (dev
, BTN_TOUCH
, touch
);
314 input_report_abs (dev
, ABS_X
, x
);
315 input_report_abs (dev
, ABS_Y
, y
);
320 vsxxxaa_handle_POR_packet (struct vsxxxaa
*mouse
, struct pt_regs
*regs
)
322 struct input_dev
*dev
= &mouse
->dev
;
323 unsigned char *buf
= mouse
->buf
;
324 int left
, middle
, right
;
328 * Check for Power-On-Reset packets. These are sent out
329 * after plugging the mouse in, or when explicitely
330 * requested by sending 'T'.
332 * [0]: 1 0 1 0 R3 R2 R1 R0
333 * [1]: 0 M2 M1 M0 D3 D2 D1 D0
334 * [2]: 0 E6 E5 E4 E3 E2 E1 E0
335 * [3]: 0 0 0 0 0 Left Middle Right
337 * M: manufacturer location code
339 * E: Error code. I'm not sure about these, but gpm's sources,
340 * which support this mouse, too, tell about them:
341 * E = [0x00 .. 0x1f]: no error, byte #3 is button state
342 * E = 0x3d: button error, byte #3 tells which one.
343 * E = <else>: other error
344 * D: <0010> == mouse, <0100> == tablet
348 mouse
->version
= buf
[0] & 0x0f;
349 mouse
->country
= (buf
[1] >> 4) & 0x07;
350 mouse
->type
= buf
[1] & 0x0f;
351 error
= buf
[2] & 0x7f;
354 * Get button state. It's the low three bits
355 * (for three buttons) of byte 0. Maybe even the bit <3>
356 * has some meaning if a tablet is attached.
358 left
= (buf
[0] & 0x04)? 1: 0;
359 middle
= (buf
[0] & 0x02)? 1: 0;
360 right
= (buf
[0] & 0x01)? 1: 0;
362 vsxxxaa_drop_bytes (mouse
, 4);
363 vsxxxaa_detection_done (mouse
);
366 /* No error. Report buttons */
367 input_regs (dev
, regs
);
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);
374 printk (KERN_ERR
"Your %s on %s reports an undefined error, "
375 "please check it...\n", mouse
->name
,
380 * If the mouse was hot-plugged, we need to force differential mode
381 * now... However, give it a second to recover from it's reset.
383 printk (KERN_NOTICE
"%s on %s: Forceing standard packet format and "
384 "streaming mode\n", mouse
->name
, mouse
->phys
);
385 mouse
->serio
->write (mouse
->serio
, 'S');
387 mouse
->serio
->write (mouse
->serio
, 'R');
391 vsxxxaa_parse_buffer (struct vsxxxaa
*mouse
, struct pt_regs
*regs
)
393 unsigned char *buf
= mouse
->buf
;
397 * Parse buffer to death...
401 * Out of sync? Throw away what we don't understand. Each
402 * packet starts with a byte whose bit 7 is set. Unhandled
403 * packets (ie. which we don't know about or simply b0rk3d
404 * data...) will get shifted out of the buffer after some
405 * activity on the mouse.
407 while (mouse
->count
> 0 && !IS_HDR_BYTE(buf
[0])) {
408 printk (KERN_ERR
"%s on %s: Dropping a byte to regain "
409 "sync with mouse data stream...\n",
410 mouse
->name
, mouse
->phys
);
411 vsxxxaa_drop_bytes (mouse
, 1);
415 * Check for packets we know about.
418 if (vsxxxaa_smells_like_packet (mouse
, VSXXXAA_PACKET_REL
, 3)) {
419 /* Check for broken packet */
420 stray_bytes
= vsxxxaa_check_packet (mouse
, 3);
421 if (stray_bytes
> 0) {
422 printk (KERN_ERR
"Dropping %d bytes now...\n",
424 vsxxxaa_drop_bytes (mouse
, stray_bytes
);
428 vsxxxaa_handle_REL_packet (mouse
, regs
);
429 continue; /* More to parse? */
432 if (vsxxxaa_smells_like_packet (mouse
, VSXXXAA_PACKET_ABS
, 5)) {
433 /* Check for broken packet */
434 stray_bytes
= vsxxxaa_check_packet (mouse
, 5);
435 if (stray_bytes
> 0) {
436 printk (KERN_ERR
"Dropping %d bytes now...\n",
438 vsxxxaa_drop_bytes (mouse
, stray_bytes
);
442 vsxxxaa_handle_ABS_packet (mouse
, regs
);
443 continue; /* More to parse? */
446 if (vsxxxaa_smells_like_packet (mouse
, VSXXXAA_PACKET_POR
, 4)) {
447 /* Check for broken packet */
448 stray_bytes
= vsxxxaa_check_packet (mouse
, 4);
449 if (stray_bytes
> 0) {
450 printk (KERN_ERR
"Dropping %d bytes now...\n",
452 vsxxxaa_drop_bytes (mouse
, stray_bytes
);
456 vsxxxaa_handle_POR_packet (mouse
, regs
);
457 continue; /* More to parse? */
460 break; /* No REL, ABS or POR packet found */
465 vsxxxaa_interrupt (struct serio
*serio
, unsigned char data
, unsigned int flags
,
466 struct pt_regs
*regs
)
468 struct vsxxxaa
*mouse
= serio
->private;
470 vsxxxaa_queue_byte (mouse
, data
);
471 vsxxxaa_parse_buffer (mouse
, regs
);
477 vsxxxaa_disconnect (struct serio
*serio
)
479 struct vsxxxaa
*mouse
= serio
->private;
481 input_unregister_device (&mouse
->dev
);
487 vsxxxaa_connect (struct serio
*serio
, struct serio_driver
*drv
)
489 struct vsxxxaa
*mouse
;
491 if ((serio
->type
& SERIO_TYPE
) != SERIO_RS232
)
493 if ((serio
->type
& SERIO_PROTO
) != SERIO_VSXXXAA
)
496 if (!(mouse
= kmalloc (sizeof (struct vsxxxaa
), GFP_KERNEL
)))
499 memset (mouse
, 0, sizeof (struct vsxxxaa
));
501 init_input_dev (&mouse
->dev
);
502 set_bit (EV_KEY
, mouse
->dev
.evbit
); /* We have buttons */
503 set_bit (EV_REL
, mouse
->dev
.evbit
);
504 set_bit (EV_ABS
, mouse
->dev
.evbit
);
505 set_bit (BTN_LEFT
, mouse
->dev
.keybit
); /* We have 3 buttons */
506 set_bit (BTN_MIDDLE
, mouse
->dev
.keybit
);
507 set_bit (BTN_RIGHT
, mouse
->dev
.keybit
);
508 set_bit (BTN_TOUCH
, mouse
->dev
.keybit
); /* ...and Tablet */
509 set_bit (REL_X
, mouse
->dev
.relbit
);
510 set_bit (REL_Y
, mouse
->dev
.relbit
);
511 set_bit (ABS_X
, mouse
->dev
.absbit
);
512 set_bit (ABS_Y
, mouse
->dev
.absbit
);
514 mouse
->dev
.absmin
[ABS_X
] = 0;
515 mouse
->dev
.absmax
[ABS_X
] = 1023;
516 mouse
->dev
.absmin
[ABS_Y
] = 0;
517 mouse
->dev
.absmax
[ABS_Y
] = 1023;
519 mouse
->dev
.private = mouse
;
520 serio
->private = mouse
;
522 sprintf (mouse
->name
, "DEC VSXXX-AA/GA mouse or VSXXX-AB digitizer");
523 sprintf (mouse
->phys
, "%s/input0", serio
->phys
);
524 mouse
->dev
.name
= mouse
->name
;
525 mouse
->dev
.phys
= mouse
->phys
;
526 mouse
->dev
.id
.bustype
= BUS_RS232
;
527 mouse
->serio
= serio
;
529 if (serio_open (serio
, drv
)) {
535 * Request selftest. Standard packet format and differential
536 * mode will be requested after the device ID'ed successfully.
538 mouse
->serio
->write (mouse
->serio
, 'T'); /* Test */
540 input_register_device (&mouse
->dev
);
542 printk (KERN_INFO
"input: %s on %s\n", mouse
->name
, mouse
->phys
);
545 static struct serio_driver vsxxxaa_drv
= {
549 .description
= DRIVER_DESC
,
550 .connect
= vsxxxaa_connect
,
551 .interrupt
= vsxxxaa_interrupt
,
552 .disconnect
= vsxxxaa_disconnect
,
558 serio_register_driver(&vsxxxaa_drv
);
565 serio_unregister_driver(&vsxxxaa_drv
);
568 module_init (vsxxxaa_init
);
569 module_exit (vsxxxaa_exit
);