aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-24 19:33:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-24 19:33:11 -0400
commita52bd79e3ef683808e129c7627e8878ea0309459 (patch)
tree7afc8cd1330fa554a22d104282cc30a56be79d29
parentafdf0b91bdf04bc66ee64e1ac44f0979c55749b1 (diff)
parent8b5a359c5b3e631f17eeb1dcb930474000d33d49 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: "A fix for the warnings/oops when handling HID devices with "unnamed" LEDs and couple of other driver fixups"" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: goodix - fix touch coordinates on WinBook TW100 and TW700 Input: LEDs - skip unnamed LEDs Input: usbtouchscreen - avoid unresponsive TSC-30 touch screen Input: elantech - force resolution of 31 u/mm Input: zforce - don't overwrite the stack
-rw-r--r--drivers/input/input-leds.c16
-rw-r--r--drivers/input/mouse/elantech.c13
-rw-r--r--drivers/input/touchscreen/goodix.c36
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c3
-rw-r--r--drivers/input/touchscreen/zforce_ts.c2
5 files changed, 62 insertions, 8 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,
71{ 71{
72} 72}
73 73
74static int input_leds_get_count(struct input_dev *dev)
75{
76 unsigned int led_code;
77 int count = 0;
78
79 for_each_set_bit(led_code, dev->ledbit, LED_CNT)
80 if (input_led_info[led_code].name)
81 count++;
82
83 return count;
84}
85
74static int input_leds_connect(struct input_handler *handler, 86static int input_leds_connect(struct input_handler *handler,
75 struct input_dev *dev, 87 struct input_dev *dev,
76 const struct input_device_id *id) 88 const struct input_device_id *id)
@@ -81,7 +93,7 @@ static int input_leds_connect(struct input_handler *handler,
81 int led_no; 93 int led_no;
82 int error; 94 int error;
83 95
84 num_leds = bitmap_weight(dev->ledbit, LED_CNT); 96 num_leds = input_leds_get_count(dev);
85 if (!num_leds) 97 if (!num_leds)
86 return -ENXIO; 98 return -ENXIO;
87 99
@@ -112,7 +124,7 @@ static int input_leds_connect(struct input_handler *handler,
112 led->handle = &leds->handle; 124 led->handle = &leds->handle;
113 led->code = led_code; 125 led->code = led_code;
114 126
115 if (WARN_ON(!input_led_info[led_code].name)) 127 if (!input_led_info[led_code].name)
116 continue; 128 continue;
117 129
118 led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", 130 led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s",
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)
1167 struct input_dev *dev = psmouse->dev; 1167 struct input_dev *dev = psmouse->dev;
1168 struct elantech_data *etd = psmouse->private; 1168 struct elantech_data *etd = psmouse->private;
1169 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; 1169 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0;
1170 unsigned int x_res = 0, y_res = 0; 1170 unsigned int x_res = 31, y_res = 31;
1171 1171
1172 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) 1172 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
1173 return -1; 1173 return -1;
@@ -1232,8 +1232,6 @@ static int elantech_set_input_params(struct psmouse *psmouse)
1232 /* For X to recognize me as touchpad. */ 1232 /* For X to recognize me as touchpad. */
1233 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); 1233 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
1234 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); 1234 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
1235 input_abs_set_res(dev, ABS_X, x_res);
1236 input_abs_set_res(dev, ABS_Y, y_res);
1237 /* 1235 /*
1238 * range of pressure and width is the same as v2, 1236 * range of pressure and width is the same as v2,
1239 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility. 1237 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
@@ -1246,8 +1244,6 @@ static int elantech_set_input_params(struct psmouse *psmouse)
1246 input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); 1244 input_mt_init_slots(dev, ETP_MAX_FINGERS, 0);
1247 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); 1245 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
1248 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); 1246 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
1249 input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
1250 input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
1251 input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2, 1247 input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
1252 ETP_PMAX_V2, 0, 0); 1248 ETP_PMAX_V2, 0, 0);
1253 /* 1249 /*
@@ -1259,6 +1255,13 @@ static int elantech_set_input_params(struct psmouse *psmouse)
1259 break; 1255 break;
1260 } 1256 }
1261 1257
1258 input_abs_set_res(dev, ABS_X, x_res);
1259 input_abs_set_res(dev, ABS_Y, y_res);
1260 if (etd->hw_version > 1) {
1261 input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
1262 input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
1263 }
1264
1262 etd->y_max = y_max; 1265 etd->y_max = y_max;
1263 etd->width = width; 1266 etd->width = width;
1264 1267
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 @@
15 */ 15 */
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/dmi.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
19#include <linux/input.h> 20#include <linux/input.h>
20#include <linux/input/mt.h> 21#include <linux/input/mt.h>
@@ -34,6 +35,7 @@ struct goodix_ts_data {
34 int abs_y_max; 35 int abs_y_max;
35 unsigned int max_touch_num; 36 unsigned int max_touch_num;
36 unsigned int int_trigger_type; 37 unsigned int int_trigger_type;
38 bool rotated_screen;
37}; 39};
38 40
39#define GOODIX_MAX_HEIGHT 4096 41#define GOODIX_MAX_HEIGHT 4096
@@ -60,6 +62,30 @@ static const unsigned long goodix_irq_flags[] = {
60 IRQ_TYPE_LEVEL_HIGH, 62 IRQ_TYPE_LEVEL_HIGH,
61}; 63};
62 64
65/*
66 * Those tablets have their coordinates origin at the bottom right
67 * of the tablet, as if rotated 180 degrees
68 */
69static const struct dmi_system_id rotated_screen[] = {
70#if defined(CONFIG_DMI) && defined(CONFIG_X86)
71 {
72 .ident = "WinBook TW100",
73 .matches = {
74 DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
75 DMI_MATCH(DMI_PRODUCT_NAME, "TW100")
76 }
77 },
78 {
79 .ident = "WinBook TW700",
80 .matches = {
81 DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
82 DMI_MATCH(DMI_PRODUCT_NAME, "TW700")
83 },
84 },
85#endif
86 {}
87};
88
63/** 89/**
64 * goodix_i2c_read - read data from a register of the i2c slave device. 90 * goodix_i2c_read - read data from a register of the i2c slave device.
65 * 91 *
@@ -129,6 +155,11 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
129 int input_y = get_unaligned_le16(&coor_data[3]); 155 int input_y = get_unaligned_le16(&coor_data[3]);
130 int input_w = get_unaligned_le16(&coor_data[5]); 156 int input_w = get_unaligned_le16(&coor_data[5]);
131 157
158 if (ts->rotated_screen) {
159 input_x = ts->abs_x_max - input_x;
160 input_y = ts->abs_y_max - input_y;
161 }
162
132 input_mt_slot(ts->input_dev, id); 163 input_mt_slot(ts->input_dev, id);
133 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); 164 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
134 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); 165 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)
223 ts->abs_y_max = GOODIX_MAX_HEIGHT; 254 ts->abs_y_max = GOODIX_MAX_HEIGHT;
224 ts->max_touch_num = GOODIX_MAX_CONTACTS; 255 ts->max_touch_num = GOODIX_MAX_CONTACTS;
225 } 256 }
257
258 ts->rotated_screen = dmi_check_system(rotated_screen);
259 if (ts->rotated_screen)
260 dev_dbg(&ts->client->dev,
261 "Applying '180 degrees rotated screen' quirk\n");
226} 262}
227 263
228/** 264/**
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)
627 goto err_out; 627 goto err_out;
628 } 628 }
629 629
630 /* TSC-25 data sheet specifies a delay after the RESET command */
631 msleep(150);
632
630 /* set coordinate output rate */ 633 /* set coordinate output rate */
631 buf[0] = buf[1] = 0xFF; 634 buf[0] = buf[1] = 0xFF;
632 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), 635 ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
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)
429 goto unlock; 429 goto unlock;
430 } 430 }
431 431
432 if (buf[PAYLOAD_LENGTH] == 0) { 432 if (buf[PAYLOAD_LENGTH] == 0 || buf[PAYLOAD_LENGTH] > FRAME_MAXSIZE) {
433 dev_err(&client->dev, "invalid payload length: %d\n", 433 dev_err(&client->dev, "invalid payload length: %d\n",
434 buf[PAYLOAD_LENGTH]); 434 buf[PAYLOAD_LENGTH]);
435 ret = -EIO; 435 ret = -EIO;