]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] New set of input patches
authorJan-Benedict Glaw <jbglaw@lug-owl.de>
Wed, 21 Apr 2004 09:22:53 +0000 (02:22 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 21 Apr 2004 09:22:53 +0000 (02:22 -0700)
This  updates the vsxxx driver to it's current version.

Even DEC tablet support (VSXXX-AB) is now tested - it works:)
You can even hotplug between mouse and digitizer...

drivers/input/mouse/Kconfig
drivers/input/mouse/vsxxxaa.c

index 13086cec9f4940babaf038b2e02325265a070e83..17db090dc6f6e0eefa18b8de2a81fc2bac8954a8 100644 (file)
@@ -119,7 +119,7 @@ config MOUSE_RISCPC
          module will be called rpcmouse.
 
 config MOUSE_VSXXXAA
-       tristate "DEC VSXXX-AA/GA mouse and tablet"
+       tristate "DEC VSXXX-AA/GA mouse and VSXXX-AB tablet"
        depends on INPUT && INPUT_MOUSE
        select SERIO
        help
index bcc0d3ae219f7429bd56a9e27d9d49bb82300c63..c26d907e8bb93b4a290dbd48b184d09b773dbae3 100644 (file)
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or 
+ * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  *     DEC socket      DB9     DB25    Note
  *     1 (GND)         5       7       -
- *     2 (RxD)         3       3       -
- *     3 (TxD)         2       2       -
+ *     2 (RxD)         2       3       -
+ *     3 (TxD)         3       2       -
  *     4 (-12V)        -       -       Somewhere from the PSU. At ATX, it's
- *                                     the blue wire at pin 12 of the ATX
- *                                     power connector. Please note that the
- *                                     docs say this should be +12V! However,
- *                                     I measured -12V...
- *     5 (+5V)         -       -       PSU (red wire of ATX power connector
+ *                                     the thin blue wire at pin 12 of the
+ *                                     ATX power connector. Only required for
+ *                                     VSXXX-AA/-GA mice.
+ *     5 (+5V)         -       -       PSU (red wires of ATX power connector
  *                                     on pin 4, 6, 19 or 20) or HDD power
- *                                     connector (also red wire)
- *     6 (not conn.)   -       -       -
+ *                                     connector (also red wire).
+ *     6 (+12V)        -       -       HDD power connector, yellow wire. Only
+ *                                     required for VSXXX-AB digitizer.
  *     7 (dev. avail.) -       -       The mouse shorts this one to pin 1.
  *                                     This way, the host computer can detect
  *                                     the mouse. To use it with the adaptor,
  *                                     simply don't connect this pin.
  *
  * So to get a working adaptor, you need to connect the mouse with three
- * wires to a RS232 port and two additional wires for +5V and -12V to the
- * PSU.
+ * wires to a RS232 port and two or three additional wires for +5V, +12V and
+ * -12V to the PSU.
  *
  * Flow specification for the link is 4800, 8o1.
- */
-
-/*
- * TODO list:
- * - Automatically attach to a given serial port (no need for inputattach).
+ *
+ * The mice and tablet are described in "VCB02 Video Subsystem - Technical
+ * Manual", DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
+ * specific for DEC documentation. Try
+ * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
  */
 
 #include <linux/delay.h>
@@ -115,6 +115,7 @@ struct vsxxxaa {
        unsigned char version;
        unsigned char country;
        unsigned char type;
+       char name[64];
        char phys[32];
 };
 
@@ -134,27 +135,34 @@ vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
 {
        if (mouse->count == BUFLEN) {
                printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
-                               mouse->dev.name, mouse->dev.phys);
+                               mouse->name, mouse->phys);
                vsxxxaa_drop_bytes (mouse, 1);
        }
+       DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
 
        mouse->buf[mouse->count++] = byte;
 }
 
 static void
