|
@@ -294,7 +294,29 @@ static int synaptics_pt_write(struct serio *serio, unsigned char c)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static inline int synaptics_is_pt_packet(unsigned char *buf)
|
|
|
+static int synaptics_pt_start(struct serio *serio)
|
|
|
+{
|
|
|
+ struct psmouse *parent = serio_get_drvdata(serio->parent);
|
|
|
+ struct synaptics_data *priv = parent->private;
|
|
|
+
|
|
|
+ serio_pause_rx(parent->ps2dev.serio);
|
|
|
+ priv->pt_port = serio;
|
|
|
+ serio_continue_rx(parent->ps2dev.serio);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void synaptics_pt_stop(struct serio *serio)
|
|
|
+{
|
|
|
+ struct psmouse *parent = serio_get_drvdata(serio->parent);
|
|
|
+ struct synaptics_data *priv = parent->private;
|
|
|
+
|
|
|
+ serio_pause_rx(parent->ps2dev.serio);
|
|
|
+ priv->pt_port = NULL;
|
|
|
+ serio_continue_rx(parent->ps2dev.serio);
|
|
|
+}
|
|
|
+
|
|
|
+static int synaptics_is_pt_packet(unsigned char *buf)
|
|
|
{
|
|
|
return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
|
|
|
}
|
|
@@ -315,9 +337,8 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet
|
|
|
|
|
|
static void synaptics_pt_activate(struct psmouse *psmouse)
|
|
|
{
|
|
|
- struct serio *ptport = psmouse->ps2dev.serio->child;
|
|
|
- struct psmouse *child = serio_get_drvdata(ptport);
|
|
|
struct synaptics_data *priv = psmouse->private;
|
|
|
+ struct psmouse *child = serio_get_drvdata(priv->pt_port);
|
|
|
|
|
|
/* adjust the touchpad to child's choice of protocol */
|
|
|
if (child) {
|
|
@@ -345,6 +366,8 @@ static void synaptics_pt_create(struct psmouse *psmouse)
|
|
|
strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
|
|
|
strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
|
|
|
serio->write = synaptics_pt_write;
|
|
|
+ serio->start = synaptics_pt_start;
|
|
|
+ serio->stop = synaptics_pt_stop;
|
|
|
serio->parent = psmouse->ps2dev.serio;
|
|
|
|
|
|
psmouse->pt_activate = synaptics_pt_activate;
|
|
@@ -578,9 +601,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
|
|
|
if (unlikely(priv->pkt_type == SYN_NEWABS))
|
|
|
priv->pkt_type = synaptics_detect_pkt_type(psmouse);
|
|
|
|
|
|
- if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) {
|
|
|
- if (psmouse->ps2dev.serio->child)
|
|
|
- synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet);
|
|
|
+ if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
|
|
|
+ synaptics_is_pt_packet(psmouse->packet)) {
|
|
|
+ if (priv->pt_port)
|
|
|
+ synaptics_pass_pt_packet(priv->pt_port, psmouse->packet);
|
|
|
} else
|
|
|
synaptics_process_packet(psmouse);
|
|
|
|