diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-24 19:33:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-24 19:33:11 -0400 |
commit | a52bd79e3ef683808e129c7627e8878ea0309459 (patch) | |
tree | 7afc8cd1330fa554a22d104282cc30a56be79d29 | |
parent | afdf0b91bdf04bc66ee64e1ac44f0979c55749b1 (diff) | |
parent | 8b5a359c5b3e631f17eeb1dcb930474000d33d49 (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.c | 16 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 13 | ||||
-rw-r--r-- | drivers/input/touchscreen/goodix.c | 36 | ||||
-rw-r--r-- | drivers/input/touchscreen/usbtouchscreen.c | 3 | ||||
-rw-r--r-- | drivers/input/touchscreen/zforce_ts.c | 2 |
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 | ||
74 | static 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 | |||
74 | static int input_leds_connect(struct input_handler *handler, | 86 | static 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 | */ | ||
69 | static 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; |