-vsxxxaa_report_mouse (struct vsxxxaa *mouse)
+vsxxxaa_detection_done (struct vsxxxaa *mouse)
 {
-       char *devtype;
-
        switch (mouse->type) {
-               case 0x02:      devtype = "DEC mouse"; break;
-               case 0x04:      devtype = "DEC tablet"; break;
-               default:        devtype = "unknown DEC device"; break;
+               case 0x02:
+                       sprintf (mouse->name, "DEC VSXXX-AA/GA mouse");
+                       break;
+
+               case 0x04:
+                       sprintf (mouse->name, "DEC VSXXX-AB digitizer");
+                       break;
+
+               default:
+                       sprintf (mouse->name, "unknown DEC pointer device");
+                       break;
        }
 
-       printk (KERN_INFO "Found %s version 0x%x from country 0x%x "
-                       "on port %s\n", devtype, mouse->version,
-                       mouse->country, mouse->dev.phys);
+       printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x "
+                       "on port %s\n", mouse->name, mouse->version,
+                       mouse->country, mouse->phys);
 }
 
 /*
@@ -216,7 +224,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
         * 0, bit 4 of byte 0 is direction.
         */
        dx = buf[1] & 0x7f;
-       dx *= ((buf[0] >> 4) & 0x01)? -1: 1;
+       dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
 
        /*
         * Low 7 bit of byte 2 are abs(dy), bit 7 is
@@ -236,7 +244,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        vsxxxaa_drop_bytes (mouse, 3);
 
        DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
-                       mouse->dev.name, mouse->dev.phys, dx, dy,
+                       mouse->name, mouse->phys, dx, dy,
                        left? "L": "l", middle? "M": "m", right? "R": "r");
 
        /*
@@ -246,6 +254,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        input_report_key (dev, BTN_LEFT, left);
        input_report_key (dev, BTN_MIDDLE, middle);
        input_report_key (dev, BTN_RIGHT, right);
+       input_report_key (dev, BTN_TOUCH, 0);
        input_report_rel (dev, REL_X, dx);
        input_report_rel (dev, REL_Y, dy);
        input_sync (dev);
@@ -256,7 +265,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 {
        struct input_dev *dev = &mouse->dev;
        unsigned char *buf = mouse->buf;
-       int left, middle, right, extra;
+       int left, middle, right, touch;
        int x, y;
 
        /*
@@ -270,10 +279,12 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
         */
 
        /*
-        * Get X/Y position
+        * Get X/Y position. Y axis needs to be inverted since VSXXX-AB
+        * counts down->top while monitor counts top->bottom.
         */
        x = ((buf[2] & 0x3f) << 6) | (buf[1] & 0x3f);
        y = ((buf[4] & 0x3f) << 6) | (buf[3] & 0x3f);
+       y = 1023 - y;
 
        /*
         * Get button state. It's bits <4..1> of byte 0.
@@ -281,14 +292,14 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        left    = (buf[0] & 0x02)? 1: 0;
        middle  = (buf[0] & 0x04)? 1: 0;
        right   = (buf[0] & 0x08)? 1: 0;
-       extra   = (buf[0] & 0x10)? 1: 0;
+       touch   = (buf[0] & 0x10)? 1: 0;
 
        vsxxxaa_drop_bytes (mouse, 5);
 
        DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
-                       mouse->dev.name, mouse->dev.phys, x, y,
+                       mouse->name, mouse->phys, x, y,
                        left? "L": "l", middle? "M": "m",
-                       right? "R": "r", extra? "E": "e");
+                       right? "R": "r", touch? "T": "t");
 
        /*
         * Report what we've found so far...
@@ -297,7 +308,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        input_report_key (dev, BTN_LEFT, left);
        input_report_key (dev, BTN_MIDDLE, middle);
        input_report_key (dev, BTN_RIGHT, right);
-       input_report_key (dev, BTN_EXTRA, extra);
+       input_report_key (dev, BTN_TOUCH, touch);
        input_report_abs (dev, ABS_X, x);
        input_report_abs (dev, ABS_Y, y);
        input_sync (dev);
@@ -334,7 +345,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 
        mouse->version = buf[0] & 0x0f;
        mouse->country = (buf[1] >> 4) & 0x07;
-       mouse->type = buf[1] & 0x07;
+       mouse->type = buf[1] & 0x0f;
        error = buf[2] & 0x7f;
 
        /*
@@ -347,7 +358,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        right   = (buf[0] & 0x01)? 1: 0;
 
        vsxxxaa_drop_bytes (mouse, 4);
-       vsxxxaa_report_mouse (mouse);
+       vsxxxaa_detection_done (mouse);
 
        if (error <= 0x1f) {
                /* No error. Report buttons */
@@ -355,20 +366,22 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
                input_report_key (dev, BTN_LEFT, left);
                input_report_key (dev, BTN_MIDDLE, middle);
                input_report_key (dev, BTN_RIGHT, right);
