|
@@ -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;
|