]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/input/mouse/psmouse-base.c
qed: Fix overriding of supported autoneg value.
[mirror_ubuntu-bionic-kernel.git] / drivers / input / mouse / psmouse-base.c
index bee2674249722fd4117a7d7de95d222749c6b86a..a598b7223cef2fc60f1df135856ac5dd669b86d6 100644 (file)
@@ -127,6 +127,13 @@ struct psmouse_protocol {
        int (*init)(struct psmouse *);
 };
 
+static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
+{
+       input_report_key(dev, BTN_LEFT,   buttons & BIT(0));
+       input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
+       input_report_key(dev, BTN_RIGHT,  buttons & BIT(1));
+}
+
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
  * relevant events to the input module once full packet has arrived.
@@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
        }
 
        /* Generic PS/2 Mouse */
-       input_report_key(dev, BTN_LEFT,    packet[0]       & 1);
-       input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
-       input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);
+       psmouse_report_standard_buttons(dev,
+                                       packet[0] | psmouse->extra_buttons);
 
        input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
        input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
@@ -282,6 +288,30 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
        return 0;
 }
 
+static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
+{
+       switch (psmouse->oob_data_type) {
+       case PSMOUSE_OOB_NONE:
+               psmouse->oob_data_type = data;
+               break;
+
+       case PSMOUSE_OOB_EXTRA_BTNS:
+               psmouse_report_standard_buttons(psmouse->dev, data);
+               input_sync(psmouse->dev);
+
+               psmouse->extra_buttons = data;
+               psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+               break;
+
+       default:
+               psmouse_warn(psmouse,
+                            "unknown OOB_DATA type: 0x%02x\n",
+                            psmouse->oob_data_type);
+               psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+               break;
+       }
+}
+
 /*
  * psmouse_interrupt() handles incoming characters, either passing them
  * for normal processing or gathering them as command response.
@@ -306,6 +336,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                goto out;
        }
 
+       if (flags & SERIO_OOB_DATA) {
+               psmouse_handle_oob_data(psmouse, data);
+               goto out;
+       }
+
        if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
                if  (ps2_handle_ack(&psmouse->ps2dev, data))
                        goto out;