From 8be3c650f54c259694e82282e54b12c14304487e Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Wed, 6 Jul 2011 22:27:47 -0700 Subject: Input: synaptics - set resolution for MT_POSITION_X/Y axes Set resolution for MT_POSITION_X and MT_POSITION_Y to match ABS_X and ABS_Y, respectively. Signed-off-by: Daniel Kurtz Acked-by: Chase Douglas Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/input/mouse/synaptics.c') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e06e045bf907..477d1eaea8b5 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -701,6 +701,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) priv->x_max ?: XMAX_NOMINAL, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); + + input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); + input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); } if (SYN_CAP_PALMDETECT(priv->capabilities)) -- cgit v1.2.3 From a9f0b79edfda3750d254ba5b192795e2554c361d Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Wed, 6 Jul 2011 22:39:14 -0700 Subject: Input: synaptics - fuzz position for touchpad with reduced filtering Synaptics touchpads indicate via a capability bit when they perform reduced filtering on position data. In such a case, use a non-zero fuzz value. Fuzz = 8 was chosen empirically by observing the raw position data reported by a clickpad indicating it had reduced filtering. Signed-off-by: Daniel Kurtz Acked-by: Chase Douglas Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/input/mouse/synaptics.c') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 477d1eaea8b5..363aedf8131d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -684,23 +684,25 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) { int i; + int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? + SYN_REDUCED_FILTER_FUZZ : 0; __set_bit(INPUT_PROP_POINTER, dev->propbit); __set_bit(EV_ABS, dev->evbit); - input_set_abs_params(dev, ABS_X, - XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); - input_set_abs_params(dev, ABS_Y, - YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, + priv->x_max ?: XMAX_NOMINAL, fuzz, 0); + input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, + priv->y_max ?: YMAX_NOMINAL, fuzz, 0); input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); input_mt_init_slots(dev, 2); input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, - priv->x_max ?: XMAX_NOMINAL, 0, 0); + priv->x_max ?: XMAX_NOMINAL, fuzz, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, - priv->y_max ?: YMAX_NOMINAL, 0, 0); + priv->y_max ?: YMAX_NOMINAL, fuzz, 0); input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); @@ -974,4 +976,3 @@ bool synaptics_supported(void) } #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ - -- cgit v1.2.3 From bea9f0ff263e1c2031d76afc21c22ad773f0b163 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Wed, 6 Jul 2011 22:42:52 -0700 Subject: Input: synaptics - rename set_slot to be more descriptive Signed-off-by: Daniel Kurtz Acked-by: Chase Douglas Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/input/mouse/synaptics.c') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 363aedf8131d..c5c91bc2cce8 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -485,7 +485,8 @@ static int synaptics_parse_hw_state(const unsigned char buf[], return 0; } -static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) +static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot, + bool active, int x, int y) { input_mt_slot(dev, slot); input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); @@ -502,14 +503,16 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, int num_fingers) { if (num_fingers >= 2) { - set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y)); - set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y)); + synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x), + min(a->y, b->y)); + synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x), + max(a->y, b->y)); } else if (num_fingers == 1) { - set_slot(dev, 0, true, a->x, a->y); - set_slot(dev, 1, false, 0, 0); + synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y); + synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); } else { - set_slot(dev, 0, false, 0, 0); - set_slot(dev, 1, false, 0, 0); + synaptics_report_semi_mt_slot(dev, 0, false, 0, 0); + synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); } } -- cgit v1.2.3 From 28d5fd860f97f017573c4cd8f199bab867c50a11 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Wed, 6 Jul 2011 22:57:39 -0700 Subject: Input: synaptics - process button bits in AGM packets AGM packets contain valid button bits, too. This patch refactors packet processing to parse button bits in AGM packets. However, they aren't actually used or reported. The point is to more completely process AGM packets, and prepare for future patches that may actually use AGM packet button bits. Signed-off-by: Daniel Kurtz Acked-by: Chase Douglas Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/input/mouse/synaptics.c') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c5c91bc2cce8..86bd89a28710 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -406,26 +406,10 @@ static int synaptics_parse_hw_state(const unsigned char buf[], memset(hw, 0, sizeof(struct synaptics_hw_state)); if (SYN_MODEL_NEWABS(priv->model_id)) { - hw->x = (((buf[3] & 0x10) << 8) | - ((buf[1] & 0x0f) << 8) | - buf[4]); - hw->y = (((buf[3] & 0x20) << 7) | - ((buf[1] & 0xf0) << 4) | - buf[5]); - - hw->z = buf[2]; hw->w = (((buf[0] & 0x30) >> 2) | ((buf[0] & 0x04) >> 1) | ((buf[3] & 0x04) >> 2)); - if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { - /* Gesture packet: (x, y, z) at half resolution */ - priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; - priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; - priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; - return 1; - } - hw->left = (buf[0] & 0x01) ? 1 : 0; hw->right = (buf[0] & 0x02) ? 1 : 0; @@ -448,6 +432,22 @@ static int synaptics_parse_hw_state(const unsigned char buf[], hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; } + if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { + /* Gesture packet: (x, y, z) at half resolution */ + priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; + priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; + priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; + return 1; + } + + hw->x = (((buf[3] & 0x10) << 8) | + ((buf[1] & 0x0f) << 8) | + buf[4]); + hw->y = (((buf[3] & 0x20) << 7) | + ((buf[1] & 0xf0) << 4) | + buf[5]); + hw->z = buf[2]; + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && ((buf[0] ^ buf[3]) & 0x02)) { switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { -- cgit v1.2.3 From a66413fbc37994710d638aec3314f735a7ac0df5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 9 Jul 2011 12:32:56 -0700 Subject: Input: synaptics - set minimum coordinates as reported by firmware Newer Synaptics firmware allows to query minimum coordinates reported by the device, let's use this data. Acked-by: Chase Douglas Acked-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 56 +++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 19 deletions(-) (limited to 'drivers/input/mouse/synaptics.c') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 86bd89a28710..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) static int synaptics_resolution(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; - unsigned char res[3]; - unsigned char max[3]; + unsigned char resp[3]; if (SYN_ID_MAJOR(priv->identity) < 4) return 0; - if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { - if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { - priv->x_res = res[0]; /* x resolution in units/mm */ - priv->y_res = res[2]; /* y resolution in units/mm */ + if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp) == 0) { + if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) { + priv->x_res = resp[0]; /* x resolution in units/mm */ + priv->y_res = resp[2]; /* y resolution in units/mm */ } } if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { - if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { - printk(KERN_ERR "Synaptics claims to have dimensions query," - " but I'm not able to read it.\n"); + if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { + printk(KERN_ERR "Synaptics claims to have max coordinates" + " query, but I'm not able to read it.\n"); + } else { + priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); + priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); + } + } + + if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && + SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { + if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { + printk(KERN_ERR "Synaptics claims to have min coordinates" + " query, but I'm not able to read it.\n"); } else { - priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); - priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); + priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); + priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); } } @@ -693,19 +703,27 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) __set_bit(INPUT_PROP_POINTER, dev->propbit); __set_bit(EV_ABS, dev->evbit); - input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, - priv->x_max ?: XMAX_NOMINAL, fuzz, 0); - input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, - priv->y_max ?: YMAX_NOMINAL, fuzz, 0); + input_set_abs_params(dev, ABS_X, + priv->x_min ?: XMIN_NOMINAL, + priv->x_max ?: XMAX_NOMINAL, + fuzz, 0); + input_set_abs_params(dev, ABS_Y, + priv->y_min ?: YMIN_NOMINAL, + priv->y_max ?: YMAX_NOMINAL, + fuzz, 0); input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); input_mt_init_slots(dev, 2); - input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, - priv->x_max ?: XMAX_NOMINAL, fuzz, 0); - input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, - priv->y_max ?: YMAX_NOMINAL, fuzz, 0); + input_set_abs_params(dev, ABS_MT_POSITION_X, + priv->x_min ?: XMIN_NOMINAL, + priv->x_max ?: XMAX_NOMINAL, + fuzz, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, + priv->y_min ?: YMIN_NOMINAL, + priv->y_max ?: YMAX_NOMINAL, + fuzz, 0); input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); -- cgit v1.2.3