From 7d01cd261c76f95913c81554a751968a1d282d3a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 13 Jul 2015 09:54:42 -0700 Subject: [PATCH 1/5] Input: zforce - don't overwrite the stack If we get a corrupted packet with PAYLOAD_LENGTH > FRAME_MAXSIZE, we will silently overwrite the stack. Cc: stable@vger.kernel.org Signed-off-by: Oleksij Rempel Signed-off-by: Dirk Behme Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/zforce_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index f58a196521a9..80285c71786e 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -429,7 +429,7 @@ static int zforce_read_packet(struct zforce_ts *ts, u8 *buf) goto unlock; } - if (buf[PAYLOAD_LENGTH] == 0) { + if (buf[PAYLOAD_LENGTH] == 0 || buf[PAYLOAD_LENGTH] > FRAME_MAXSIZE) { dev_err(&client->dev, "invalid payload length: %d\n", buf[PAYLOAD_LENGTH]); ret = -EIO; From d98399e688f8c4f42f4270c2dfe1293f69247c5b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 16 Jul 2015 10:38:15 -0700 Subject: [PATCH 2/5] Input: elantech - force resolution of 31 u/mm All Elantech touchpads pre-v4 with dynamic resolution queries have a fixed resolution of 800dpi -> 31.49 units/mm. Set this statically, so userspace does not have to guess. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede Reviewed-by: David Herrmann Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ce3d40004458..22b9ca901f4e 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1167,7 +1167,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) struct input_dev *dev = psmouse->dev; struct elantech_data *etd = psmouse->private; unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; - unsigned int x_res = 0, y_res = 0; + unsigned int x_res = 31, y_res = 31; if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) return -1; @@ -1232,8 +1232,6 @@ static int elantech_set_input_params(struct psmouse *psmouse) /* For X to recognize me as touchpad. */ input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); - input_abs_set_res(dev, ABS_X, x_res); - input_abs_set_res(dev, ABS_Y, y_res); /* * range of pressure and width is the same as v2, * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility. @@ -1246,8 +1244,6 @@ static int elantech_set_input_params(struct psmouse *psmouse) input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); - input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); - input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res); input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2, ETP_PMAX_V2, 0, 0); /* @@ -1259,6 +1255,13 @@ static int elantech_set_input_params(struct psmouse *psmouse) break; } + input_abs_set_res(dev, ABS_X, x_res); + input_abs_set_res(dev, ABS_Y, y_res); + if (etd->hw_version > 1) { + input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); + input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res); + } + etd->y_max = y_max; etd->width = width; From 968491709e5b1aaf429428814fff3d932fa90b60 Mon Sep 17 00:00:00 2001 From: Bernhard Bender Date: Thu, 23 Jul 2015 13:58:08 -0700 Subject: [PATCH 3/5] Input: usbtouchscreen - avoid unresponsive TSC-30 touch screen This patch fixes a problem in the usbtouchscreen driver for DMC TSC-30 touch screen. Due to a missing delay between the RESET and SET_RATE commands, the touch screen may become unresponsive during system startup or driver loading. According to the DMC documentation, a delay is needed after the RESET command to allow the chip to complete its internal initialization. As this delay is not guaranteed, we had a system where the touch screen occasionally did not send any touch data. There was no other indication of the problem. The patch fixes the problem by adding a 150ms delay between the RESET and SET_RATE commands. Cc: stable@vger.kernel.org Suggested-by: Jakob Mustafa Signed-off-by: Bernhard Bender Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f2c6c352c55a..2c41107240de 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -627,6 +627,9 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) goto err_out; } + /* TSC-25 data sheet specifies a delay after the RESET command */ + msleep(150); + /* set coordinate output rate */ buf[0] = buf[1] = 0xFF; ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), From b38ebd1d4b6656582b8c16358bb88d059d28b794 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 22 Jul 2015 14:56:39 -0700 Subject: [PATCH 4/5] Input: LEDs - skip unnamed LEDs Devices may declare more LEDs than what is known to input-leds (HID does this for some devices). Instead of showing ugly warnings on connect and, even worse, oopsing on disconnect, let's simply ignore LEDs that are not known to us. Reported-and-tested-by: Vlastimil Babka Signed-off-by: Dmitry Torokhov --- drivers/input/input-leds.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 074a65ed17bb..766bf2660116 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -71,6 +71,18 @@ static void input_leds_event(struct input_handle *handle, unsigned int type, { } +static int input_leds_get_count(struct input_dev *dev) +{ + unsigned int led_code; + int count = 0; + + for_each_set_bit(led_code, dev->ledbit, LED_CNT) + if (input_led_info[led_code].name) + count++; + + return count; +} + static int input_leds_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) @@ -81,7 +93,7 @@ static int input_leds_connect(struct input_handler *handler, int led_no; int error; - num_leds = bitmap_weight(dev->ledbit, LED_CNT); + num_leds = input_leds_get_count(dev); if (!num_leds) return -ENXIO; @@ -112,7 +124,7 @@ static int input_leds_connect(struct input_handler *handler, led->handle = &leds->handle; led->code = led_code; - if (WARN_ON(!input_led_info[led_code].name)) + if (!input_led_info[led_code].name) continue; led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", From 8b5a359c5b3e631f17eeb1dcb930474000d33d49 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 24 Jul 2015 09:08:53 -0700 Subject: [PATCH 5/5] Input: goodix - fix touch coordinates on WinBook TW100 and TW700 The touchscreen on the WinBook TW100 and TW700 don't match the default display, with 0,0 touches being reported when touching at the bottom right of the screen. 1280,800 0,800 +-------------+ | | | | | | +-------------+ 1280,0 0,0 It's unfortunately impossible to detect this problem with data from the DSDT, or other auxiliary metadata, so fallback to quirking this specific model of tablet instead. Signed-off-by: Bastien Nocera Reviewed-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index b4d12e29abff..e36162b28c2a 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,7 @@ struct goodix_ts_data { int abs_y_max; unsigned int max_touch_num; unsigned int int_trigger_type; + bool rotated_screen; }; #define GOODIX_MAX_HEIGHT 4096 @@ -60,6 +62,30 @@ static const unsigned long goodix_irq_flags[] = { IRQ_TYPE_LEVEL_HIGH, }; +/* + * Those tablets have their coordinates origin at the bottom right + * of the tablet, as if rotated 180 degrees + */ +static const struct dmi_system_id rotated_screen[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + .ident = "WinBook TW100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), + DMI_MATCH(DMI_PRODUCT_NAME, "TW100") + } + }, + { + .ident = "WinBook TW700", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), + DMI_MATCH(DMI_PRODUCT_NAME, "TW700") + }, + }, +#endif + {} +}; + /** * goodix_i2c_read - read data from a register of the i2c slave device. * @@ -129,6 +155,11 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) int input_y = get_unaligned_le16(&coor_data[3]); int input_w = get_unaligned_le16(&coor_data[5]); + if (ts->rotated_screen) { + input_x = ts->abs_x_max - input_x; + input_y = ts->abs_y_max - input_y; + } + input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); @@ -223,6 +254,11 @@ static void goodix_read_config(struct goodix_ts_data *ts) ts->abs_y_max = GOODIX_MAX_HEIGHT; ts->max_touch_num = GOODIX_MAX_CONTACTS; } + + ts->rotated_screen = dmi_check_system(rotated_screen); + if (ts->rotated_screen) + dev_dbg(&ts->client->dev, + "Applying '180 degrees rotated screen' quirk\n"); } /**