]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/input/mouse/psmouse-base.c
sdhci: make workaround for timeout bug more general
[linux-2.6-omap-h63xx.git] / drivers / input / mouse / psmouse-base.c
index f15f695777f8ff6b0c352a948a9a1bc0fe942a2f..f5a6be1d3c46325b2173ff00e2588a9de9ca5d81 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
@@ -177,6 +176,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
                packet[1] |= (packet[0] & 0x40) << 1;
        }
 
+/*
+ * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first
+ * byte.
+ */
+       if (psmouse->type == PSMOUSE_CORTRON) {
+               input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
+               packet[0] |= 0x08;
+       }
+
 /*
  * Generic PS/2 Mouse
  */
@@ -539,6 +547,20 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
        return 0;
 }
 
+/*
+ * Cortron PS/2 protocol detection. There's no special way to detect it, so it
+ * must be forced by sysfs protocol writing.
+ */
+static int cortron_detect(struct psmouse *psmouse, int set_properties)
+{
+       if (set_properties) {
+               psmouse->vendor = "Cortron";
+               psmouse->name = "PS/2 Trackball";
+               set_bit(BTN_SIDE, psmouse->dev->keybit);
+       }
+
+       return 0;
+}
 
 /*
  * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
@@ -625,9 +647,10 @@ static int psmouse_extensions(struct psmouse *psmouse,
 
 /*
  * Reset to defaults in case the device got confused by extended
- * protocol probes. Note that we do full reset becuase some mice
- * put themselves to sleep when see PSMOUSE_RESET_DIS.
+ * protocol probes. Note that we follow up with full reset because
+ * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
  */
+       ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
        psmouse_reset(psmouse);
 
        if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
@@ -739,6 +762,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .detect         = touchkit_ps2_detect,
        },
 #endif
+       {
+               .type           = PSMOUSE_CORTRON,
+               .name           = "CortronPS/2",
+               .alias          = "cortps",
+               .detect         = cortron_detect,
+       },
        {
                .type           = PSMOUSE_AUTO,
                .name           = "auto",
@@ -876,7 +905,7 @@ static void psmouse_activate(struct psmouse *psmouse)
 
 /*
  * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion
- * reports from it unless we explicitely request it.
+ * reports from it unless we explicitly request it.
  */
 
 static void psmouse_deactivate(struct psmouse *psmouse)
@@ -1085,9 +1114,10 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
 
        input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        psmouse->set_rate = psmouse_set_rate;
        psmouse->set_resolution = psmouse_set_resolution;
@@ -1216,6 +1246,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
  err_pt_deactivate:
        if (parent && parent->pt_deactivate)
                parent->pt_deactivate(parent);
+       input_unregister_device(psmouse->dev);
+       input_dev = NULL; /* so we don't try to free it below */
  err_protocol_disconnect:
        if (psmouse->disconnect)
                psmouse->disconnect(psmouse);