1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers)
4 * DEC VSXXX-GA mouse (rectangular mouse, with ball)
5 * DEC VSXXX-AB tablet (digitizer with hair cross or stylus)
7 * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
9 * The packet format was initially taken from a patch to GPM which is (C) 2001
10 * by Karsten Merker <merker@linuxtag.org>
11 * and Maciej W. Rozycki <macro@ds2.pg.gda.pl>
12 * Later on, I had access to the device's documentation (referenced below).
16 * Building an adaptor to DE9 / DB25 RS232
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for
20 * anything if you break your mouse, your computer or whatever!
22 * In theory, this mouse is a simple RS232 device. In practice, it has got
23 * a quite uncommon plug and the requirement to additionally get a power
24 * supply at +5V and -12V.
26 * If you look at the socket/jack (_not_ at the plug), we use this pin
34 * DEC socket DE9 DB25 Note
38 * 4 (-12V) - - Somewhere from the PSU. At ATX, it's
39 * the thin blue wire at pin 12 of the
40 * ATX power connector. Only required for
42 * 5 (+5V) - - PSU (red wires of ATX power connector
43 * on pin 4, 6, 19 or 20) or HDD power
44 * connector (also red wire).
45 * 6 (+12V) - - HDD power connector, yellow wire. Only
46 * required for VSXXX-AB digitizer.
47 * 7 (dev. avail.) - - The mouse shorts this one to pin 1.
48 * This way, the host computer can detect
49 * the mouse. To use it with the adaptor,
50 * simply don't connect this pin.
52 * So to get a working adaptor, you need to connect the mouse with three
53 * wires to a RS232 port and two or three additional wires for +5V, +12V and
56 * Flow specification for the link is 4800, 8o1.
58 * The mice and tablet are described in "VCB02 Video Subsystem - Technical
59 * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
60 * specific for DEC documentation. Try
61 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
64 #include <linux/delay.h>
65 #include <linux/module.h>
66 #include <linux/slab.h>
67 #include <linux/interrupt.h>
68 #include <linux/input.h>
69 #include <linux/serio.h>
71 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
73 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
74 MODULE_DESCRIPTION(DRIVER_DESC
);
75 MODULE_LICENSE("GPL");
79 #define DBG(x...) printk(x)
81 #define DBG(x...) do {} while (0)
84 #define VSXXXAA_INTRO_MASK 0x80
85 #define VSXXXAA_INTRO_HEAD 0x80
86 #define IS_HDR_BYTE(x) \
87 (((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD)
89 #define VSXXXAA_PACKET_MASK 0xe0
90 #define VSXXXAA_PACKET_REL 0x80
91 #define VSXXXAA_PACKET_ABS 0xc0
92 #define VSXXXAA_PACKET_POR 0xa0
93 #define MATCH_PACKET_TYPE(data, type) \
94 (((data) & VSXXXAA_PACKET_MASK) == (type))
99 struct input_dev
*dev
;
101 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
102 unsigned char buf
[BUFLEN
];
104 unsigned char version
;
105 unsigned char country
;
111 static void vsxxxaa_drop_bytes(struct vsxxxaa
*mouse
, int num
)
113 if (num
>= mouse
->count
) {
116 memmove(mouse
->buf
, mouse
->buf
+ num
, BUFLEN
- num
);
121 static void vsxxxaa_queue_byte(struct vsxxxaa
*mouse
, unsigned char byte
)
123 if (mouse
->count
== BUFLEN
) {
124 printk(KERN_ERR
"%s on %s: Dropping a byte of full buffer.\n",
125 mouse
->name
, mouse
->phys
);
126 vsxxxaa_drop_bytes(mouse
, 1);
129 DBG(KERN_INFO
"Queueing byte 0x%02x\n", byte
);
131 mouse
->buf
[mouse
->count
++] = byte
;
134 static void vsxxxaa_detection_done(struct vsxxxaa
*mouse
)
136 switch (mouse
->type
) {
138 strscpy(mouse
->name
, "DEC VSXXX-AA/-GA mouse",
139 sizeof(mouse
->name
));
143 strscpy(mouse
->name
, "DEC VSXXX-AB digitizer",
144 sizeof(mouse
->name
));
148 snprintf(mouse
->name
, sizeof(mouse
->name
),
149 "unknown DEC pointer device (type = 0x%02x)",
155 "Found %s version 0x%02x from country 0x%02x on port %s\n",
156 mouse
->name
, mouse
->version
, mouse
->country
, mouse
->phys
);
160 * Returns number of bytes to be dropped, 0 if packet is okay.
162 static int vsxxxaa_check_packet(struct vsxxxaa
*mouse
, int packet_len
)
166 /* First byte must be a header byte */
167 if (!IS_HDR_BYTE(mouse
->buf
[0])) {
168 DBG("vsck: len=%d, 1st=0x%02x\n", packet_len
, mouse
->buf
[0]);
172 /* Check all following bytes */
173 for (i
= 1; i
< packet_len
; i
++) {
174 if (IS_HDR_BYTE(mouse
->buf
[i
])) {
176 "Need to drop %d bytes of a broken packet.\n",
178 DBG(KERN_INFO
"check: len=%d, b[%d]=0x%02x\n",
179 packet_len
, i
, mouse
->buf
[i
]);
187 static inline int vsxxxaa_smells_like_packet(struct vsxxxaa
*mouse
,
188 unsigned char type
, size_t len
)
190 return mouse
->count
>= len
&& MATCH_PACKET_TYPE(mouse
->buf
[0], type
);
193 static void vsxxxaa_handle_REL_packet(struct vsxxxaa
*mouse
)
195 struct input_dev
*dev
= mouse
->dev
;
196 unsigned char *buf
= mouse
->buf
;
197 int left
, middle
, right
;
201 * Check for normal stream packets. This is three bytes,
202 * with the first byte's 3 MSB set to 100.
204 * [0]: 1 0 0 SignX SignY Left Middle Right
205 * [1]: 0 dx dx dx dx dx dx dx
206 * [2]: 0 dy dy dy dy dy dy dy
210 * Low 7 bit of byte 1 are abs(dx), bit 7 is
211 * 0, bit 4 of byte 0 is direction.
214 dx
*= ((buf
[0] >> 4) & 0x01) ? 1 : -1;
217 * Low 7 bit of byte 2 are abs(dy), bit 7 is
218 * 0, bit 3 of byte 0 is direction.
221 dy
*= ((buf
[0] >> 3) & 0x01) ? -1 : 1;
224 * Get button state. It's the low three bits
225 * (for three buttons) of byte 0.
227 left
= buf
[0] & 0x04;
228 middle
= buf
[0] & 0x02;
229 right
= buf
[0] & 0x01;
231 vsxxxaa_drop_bytes(mouse
, 3);
233 DBG(KERN_INFO
"%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
234 mouse
->name
, mouse
->phys
, dx
, dy
,
235 left
? "L" : "l", middle
? "M" : "m", right
? "R" : "r");
238 * Report what we've found so far...
240 input_report_key(dev
, BTN_LEFT
, left
);
241 input_report_key(dev
, BTN_MIDDLE
, middle
);
242 input_report_key(dev
, BTN_RIGHT
, right
);
243 input_report_key(dev
, BTN_TOUCH
, 0);
244 input_report_rel(dev
, REL_X
, dx
);
245 input_report_rel(dev
, REL_Y
, dy
);
249 static void vsxxxaa_handle_ABS_packet(struct vsxxxaa
*mouse
)
251 struct input_dev
*dev
= mouse
->dev
;
252 unsigned char *buf
= mouse
->buf
;
253 int left
, middle
, right
, touch
;
257 * Tablet position / button packet
259 * [0]: 1 1 0 B4 B3 B2 B1 Pr
260 * [1]: 0 0 X5 X4 X3 X2 X1 X0
261 * [2]: 0 0 X11 X10 X9 X8 X7 X6
262 * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0
263 * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6
267 * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
268 * counts down->top while monitor counts top->bottom.
270 x
= ((buf
[2] & 0x3f) << 6) | (buf
[1] & 0x3f);
271 y
= ((buf
[4] & 0x3f) << 6) | (buf
[3] & 0x3f);
275 * Get button state. It's bits <4..1> of byte 0.
277 left
= buf
[0] & 0x02;
278 middle
= buf
[0] & 0x04;
279 right
= buf
[0] & 0x08;
280 touch
= buf
[0] & 0x10;
282 vsxxxaa_drop_bytes(mouse
, 5);
284 DBG(KERN_INFO
"%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
285 mouse
->name
, mouse
->phys
, x
, y
,
286 left
? "L" : "l", middle
? "M" : "m",
287 right
? "R" : "r", touch
? "T" : "t");
290 * Report what we've found so far...
292 input_report_key(dev
, BTN_LEFT
, left
);
293 input_report_key(dev
, BTN_MIDDLE
, middle
);
294 input_report_key(dev
, BTN_RIGHT
, right
);
295 input_report_key(dev
, BTN_TOUCH
, touch
);
296 input_report_abs(dev
, ABS_X
, x
);
297 input_report_abs(dev
, ABS_Y
, y
);
301 static void vsxxxaa_handle_POR_packet(struct vsxxxaa
*mouse
)
303 struct input_dev
*dev
= mouse
->dev
;
304 unsigned char *buf
= mouse
->buf
;
305 int left
, middle
, right
;
309 * Check for Power-On-Reset packets. These are sent out
310 * after plugging the mouse in, or when explicitly
311 * requested by sending 'T'.
313 * [0]: 1 0 1 0 R3 R2 R1 R0
314 * [1]: 0 M2 M1 M0 D3 D2 D1 D0
315 * [2]: 0 E6 E5 E4 E3 E2 E1 E0
316 * [3]: 0 0 0 0 0 Left Middle Right
318 * M: manufacturer location code
320 * E: Error code. If it's in the range of 0x00..0x1f, only some
321 * minor problem occurred. Errors >= 0x20 are considered bad
322 * and the device may not work properly...
323 * D: <0010> == mouse, <0100> == tablet
326 mouse
->version
= buf
[0] & 0x0f;
327 mouse
->country
= (buf
[1] >> 4) & 0x07;
328 mouse
->type
= buf
[1] & 0x0f;
329 error
= buf
[2] & 0x7f;
332 * Get button state. It's the low three bits
333 * (for three buttons) of byte 0. Maybe even the bit <3>
334 * has some meaning if a tablet is attached.
336 left
= buf
[0] & 0x04;
337 middle
= buf
[0] & 0x02;
338 right
= buf
[0] & 0x01;
340 vsxxxaa_drop_bytes(mouse
, 4);
341 vsxxxaa_detection_done(mouse
);
344 /* No (serious) error. Report buttons */
345 input_report_key(dev
, BTN_LEFT
, left
);
346 input_report_key(dev
, BTN_MIDDLE
, middle
);
347 input_report_key(dev
, BTN_RIGHT
, right
);
348 input_report_key(dev
, BTN_TOUCH
, 0);
352 printk(KERN_INFO
"Your %s on %s reports error=0x%02x\n",
353 mouse
->name
, mouse
->phys
, error
);
358 * If the mouse was hot-plugged, we need to force differential mode
359 * now... However, give it a second to recover from it's reset.
362 "%s on %s: Forcing standard packet format, "
363 "incremental streaming mode and 72 samples/sec\n",
364 mouse
->name
, mouse
->phys
);
365 serio_write(mouse
->serio
, 'S'); /* Standard format */
367 serio_write(mouse
->serio
, 'R'); /* Incremental */
369 serio_write(mouse
->serio
, 'L'); /* 72 samples/sec */
372 static void vsxxxaa_parse_buffer(struct vsxxxaa
*mouse
)
374 unsigned char *buf
= mouse
->buf
;
378 * Parse buffer to death...
382 * Out of sync? Throw away what we don't understand. Each
383 * packet starts with a byte whose bit 7 is set. Unhandled
384 * packets (ie. which we don't know about or simply b0rk3d
385 * data...) will get shifted out of the buffer after some
386 * activity on the mouse.
388 while (mouse
->count
> 0 && !IS_HDR_BYTE(buf
[0])) {
389 printk(KERN_ERR
"%s on %s: Dropping a byte to regain "
390 "sync with mouse data stream...\n",
391 mouse
->name
, mouse
->phys
);
392 vsxxxaa_drop_bytes(mouse
, 1);
396 * Check for packets we know about.
399 if (vsxxxaa_smells_like_packet(mouse
, VSXXXAA_PACKET_REL
, 3)) {
400 /* Check for broken packet */
401 stray_bytes
= vsxxxaa_check_packet(mouse
, 3);
403 vsxxxaa_handle_REL_packet(mouse
);
405 } else if (vsxxxaa_smells_like_packet(mouse
,
406 VSXXXAA_PACKET_ABS
, 5)) {
407 /* Check for broken packet */
408 stray_bytes
= vsxxxaa_check_packet(mouse
, 5);
410 vsxxxaa_handle_ABS_packet(mouse
);
412 } else if (vsxxxaa_smells_like_packet(mouse
,
413 VSXXXAA_PACKET_POR
, 4)) {
414 /* Check for broken packet */
415 stray_bytes
= vsxxxaa_check_packet(mouse
, 4);
417 vsxxxaa_handle_POR_packet(mouse
);
420 break; /* No REL, ABS or POR packet found */
423 if (stray_bytes
> 0) {
424 printk(KERN_ERR
"Dropping %d bytes now...\n",
426 vsxxxaa_drop_bytes(mouse
, stray_bytes
);
432 static irqreturn_t
vsxxxaa_interrupt(struct serio
*serio
,
433 unsigned char data
, unsigned int flags
)
435 struct vsxxxaa
*mouse
= serio_get_drvdata(serio
);
437 vsxxxaa_queue_byte(mouse
, data
);
438 vsxxxaa_parse_buffer(mouse
);
443 static void vsxxxaa_disconnect(struct serio
*serio
)
445 struct vsxxxaa
*mouse
= serio_get_drvdata(serio
);
448 serio_set_drvdata(serio
, NULL
);
449 input_unregister_device(mouse
->dev
);
453 static int vsxxxaa_connect(struct serio
*serio
, struct serio_driver
*drv
)
455 struct vsxxxaa
*mouse
;
456 struct input_dev
*input_dev
;
459 mouse
= kzalloc(sizeof(*mouse
), GFP_KERNEL
);
460 input_dev
= input_allocate_device();
461 if (!mouse
|| !input_dev
)
464 mouse
->dev
= input_dev
;
465 mouse
->serio
= serio
;
466 strlcat(mouse
->name
, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
467 sizeof(mouse
->name
));
468 snprintf(mouse
->phys
, sizeof(mouse
->phys
), "%s/input0", serio
->phys
);
470 input_dev
->name
= mouse
->name
;
471 input_dev
->phys
= mouse
->phys
;
472 input_dev
->id
.bustype
= BUS_RS232
;
473 input_dev
->dev
.parent
= &serio
->dev
;
475 __set_bit(EV_KEY
, input_dev
->evbit
); /* We have buttons */
476 __set_bit(EV_REL
, input_dev
->evbit
);
477 __set_bit(EV_ABS
, input_dev
->evbit
);
478 __set_bit(BTN_LEFT
, input_dev
->keybit
); /* We have 3 buttons */
479 __set_bit(BTN_MIDDLE
, input_dev
->keybit
);
480 __set_bit(BTN_RIGHT
, input_dev
->keybit
);
481 __set_bit(BTN_TOUCH
, input_dev
->keybit
); /* ...and Tablet */
482 __set_bit(REL_X
, input_dev
->relbit
);
483 __set_bit(REL_Y
, input_dev
->relbit
);
484 input_set_abs_params(input_dev
, ABS_X
, 0, 1023, 0, 0);
485 input_set_abs_params(input_dev
, ABS_Y
, 0, 1023, 0, 0);
487 serio_set_drvdata(serio
, mouse
);
489 err
= serio_open(serio
, drv
);
494 * Request selftest. Standard packet format and differential
495 * mode will be requested after the device ID'ed successfully.
497 serio_write(serio
, 'T'); /* Test */
499 err
= input_register_device(input_dev
);
505 fail3
: serio_close(serio
);
506 fail2
: serio_set_drvdata(serio
, NULL
);
507 fail1
: input_free_device(input_dev
);
512 static struct serio_device_id vsxxaa_serio_ids
[] = {
515 .proto
= SERIO_VSXXXAA
,
522 MODULE_DEVICE_TABLE(serio
, vsxxaa_serio_ids
);
524 static struct serio_driver vsxxxaa_drv
= {
528 .description
= DRIVER_DESC
,
529 .id_table
= vsxxaa_serio_ids
,
530 .connect
= vsxxxaa_connect
,
531 .interrupt
= vsxxxaa_interrupt
,
532 .disconnect
= vsxxxaa_disconnect
,
535 module_serio_driver(vsxxxaa_drv
);