1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
89MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
90MODULE_DESCRIPTION (DRIVER_DESC);
91MODULE_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) (((x) & VSXXXAA_INTRO_MASK) \
103 == 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) (((data) & VSXXXAA_PACKET_MASK) == (type))
110
111
112
113struct vsxxxaa {
114 struct input_dev *dev;
115 struct serio *serio;
116#define BUFLEN 15
117 unsigned char buf[BUFLEN];
118 unsigned char count;
119 unsigned char version;
120 unsigned char country;
121 unsigned char type;
122 char name[64];
123 char phys[32];
124};
125
126static void
127vsxxxaa_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
137static void
138vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
139{
140 if (mouse->count == BUFLEN) {
141 printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
142 mouse->name, mouse->phys);
143 vsxxxaa_drop_bytes (mouse, 1);
144 }
145 DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
146
147 mouse->buf[mouse->count++] = byte;
148}
149
150static void
151vsxxxaa_detection_done (struct vsxxxaa *mouse)
152{
153 switch (mouse->type) {
154 case 0x02:
155 strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse",
156 sizeof (mouse->name));
157 break;
158
159 case 0x04:
160 strlcpy (mouse->name, "DEC VSXXX-AB digitizer",
161 sizeof (mouse->name));
162 break;
163
164 default:
165 snprintf (mouse->name, sizeof (mouse->name),
166 "unknown DEC pointer device (type = 0x%02x)",
167 mouse->type);
168 break;
169 }
170
171 printk (KERN_INFO
172 "Found %s version 0x%02x from country 0x%02x on port %s\n",
173 mouse->name, mouse->version, mouse->country, mouse->phys);
174}
175
176
177
178
179static int
180vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
181{
182 int i;
183
184
185 if (!IS_HDR_BYTE (mouse->buf[0])) {
186 DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
187 return 1;
188 }
189
190
191 if (packet_len > 1) {
192 for (i = 1; i < packet_len; i++) {
193 if (IS_HDR_BYTE (mouse->buf[i])) {
194 printk (KERN_ERR "Need to drop %d bytes "
195 "of a broken packet.\n",
196 i - 1);
197 DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
198 packet_len, i, mouse->buf[i]);
199 return i - 1;
200 }
201 }
202 }
203
204 return 0;
205}
206
207static __inline__ int
208vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
209{
210 return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
211}
212
213static void
214vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse)
215{
216 struct input_dev *dev = mouse->dev;
217 unsigned char *buf = mouse->buf;
218 int left, middle, right;
219 int dx, dy;
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 dx = buf[1] & 0x7f;
235 dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
236
237
238
239
240
241 dy = buf[2] & 0x7f;
242 dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
243
244
245
246
247
248 left = (buf[0] & 0x04)? 1: 0;
249 middle = (buf[0] & 0x02)? 1: 0;
250 right = (buf[0] & 0x01)? 1: 0;
251
252 vsxxxaa_drop_bytes (mouse, 3);
253
254 DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
255 mouse->name, mouse->phys, dx, dy,
256 left? "L": "l", middle? "M": "m", right? "R": "r");
257
258
259
260
261 input_report_key (dev, BTN_LEFT, left);
262 input_report_key (dev, BTN_MIDDLE, middle);
263 input_report_key (dev, BTN_RIGHT, right);
264 input_report_key (dev, BTN_TOUCH, 0);
265 input_report_rel (dev, REL_X, dx);
266 input_report_rel (dev, REL_Y, dy);
267 input_sync (dev);
268}
269
270static void
271vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse)
272{
273 struct input_dev *dev = mouse->dev;
274 unsigned char *buf = mouse->buf;
275 int left, middle, right, touch;
276 int x, y;
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
293 y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
294 y = 1023 - y;
295
296
297
298
299 left = (buf[0] & 0x02)? 1: 0;
300 middle = (buf[0] & 0x04)? 1: 0;
301 right = (buf[0] & 0x08)? 1: 0;
302 touch = (buf[0] & 0x10)? 1: 0;
303
304 vsxxxaa_drop_bytes (mouse, 5);
305
306 DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
307 mouse->name, mouse->phys, x, y,
308 left? "L": "l", middle? "M": "m",
309 right? "R": "r", touch? "T": "t");
310
311
312
313
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
323static void
324vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
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
333
334
335
336
337
338
339
340
341
342
343
344
345
346
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
356
357
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
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);
372 input_sync (dev);
373
374 if (error != 0)
375 printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
376 mouse->name, mouse->phys, error);
377
378 }
379
380
381
382
383
384 printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
385 "incremental streaming mode and 72 samples/sec\n",
386 mouse->name, mouse->phys);
387 serio_write (mouse->serio, 'S');
388 mdelay (50);
389 serio_write (mouse->serio, 'R');
390 mdelay (50);
391 serio_write (mouse->serio, 'L');
392}
393
394static void
395vsxxxaa_parse_buffer (struct vsxxxaa *mouse)
396{
397 unsigned char *buf = mouse->buf;
398 int stray_bytes;
399
400
401
402
403 do {
404
405
406
407
408
409
410
411 while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
412 printk (KERN_ERR "%s on %s: Dropping a byte to regain "
413 "sync with mouse data stream...\n",
414 mouse->name, mouse->phys);
415 vsxxxaa_drop_bytes (mouse, 1);
416 }
417
418
419
420
421
422 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
423
424 stray_bytes = vsxxxaa_check_packet (mouse, 3);
425 if (stray_bytes > 0) {
426 printk (KERN_ERR "Dropping %d bytes now...\n",
427 stray_bytes);
428 vsxxxaa_drop_bytes (mouse, stray_bytes);
429 continue;
430 }
431
432 vsxxxaa_handle_REL_packet (mouse);
433 continue;
434 }
435
436 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
437
438 stray_bytes = vsxxxaa_check_packet (mouse, 5);
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 continue;
444 }
445
446 vsxxxaa_handle_ABS_packet (mouse);
447 continue;
448 }
449
450 if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
451
452 stray_bytes = vsxxxaa_check_packet (mouse, 4);
453 if (stray_bytes > 0) {
454 printk (KERN_ERR "Dropping %d bytes now...\n",
455 stray_bytes);
456 vsxxxaa_drop_bytes (mouse, stray_bytes);
457 continue;
458 }
459
460 vsxxxaa_handle_POR_packet (mouse);
461 continue;
462 }
463
464 break;
465 } while (1);
466}
467
468static irqreturn_t
469vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
470{
471 struct vsxxxaa *mouse = serio_get_drvdata (serio);
472
473 vsxxxaa_queue_byte (mouse, data);
474 vsxxxaa_parse_buffer (mouse);
475
476 return IRQ_HANDLED;
477}
478
479static void
480vsxxxaa_disconnect (struct serio *serio)
481{
482 struct vsxxxaa *mouse = serio_get_drvdata (serio);
483
484 serio_close (serio);
485 serio_set_drvdata (serio, NULL);
486 input_unregister_device (mouse->dev);
487 kfree (mouse);
488}
489
490static int
491vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
492{
493 struct vsxxxaa *mouse;
494 struct input_dev *input_dev;
495 int err = -ENOMEM;
496
497 mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
498 input_dev = input_allocate_device ();
499 if (!mouse || !input_dev)
500 goto fail1;
501
502 mouse->dev = input_dev;
503 mouse->serio = serio;
504 strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
505 sizeof (mouse->name));
506 snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys);
507
508 input_dev->name = mouse->name;
509 input_dev->phys = mouse->phys;
510 input_dev->id.bustype = BUS_RS232;
511 input_dev->dev.parent = &serio->dev;
512
513 set_bit (EV_KEY, input_dev->evbit);
514 set_bit (EV_REL, input_dev->evbit);
515 set_bit (EV_ABS, input_dev->evbit);
516 set_bit (BTN_LEFT, input_dev->keybit);
517 set_bit (BTN_MIDDLE, input_dev->keybit);
518 set_bit (BTN_RIGHT, input_dev->keybit);
519 set_bit (BTN_TOUCH, input_dev->keybit);
520 set_bit (REL_X, input_dev->relbit);
521 set_bit (REL_Y, input_dev->relbit);
522 input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
523 input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
524
525 serio_set_drvdata (serio, mouse);
526
527 err = serio_open (serio, drv);
528 if (err)
529 goto fail2;
530
531
532
533
534
535 serio_write (serio, 'T');
536
537 err = input_register_device (input_dev);
538 if (err)
539 goto fail3;
540
541 return 0;
542
543 fail3: serio_close (serio);
544 fail2: serio_set_drvdata (serio, NULL);
545 fail1: input_free_device (input_dev);
546 kfree (mouse);
547 return err;
548}
549
550static struct serio_device_id vsxxaa_serio_ids[] = {
551 {
552 .type = SERIO_RS232,
553 .proto = SERIO_VSXXXAA,
554 .id = SERIO_ANY,
555 .extra = SERIO_ANY,
556 },
557 { 0 }
558};
559
560MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);
561
562static struct serio_driver vsxxxaa_drv = {
563 .driver = {
564 .name = "vsxxxaa",
565 },
566 .description = DRIVER_DESC,
567 .id_table = vsxxaa_serio_ids,
568 .connect = vsxxxaa_connect,
569 .interrupt = vsxxxaa_interrupt,
570 .disconnect = vsxxxaa_disconnect,
571};
572
573static int __init
574vsxxxaa_init (void)
575{
576 return serio_register_driver(&vsxxxaa_drv);
577}
578
579static void __exit
580vsxxxaa_exit (void)
581{
582 serio_unregister_driver(&vsxxxaa_drv);
583}
584
585module_init (vsxxxaa_init);
586module_exit (vsxxxaa_exit);
587
588