Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vsxxxaa.c
Go to the documentation of this file.
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 <[email protected]>
7  *
8  * The packet format was initially taken from a patch to GPM which is (C) 2001
9  * by Karsten Merker <[email protected]>
10  * and Maciej W. Rozycki <[email protected]>
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 <[email protected]>");
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) \
103  (((x) & VSXXXAA_INTRO_MASK) == 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) \
110  (((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 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 vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte)
138 {
139  if (mouse->count == BUFLEN) {
140  printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
141  mouse->name, mouse->phys);
142  vsxxxaa_drop_bytes(mouse, 1);
143  }
144 
145  DBG(KERN_INFO "Queueing byte 0x%02x\n", byte);
146 
147  mouse->buf[mouse->count++] = byte;
148 }
149 
150 static void vsxxxaa_detection_done(struct vsxxxaa *mouse)
151 {
152  switch (mouse->type) {
153  case 0x02:
154  strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse",
155  sizeof(mouse->name));
156  break;
157 
158  case 0x04:
159  strlcpy(mouse->name, "DEC VSXXX-AB digitizer",
160  sizeof(mouse->name));
161  break;
162 
163  default:
164  snprintf(mouse->name, sizeof(mouse->name),
165  "unknown DEC pointer device (type = 0x%02x)",
166  mouse->type);
167  break;
168  }
169 
171  "Found %s version 0x%02x from country 0x%02x on port %s\n",
172  mouse->name, mouse->version, mouse->country, mouse->phys);
173 }
174 
175 /*
176  * Returns number of bytes to be dropped, 0 if packet is okay.
177  */
178 static int 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  for (i = 1; i < packet_len; i++) {
190  if (IS_HDR_BYTE(mouse->buf[i])) {
192  "Need to drop %d bytes of a broken packet.\n",
193  i - 1);
194  DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
195  packet_len, i, mouse->buf[i]);
196  return i - 1;
197  }
198  }
199 
200  return 0;
201 }
202 
203 static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse,
204  unsigned char type, size_t len)
205 {
206  return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type);
207 }
208 
209 static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse)
210 {
211  struct input_dev *dev = mouse->dev;
212  unsigned char *buf = mouse->buf;
213  int left, middle, right;
214  int dx, dy;
215 
216  /*
217  * Check for normal stream packets. This is three bytes,
218  * with the first byte's 3 MSB set to 100.
219  *
220  * [0]: 1 0 0 SignX SignY Left Middle Right
221  * [1]: 0 dx dx dx dx dx dx dx
222  * [2]: 0 dy dy dy dy dy dy dy
223  */
224 
225  /*
226  * Low 7 bit of byte 1 are abs(dx), bit 7 is
227  * 0, bit 4 of byte 0 is direction.
228  */
229  dx = buf[1] & 0x7f;
230  dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1;
231 
232  /*
233  * Low 7 bit of byte 2 are abs(dy), bit 7 is
234  * 0, bit 3 of byte 0 is direction.
235  */
236  dy = buf[2] & 0x7f;
237  dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1;
238 
239  /*
240  * Get button state. It's the low three bits
241  * (for three buttons) of byte 0.
242  */
243  left = buf[0] & 0x04;
244  middle = buf[0] & 0x02;
245  right = buf[0] & 0x01;
246 
247  vsxxxaa_drop_bytes(mouse, 3);
248 
249  DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
250  mouse->name, mouse->phys, dx, dy,
251  left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r");
252 
253  /*
254  * Report what we've found so far...
255  */
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);
262  input_sync(dev);
263 }
264 
265 static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse)
266 {
267  struct input_dev *dev = mouse->dev;
268  unsigned char *buf = mouse->buf;
269  int left, middle, right, touch;
270  int x, y;
271 
272  /*
273  * Tablet position / button packet
274  *
275  * [0]: 1 1 0 B4 B3 B2 B1 Pr
276  * [1]: 0 0 X5 X4 X3 X2 X1 X0
277  * [2]: 0 0 X11 X10 X9 X8 X7 X6
278  * [3]: 0 0 Y5 Y4 Y3 Y2 Y1 Y0
279  * [4]: 0 0 Y11 Y10 Y9 Y8 Y7 Y6
280  */
281 
282  /*
283  * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
284  * counts down->top while monitor counts top->bottom.
285  */
286  x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
287  y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
288  y = 1023 - y;
289 
290  /*
291  * Get button state. It's bits <4..1> of byte 0.
292  */
293  left = buf[0] & 0x02;
294  middle = buf[0] & 0x04;
295  right = buf[0] & 0x08;
296  touch = buf[0] & 0x10;
297 
298  vsxxxaa_drop_bytes(mouse, 5);
299 
300  DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
301  mouse->name, mouse->phys, x, y,
302  left ? "L" : "l", middle ? "M" : "m",
303  right ? "R" : "r", touch ? "T" : "t");
304 
305  /*
306  * Report what we've found so far...
307  */
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);
314  input_sync(dev);
315 }
316 
317 static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse)
318 {
319  struct input_dev *dev = mouse->dev;
320  unsigned char *buf = mouse->buf;
321  int left, middle, right;
322  unsigned char error;
323 
324  /*
325  * Check for Power-On-Reset packets. These are sent out
326  * after plugging the mouse in, or when explicitly
327  * requested by sending 'T'.
328  *
329  * [0]: 1 0 1 0 R3 R2 R1 R0
330  * [1]: 0 M2 M1 M0 D3 D2 D1 D0
331  * [2]: 0 E6 E5 E4 E3 E2 E1 E0
332  * [3]: 0 0 0 0 0 Left Middle Right
333  *
334  * M: manufacturer location code
335  * R: revision code
336  * E: Error code. If it's in the range of 0x00..0x1f, only some
337  * minor problem occurred. Errors >= 0x20 are considered bad
338  * and the device may not work properly...
339  * D: <0010> == mouse, <0100> == tablet
340  */
341 
342  mouse->version = buf[0] & 0x0f;
343  mouse->country = (buf[1] >> 4) & 0x07;
344  mouse->type = buf[1] & 0x0f;
345  error = buf[2] & 0x7f;
346 
347  /*
348  * Get button state. It's the low three bits
349  * (for three buttons) of byte 0. Maybe even the bit <3>
350  * has some meaning if a tablet is attached.
351  */
352  left = buf[0] & 0x04;
353  middle = buf[0] & 0x02;
354  right = buf[0] & 0x01;
355 
356  vsxxxaa_drop_bytes(mouse, 4);
357  vsxxxaa_detection_done(mouse);
358 
359  if (error <= 0x1f) {
360  /* No (serious) error. Report buttons */
361  input_report_key(dev, BTN_LEFT, left);
362  input_report_key(dev, BTN_MIDDLE, middle);
363  input_report_key(dev, BTN_RIGHT, right);
364  input_report_key(dev, BTN_TOUCH, 0);
365  input_sync(dev);
366 
367  if (error != 0)
368  printk(KERN_INFO "Your %s on %s reports error=0x%02x\n",
369  mouse->name, mouse->phys, error);
370 
371  }
372 
373  /*
374  * If the mouse was hot-plugged, we need to force differential mode
375  * now... However, give it a second to recover from it's reset.
376  */
378  "%s on %s: Forcing standard packet format, "
379  "incremental streaming mode and 72 samples/sec\n",
380  mouse->name, mouse->phys);
381  serio_write(mouse->serio, 'S'); /* Standard format */
382  mdelay(50);
383  serio_write(mouse->serio, 'R'); /* Incremental */
384  mdelay(50);
385  serio_write(mouse->serio, 'L'); /* 72 samples/sec */
386 }
387 
388 static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse)
389 {
390  unsigned char *buf = mouse->buf;
391  int stray_bytes;
392 
393  /*
394  * Parse buffer to death...
395  */
396  do {
397  /*
398  * Out of sync? Throw away what we don't understand. Each
399  * packet starts with a byte whose bit 7 is set. Unhandled
400  * packets (ie. which we don't know about or simply b0rk3d
401  * data...) will get shifted out of the buffer after some
402  * activity on the mouse.
403  */
404  while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
405  printk(KERN_ERR "%s on %s: Dropping a byte to regain "
406  "sync with mouse data stream...\n",
407  mouse->name, mouse->phys);
408  vsxxxaa_drop_bytes(mouse, 1);
409  }
410 
411  /*
412  * Check for packets we know about.
413  */
414 
415  if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) {
416  /* Check for broken packet */
417  stray_bytes = vsxxxaa_check_packet(mouse, 3);
418  if (!stray_bytes)
419  vsxxxaa_handle_REL_packet(mouse);
420 
421  } else if (vsxxxaa_smells_like_packet(mouse,
422  VSXXXAA_PACKET_ABS, 5)) {
423  /* Check for broken packet */
424  stray_bytes = vsxxxaa_check_packet(mouse, 5);
425  if (!stray_bytes)
426  vsxxxaa_handle_ABS_packet(mouse);
427 
428  } else if (vsxxxaa_smells_like_packet(mouse,
429  VSXXXAA_PACKET_POR, 4)) {
430  /* Check for broken packet */
431  stray_bytes = vsxxxaa_check_packet(mouse, 4);
432  if (!stray_bytes)
433  vsxxxaa_handle_POR_packet(mouse);
434 
435  } else {
436  break; /* No REL, ABS or POR packet found */
437  }
438 
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  }
444 
445  } while (1);
446 }
447 
448 static irqreturn_t vsxxxaa_interrupt(struct serio *serio,
449  unsigned char data, unsigned int flags)
450 {
451  struct vsxxxaa *mouse = serio_get_drvdata(serio);
452 
453  vsxxxaa_queue_byte(mouse, data);
454  vsxxxaa_parse_buffer(mouse);
455 
456  return IRQ_HANDLED;
457 }
458 
459 static void vsxxxaa_disconnect(struct serio *serio)
460 {
461  struct vsxxxaa *mouse = serio_get_drvdata(serio);
462 
463  serio_close(serio);
464  serio_set_drvdata(serio, NULL);
465  input_unregister_device(mouse->dev);
466  kfree(mouse);
467 }
468 
469 static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv)
470 {
471  struct vsxxxaa *mouse;
472  struct input_dev *input_dev;
473  int err = -ENOMEM;
474 
475  mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL);
476  input_dev = input_allocate_device();
477  if (!mouse || !input_dev)
478  goto fail1;
479 
480  mouse->dev = input_dev;
481  mouse->serio = serio;
482  strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
483  sizeof(mouse->name));
484  snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys);
485 
486  input_dev->name = mouse->name;
487  input_dev->phys = mouse->phys;
488  input_dev->id.bustype = BUS_RS232;
489  input_dev->dev.parent = &serio->dev;
490 
491  __set_bit(EV_KEY, input_dev->evbit); /* We have buttons */
492  __set_bit(EV_REL, input_dev->evbit);
493  __set_bit(EV_ABS, input_dev->evbit);
494  __set_bit(BTN_LEFT, input_dev->keybit); /* We have 3 buttons */
495  __set_bit(BTN_MIDDLE, input_dev->keybit);
496  __set_bit(BTN_RIGHT, input_dev->keybit);
497  __set_bit(BTN_TOUCH, input_dev->keybit); /* ...and Tablet */
498  __set_bit(REL_X, input_dev->relbit);
499  __set_bit(REL_Y, input_dev->relbit);
500  input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
501  input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
502 
503  serio_set_drvdata(serio, mouse);
504 
505  err = serio_open(serio, drv);
506  if (err)
507  goto fail2;
508 
509  /*
510  * Request selftest. Standard packet format and differential
511  * mode will be requested after the device ID'ed successfully.
512  */
513  serio_write(serio, 'T'); /* Test */
514 
515  err = input_register_device(input_dev);
516  if (err)
517  goto fail3;
518 
519  return 0;
520 
521  fail3: serio_close(serio);
522  fail2: serio_set_drvdata(serio, NULL);
523  fail1: input_free_device(input_dev);
524  kfree(mouse);
525  return err;
526 }
527 
528 static struct serio_device_id vsxxaa_serio_ids[] = {
529  {
530  .type = SERIO_RS232,
531  .proto = SERIO_VSXXXAA,
532  .id = SERIO_ANY,
533  .extra = SERIO_ANY,
534  },
535  { 0 }
536 };
537 
538 MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
539 
540 static struct serio_driver vsxxxaa_drv = {
541  .driver = {
542  .name = "vsxxxaa",
543  },
544  .description = DRIVER_DESC,
545  .id_table = vsxxaa_serio_ids,
546  .connect = vsxxxaa_connect,
547  .interrupt = vsxxxaa_interrupt,
548  .disconnect = vsxxxaa_disconnect,
549 };
550 
551 module_serio_driver(vsxxxaa_drv);