diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
commit | aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (patch) | |
tree | 3f9e98fadd5124fb05e8f6f9b06aa23698d4f215 /drivers/input/mouse/synaptics.c | |
parent | cca8edfd2ec2a34d9f50f593bc753bb11e1bc1f5 (diff) | |
parent | 3c6b50141ef9f0a8844bf1357b80c0cdf518bf05 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/mouse/synaptics.c')
-rw-r--r-- | drivers/input/mouse/synaptics.c | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e06e045bf907..5538fc657af1 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -207,27 +207,37 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
207 | static int synaptics_resolution(struct psmouse *psmouse) | 207 | static int synaptics_resolution(struct psmouse *psmouse) |
208 | { | 208 | { |
209 | struct synaptics_data *priv = psmouse->private; | 209 | struct synaptics_data *priv = psmouse->private; |
210 | unsigned char res[3]; | 210 | unsigned char resp[3]; |
211 | unsigned char max[3]; | ||
212 | 211 | ||
213 | if (SYN_ID_MAJOR(priv->identity) < 4) | 212 | if (SYN_ID_MAJOR(priv->identity) < 4) |
214 | return 0; | 213 | return 0; |
215 | 214 | ||
216 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { | 215 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp) == 0) { |
217 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { | 216 | if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) { |
218 | priv->x_res = res[0]; /* x resolution in units/mm */ | 217 | priv->x_res = resp[0]; /* x resolution in units/mm */ |
219 | priv->y_res = res[2]; /* y resolution in units/mm */ | 218 | priv->y_res = resp[2]; /* y resolution in units/mm */ |
220 | } | 219 | } |
221 | } | 220 | } |
222 | 221 | ||
223 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 222 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
224 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 223 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
225 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { | 224 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
226 | printk(KERN_ERR "Synaptics claims to have dimensions query," | 225 | printk(KERN_ERR "Synaptics claims to have max coordinates" |
227 | " but I'm not able to read it.\n"); | 226 | " query, but I'm not able to read it.\n"); |
227 | } else { | ||
228 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | ||
229 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | ||
234 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | ||
235 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { | ||
236 | printk(KERN_ERR "Synaptics claims to have min coordinates" | ||
237 | " query, but I'm not able to read it.\n"); | ||
228 | } else { | 238 | } else { |
229 | priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); | 239 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
230 | priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); | 240 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
231 | } | 241 | } |
232 | } | 242 | } |
233 | 243 | ||
@@ -406,26 +416,10 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
406 | memset(hw, 0, sizeof(struct synaptics_hw_state)); | 416 | memset(hw, 0, sizeof(struct synaptics_hw_state)); |
407 | 417 | ||
408 | if (SYN_MODEL_NEWABS(priv->model_id)) { | 418 | if (SYN_MODEL_NEWABS(priv->model_id)) { |
409 | hw->x = (((buf[3] & 0x10) << 8) | | ||
410 | ((buf[1] & 0x0f) << 8) | | ||
411 | buf[4]); | ||
412 | hw->y = (((buf[3] & 0x20) << 7) | | ||
413 | ((buf[1] & 0xf0) << 4) | | ||
414 | buf[5]); | ||
415 | |||
416 | hw->z = buf[2]; | ||
417 | hw->w = (((buf[0] & 0x30) >> 2) | | 419 | hw->w = (((buf[0] & 0x30) >> 2) | |
418 | ((buf[0] & 0x04) >> 1) | | 420 | ((buf[0] & 0x04) >> 1) | |
419 | ((buf[3] & 0x04) >> 2)); | 421 | ((buf[3] & 0x04) >> 2)); |
420 | 422 | ||
421 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
422 | /* Gesture packet: (x, y, z) at half resolution */ | ||
423 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
424 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
425 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
426 | return 1; | ||
427 | } | ||
428 | |||
429 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 423 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
430 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 424 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
431 | 425 | ||
@@ -448,6 +442,22 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
448 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 442 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
449 | } | 443 | } |
450 | 444 | ||
445 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
446 | /* Gesture packet: (x, y, z) at half resolution */ | ||
447 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
448 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
449 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
450 | return 1; | ||
451 | } | ||
452 | |||
453 | hw->x = (((buf[3] & 0x10) << 8) | | ||
454 | ((buf[1] & 0x0f) << 8) | | ||
455 | buf[4]); | ||
456 | hw->y = (((buf[3] & 0x20) << 7) | | ||
457 | ((buf[1] & 0xf0) << 4) | | ||
458 | buf[5]); | ||
459 | hw->z = buf[2]; | ||
460 | |||
451 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | 461 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && |
452 | ((buf[0] ^ buf[3]) & 0x02)) { | 462 | ((buf[0] ^ buf[3]) & 0x02)) { |
453 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | 463 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { |
@@ -485,7 +495,8 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
485 | return 0; | 495 | return 0; |
486 | } | 496 | } |
487 | 497 | ||
488 | static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) | 498 | static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot, |
499 | bool active, int x, int y) | ||
489 | { | 500 | { |
490 | input_mt_slot(dev, slot); | 501 | input_mt_slot(dev, slot); |
491 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | 502 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); |
@@ -502,14 +513,16 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, | |||
502 | int num_fingers) | 513 | int num_fingers) |
503 | { | 514 | { |
504 | if (num_fingers >= 2) { | 515 | if (num_fingers >= 2) { |
505 | set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y)); | 516 | synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x), |
506 | set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y)); | 517 | min(a->y, b->y)); |
518 | synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x), | ||
519 | max(a->y, b->y)); | ||
507 | } else if (num_fingers == 1) { | 520 | } else if (num_fingers == 1) { |
508 | set_slot(dev, 0, true, a->x, a->y); | 521 | synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y); |
509 | set_slot(dev, 1, false, 0, 0); | 522 | synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); |
510 | } else { | 523 | } else { |
511 | set_slot(dev, 0, false, 0, 0); | 524 | synaptics_report_semi_mt_slot(dev, 0, false, 0, 0); |
512 | set_slot(dev, 1, false, 0, 0); | 525 | synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); |
513 | } | 526 | } |
514 | } | 527 | } |
515 | 528 | ||
@@ -684,23 +697,36 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
684 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | 697 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) |
685 | { | 698 | { |
686 | int i; | 699 | int i; |
700 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? | ||
701 | SYN_REDUCED_FILTER_FUZZ : 0; | ||
687 | 702 | ||
688 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | 703 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
689 | 704 | ||
690 | __set_bit(EV_ABS, dev->evbit); | 705 | __set_bit(EV_ABS, dev->evbit); |
691 | input_set_abs_params(dev, ABS_X, | 706 | input_set_abs_params(dev, ABS_X, |
692 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); | 707 | priv->x_min ?: XMIN_NOMINAL, |
708 | priv->x_max ?: XMAX_NOMINAL, | ||
709 | fuzz, 0); | ||
693 | input_set_abs_params(dev, ABS_Y, | 710 | input_set_abs_params(dev, ABS_Y, |
694 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | 711 | priv->y_min ?: YMIN_NOMINAL, |
712 | priv->y_max ?: YMAX_NOMINAL, | ||
713 | fuzz, 0); | ||
695 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 714 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
696 | 715 | ||
697 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 716 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
698 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 717 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
699 | input_mt_init_slots(dev, 2); | 718 | input_mt_init_slots(dev, 2); |
700 | input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, | 719 | input_set_abs_params(dev, ABS_MT_POSITION_X, |
701 | priv->x_max ?: XMAX_NOMINAL, 0, 0); | 720 | priv->x_min ?: XMIN_NOMINAL, |
702 | input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, | 721 | priv->x_max ?: XMAX_NOMINAL, |
703 | priv->y_max ?: YMAX_NOMINAL, 0, 0); | 722 | fuzz, 0); |
723 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
724 | priv->y_min ?: YMIN_NOMINAL, | ||
725 | priv->y_max ?: YMAX_NOMINAL, | ||
726 | fuzz, 0); | ||
727 | |||
728 | input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); | ||
729 | input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); | ||
704 | } | 730 | } |
705 | 731 | ||
706 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 732 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
@@ -971,4 +997,3 @@ bool synaptics_supported(void) | |||
971 | } | 997 | } |
972 | 998 | ||
973 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 999 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
974 | |||