aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/synaptics.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 12:24:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 12:24:56 -0400
commit70a3eff5768350c0313a9ae70a15da113171d0ab (patch)
tree9c2558f92e567bcb35c79f59bc7ebc9cf6fdc9d3 /drivers/input/mouse/synaptics.c
parent9ed3689bdceb0064ee6faf0e76f6467122794970 (diff)
parentaa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (53 commits) Input: synaptics - fix reporting of min coordinates Input: tegra-kbc - enable key autorepeat Input: kxtj9 - fix locking typo in kxtj9_set_poll() Input: kxtj9 - fix bug in probe() Input: intel-mid-touch - remove pointless checking for variable 'found' Input: hp_sdc - staticize hp_sdc_kicker() Input: pmic8xxx-keypad - fix a leak of the IRQ during init failure Input: cy8ctmg110_ts - set reset_pin and irq_pin from platform data Input: cy8ctmg110_ts - constify i2c_device_id table Input: cy8ctmg110_ts - fix checking return value of i2c_master_send Input: lifebook - make dmi callback functions return 1 Input: atkbd - make dmi callback functions return 1 Input: gpio_keys - switch to using SIMPLE_DEV_PM_OPS Input: gpio_keys - add support for device-tree platform data Input: aiptek - remove double define Input: synaptics - set minimum coordinates as reported by firmware Input: synaptics - process button bits in AGM packets Input: synaptics - rename set_slot to be more descriptive Input: synaptics - fuzz position for touchpad with reduced filtering Input: synaptics - set resolution for MT_POSITION_X/Y axes ...
Diffstat (limited to 'drivers/input/mouse/synaptics.c')
-rw-r--r--drivers/input/mouse/synaptics.c107
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)
207static int synaptics_resolution(struct psmouse *psmouse) 207static 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
488static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) 498static 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)
684static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) 697static 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