+               input_report_key (dev, BTN_TOUCH, 0);
                input_sync (dev);
        } else {
                printk (KERN_ERR "Your %s on %s reports an undefined error, "
-                               "please check it...\n", mouse->dev.name,
-                               mouse->dev.phys);
+                               "please check it...\n", mouse->name,
+                               mouse->phys);
        }
 
        /*
-        * If the mouse was hot-plugged, we need to
-        * force differential mode now...
+        * If the mouse was hot-plugged, we need to force differential mode
+        * now... However, give it a second to recover from it's reset.
         */
        printk (KERN_NOTICE "%s on %s: Forceing standard packet format and "
-                       "streaming mode\n", mouse->dev.name, mouse->dev.phys);
+                       "streaming mode\n", mouse->name, mouse->phys);
        mouse->serio->write (mouse->serio, 'S');
+       mdelay (50);
        mouse->serio->write (mouse->serio, 'R');
 }
 
@@ -392,7 +405,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
                while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
                        printk (KERN_ERR "%s on %s: Dropping a byte to regain "
                                        "sync with mouse data stream...\n",
-                                       mouse->dev.name, mouse->dev.phys);
+                                       mouse->name, mouse->phys);
                        vsxxxaa_drop_bytes (mouse, 1);
                }
 
@@ -475,7 +488,6 @@ vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
 
        if ((serio->type & SERIO_TYPE) != SERIO_RS232)
                return;
-
        if ((serio->type & SERIO_PROTO) != SERIO_VSXXXAA)
                return;
 
@@ -486,14 +498,15 @@ vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
 
        init_input_dev (&mouse->dev);
        set_bit (EV_KEY, mouse->dev.evbit);             /* We have buttons */
-       set_bit (EV_REL, mouse->dev.evbit);             /* We can move */
+       set_bit (EV_REL, mouse->dev.evbit);
+       set_bit (EV_ABS, mouse->dev.evbit);
        set_bit (BTN_LEFT, mouse->dev.keybit);          /* We have 3 buttons */
        set_bit (BTN_MIDDLE, mouse->dev.keybit);
        set_bit (BTN_RIGHT, mouse->dev.keybit);
-       set_bit (BTN_EXTRA, mouse->dev.keybit);         /* ...and Tablet */
-       set_bit (REL_X, mouse->dev.relbit);             /* We can move in */
-       set_bit (REL_Y, mouse->dev.relbit);             /* two dimensions */
-       set_bit (ABS_X, mouse->dev.absbit);             /* DEC tablet support */
+       set_bit (BTN_TOUCH, mouse->dev.keybit);         /* ...and Tablet */
+       set_bit (REL_X, mouse->dev.relbit);
+       set_bit (REL_Y, mouse->dev.relbit);
+       set_bit (ABS_X, mouse->dev.absbit);
        set_bit (ABS_Y, mouse->dev.absbit);
 
        mouse->dev.absmin[ABS_X] = 0;
@@ -504,9 +517,10 @@ vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
        mouse->dev.private = mouse;
        serio->private = mouse;
 
+       sprintf (mouse->name, "DEC VSXXX-AA/GA mouse or VSXXX-AB digitizer");
        sprintf (mouse->phys, "%s/input0", serio->phys);
+       mouse->dev.name = mouse->name;
        mouse->dev.phys = mouse->phys;
-       mouse->dev.name = "DEC VSXXX-AA/GA mouse or DEC tablet";
        mouse->dev.id.bustype = BUS_RS232;
        mouse->serio = serio;
 
@@ -516,20 +530,20 @@ vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
        }
 
        /*
-        * Request selftest and differential stream mode.
+        * Request selftest. Standard packet format and differential
+        * mode will be requested after the device ID'ed successfully.
         */
        mouse->serio->write (mouse->serio, 'T'); /* Test */
-       mouse->serio->write (mouse->serio, 'R'); /* Differential stream */
 
        input_register_device (&mouse->dev);
 
-       printk (KERN_INFO "input: %s on %s\n", mouse->dev.name, serio->phys);
+       printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
 }
 
 static struct serio_dev vsxxxaa_dev = {
-       .interrupt =    vsxxxaa_interrupt,
-       .connect =      vsxxxaa_connect,
-       .disconnect =   vsxxxaa_disconnect
+       .connect = vsxxxaa_connect,
+       .interrupt = vsxxxaa_interrupt,
+       .disconnect = vsxxxaa_disconnect,
 };
 
 int __init