diff options
Diffstat (limited to 'drivers/input/mouse/synaptics.c')
-rw-r--r-- | drivers/input/mouse/synaptics.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 026df6010161..ebd7a99efeae 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -137,7 +137,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
137 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) | 137 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) |
138 | return -1; | 138 | return -1; |
139 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 139 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
140 | priv->ext_cap = 0; | 140 | priv->ext_cap = priv->ext_cap_0c = 0; |
141 | |||
141 | if (!SYN_CAP_VALID(priv->capabilities)) | 142 | if (!SYN_CAP_VALID(priv->capabilities)) |
142 | return -1; | 143 | return -1; |
143 | 144 | ||
@@ -150,7 +151,7 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
150 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 151 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
151 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 152 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
152 | printk(KERN_ERR "Synaptics claims to have extended capabilities," | 153 | printk(KERN_ERR "Synaptics claims to have extended capabilities," |
153 | " but I'm not able to read them."); | 154 | " but I'm not able to read them.\n"); |
154 | } else { | 155 | } else { |
155 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 156 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
156 | 157 | ||
@@ -162,6 +163,16 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
162 | priv->ext_cap &= 0xff0fff; | 163 | priv->ext_cap &= 0xff0fff; |
163 | } | 164 | } |
164 | } | 165 | } |
166 | |||
167 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | ||
168 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | ||
169 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," | ||
170 | " but I'm not able to read it.\n"); | ||
171 | } else { | ||
172 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | ||
173 | } | ||
174 | } | ||
175 | |||
165 | return 0; | 176 | return 0; |
166 | } | 177 | } |
167 | 178 | ||
@@ -348,7 +359,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
348 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 359 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
349 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 360 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
350 | 361 | ||
351 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 362 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
363 | /* | ||
364 | * Clickpad's button is transmitted as middle button, | ||
365 | * however, since it is primary button, we will report | ||
366 | * it as BTN_LEFT. | ||
367 | */ | ||
368 | hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | ||
369 | |||
370 | } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | ||
352 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | 371 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; |
353 | if (hw->w == 2) | 372 | if (hw->w == 2) |
354 | hw->scroll = (signed char)(buf[1]); | 373 | hw->scroll = (signed char)(buf[1]); |
@@ -593,6 +612,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
593 | 612 | ||
594 | dev->absres[ABS_X] = priv->x_res; | 613 | dev->absres[ABS_X] = priv->x_res; |
595 | dev->absres[ABS_Y] = priv->y_res; | 614 | dev->absres[ABS_Y] = priv->y_res; |
615 | |||
616 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
617 | /* Clickpads report only left button */ | ||
618 | __clear_bit(BTN_RIGHT, dev->keybit); | ||
619 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
620 | } | ||
596 | } | 621 | } |
597 | 622 | ||
598 | static void synaptics_disconnect(struct psmouse *psmouse) | 623 | static void synaptics_disconnect(struct psmouse *psmouse) |
@@ -697,10 +722,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
697 | 722 | ||
698 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 723 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
699 | 724 | ||
700 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", | 725 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
701 | SYN_ID_MODEL(priv->identity), | 726 | SYN_ID_MODEL(priv->identity), |
702 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 727 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
703 | priv->model_id, priv->capabilities, priv->ext_cap); | 728 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); |
704 | 729 | ||
705 | set_input_params(psmouse->dev, priv); | 730 | set_input_params(psmouse->dev, priv); |
706 | 731 | ||