diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-25 20:30:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-25 20:30:47 -0500 |
commit | 993ca2068b043dc3c933a8a4fe1052b77fe63f10 (patch) | |
tree | ea20f515820b7fe08e6a602a793c9e43120b386e | |
parent | 6793f1c450b1533a5e9c2493490de771d38b24f9 (diff) | |
parent | 060403f34008af90e310d7e0e7531ebb3acf9557 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov:
"The main item is that we try to better handle the newer trackpoints on
Lenovo devices that are now being produced by Elan/ALPS/NXP and only
implement a small subset of the original IBM trackpoint controls"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Revert "Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01"
Input: trackpoint - only expose supported controls for Elan, ALPS and NXP
Input: trackpoint - force 3 buttons if 0 button is reported
Input: xpad - add support for PDP Xbox One controllers
Input: stmfts,s6sy671 - add SPDX identifier
-rw-r--r-- | drivers/input/joystick/xpad.c | 19 | ||||
-rw-r--r-- | drivers/input/mouse/trackpoint.c | 245 | ||||
-rw-r--r-- | drivers/input/mouse/trackpoint.h | 34 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f01.c | 12 | ||||
-rw-r--r-- | drivers/input/touchscreen/s6sy761.c | 15 | ||||
-rw-r--r-- | drivers/input/touchscreen/stmfts.c | 15 |
6 files changed, 210 insertions, 130 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d86e59515b9c..d88d3e0f59fb 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -229,6 +229,7 @@ static const struct xpad_device { | |||
229 | { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, | 229 | { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, |
230 | { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, | 230 | { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, |
231 | { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, | 231 | { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, |
232 | { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, | ||
232 | { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, | 233 | { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, |
233 | { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, | 234 | { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, |
234 | { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, | 235 | { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, |
@@ -476,6 +477,22 @@ static const u8 xboxone_hori_init[] = { | |||
476 | }; | 477 | }; |
477 | 478 | ||
478 | /* | 479 | /* |
480 | * This packet is required for some of the PDP pads to start | ||
481 | * sending input reports. One of those pads is (0x0e6f:0x02ab). | ||
482 | */ | ||
483 | static const u8 xboxone_pdp_init1[] = { | ||
484 | 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 | ||
485 | }; | ||
486 | |||
487 | /* | ||
488 | * This packet is required for some of the PDP pads to start | ||
489 | * sending input reports. One of those pads is (0x0e6f:0x02ab). | ||
490 | */ | ||
491 | static const u8 xboxone_pdp_init2[] = { | ||
492 | 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 | ||
493 | }; | ||
494 | |||
495 | /* | ||
479 | * A specific rumble packet is required for some PowerA pads to start | 496 | * A specific rumble packet is required for some PowerA pads to start |
480 | * sending input reports. One of those pads is (0x24c6:0x543a). | 497 | * sending input reports. One of those pads is (0x24c6:0x543a). |
481 | */ | 498 | */ |
@@ -505,6 +522,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { | |||
505 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), | 522 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), |
506 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), | 523 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), |
507 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), | 524 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), |
525 | XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1), | ||
526 | XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2), | ||
508 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), | 527 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), |
509 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), | 528 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), |
510 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), | 529 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 0871010f18d5..bbd29220dbe9 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -19,6 +19,13 @@ | |||
19 | #include "psmouse.h" | 19 | #include "psmouse.h" |
20 | #include "trackpoint.h" | 20 | #include "trackpoint.h" |
21 | 21 | ||
22 | static const char * const trackpoint_variants[] = { | ||
23 | [TP_VARIANT_IBM] = "IBM", | ||
24 | [TP_VARIANT_ALPS] = "ALPS", | ||
25 | [TP_VARIANT_ELAN] = "Elan", | ||
26 | [TP_VARIANT_NXP] = "NXP", | ||
27 | }; | ||
28 | |||
22 | /* | 29 | /* |
23 | * Power-on Reset: Resets all trackpoint parameters, including RAM values, | 30 | * Power-on Reset: Resets all trackpoint parameters, including RAM values, |
24 | * to defaults. | 31 | * to defaults. |
@@ -26,7 +33,7 @@ | |||
26 | */ | 33 | */ |
27 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | 34 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) |
28 | { | 35 | { |
29 | unsigned char results[2]; | 36 | u8 results[2]; |
30 | int tries = 0; | 37 | int tries = 0; |
31 | 38 | ||
32 | /* Issue POR command, and repeat up to once if 0xFC00 received */ | 39 | /* Issue POR command, and repeat up to once if 0xFC00 received */ |
@@ -38,7 +45,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | |||
38 | 45 | ||
39 | /* Check for success response -- 0xAA00 */ | 46 | /* Check for success response -- 0xAA00 */ |
40 | if (results[0] != 0xAA || results[1] != 0x00) | 47 | if (results[0] != 0xAA || results[1] != 0x00) |
41 | return -1; | 48 | return -ENODEV; |
42 | 49 | ||
43 | return 0; | 50 | return 0; |
44 | } | 51 | } |
@@ -46,8 +53,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | |||
46 | /* | 53 | /* |
47 | * Device IO: read, write and toggle bit | 54 | * Device IO: read, write and toggle bit |
48 | */ | 55 | */ |
49 | static int trackpoint_read(struct ps2dev *ps2dev, | 56 | static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results) |
50 | unsigned char loc, unsigned char *results) | ||
51 | { | 57 | { |
52 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 58 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || |
53 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) { | 59 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) { |
@@ -57,8 +63,7 @@ static int trackpoint_read(struct ps2dev *ps2dev, | |||
57 | return 0; | 63 | return 0; |
58 | } | 64 | } |
59 | 65 | ||
60 | static int trackpoint_write(struct ps2dev *ps2dev, | 66 | static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val) |
61 | unsigned char loc, unsigned char val) | ||
62 | { | 67 | { |
63 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 68 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || |
64 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) || | 69 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) || |
@@ -70,8 +75,7 @@ static int trackpoint_write(struct ps2dev *ps2dev, | |||
70 | return 0; | 75 | return 0; |
71 | } | 76 | } |
72 | 77 | ||
73 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, | 78 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask) |
74 | unsigned char loc, unsigned char mask) | ||
75 | { | 79 | { |
76 | /* Bad things will happen if the loc param isn't in this range */ | 80 | /* Bad things will happen if the loc param isn't in this range */ |
77 | if (loc < 0x20 || loc >= 0x2F) | 81 | if (loc < 0x20 || loc >= 0x2F) |
@@ -87,11 +91,11 @@ static int trackpoint_toggle_bit(struct ps2dev *ps2dev, | |||
87 | return 0; | 91 | return 0; |
88 | } | 92 | } |
89 | 93 | ||
90 | static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc, | 94 | static int trackpoint_update_bit(struct ps2dev *ps2dev, |
91 | unsigned char mask, unsigned char value) | 95 | u8 loc, u8 mask, u8 value) |
92 | { | 96 | { |
93 | int retval = 0; | 97 | int retval = 0; |
94 | unsigned char data; | 98 | u8 data; |
95 | 99 | ||
96 | trackpoint_read(ps2dev, loc, &data); | 100 | trackpoint_read(ps2dev, loc, &data); |
97 | if (((data & mask) == mask) != !!value) | 101 | if (((data & mask) == mask) != !!value) |
@@ -105,17 +109,18 @@ static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc, | |||
105 | */ | 109 | */ |
106 | struct trackpoint_attr_data { | 110 | struct trackpoint_attr_data { |
107 | size_t field_offset; | 111 | size_t field_offset; |
108 | unsigned char command; | 112 | u8 command; |
109 | unsigned char mask; | 113 | u8 mask; |
110 | unsigned char inverted; | 114 | bool inverted; |
111 | unsigned char power_on_default; | 115 | u8 power_on_default; |
112 | }; | 116 | }; |
113 | 117 | ||
114 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) | 118 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, |
119 | void *data, char *buf) | ||
115 | { | 120 | { |
116 | struct trackpoint_data *tp = psmouse->private; | 121 | struct trackpoint_data *tp = psmouse->private; |
117 | struct trackpoint_attr_data *attr = data; | 122 | struct trackpoint_attr_data *attr = data; |
118 | unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset); | 123 | u8 value = *(u8 *)((void *)tp + attr->field_offset); |
119 | 124 | ||
120 | if (attr->inverted) | 125 | if (attr->inverted) |
121 | value = !value; | 126 | value = !value; |
@@ -128,8 +133,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, | |||
128 | { | 133 | { |
129 | struct trackpoint_data *tp = psmouse->private; | 134 | struct trackpoint_data *tp = psmouse->private; |
130 | struct trackpoint_attr_data *attr = data; | 135 | struct trackpoint_attr_data *attr = data; |
131 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 136 | u8 *field = (void *)tp + attr->field_offset; |
132 | unsigned char value; | 137 | u8 value; |
133 | int err; | 138 | int err; |
134 | 139 | ||
135 | err = kstrtou8(buf, 10, &value); | 140 | err = kstrtou8(buf, 10, &value); |
@@ -157,17 +162,14 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
157 | { | 162 | { |
158 | struct trackpoint_data *tp = psmouse->private; | 163 | struct trackpoint_data *tp = psmouse->private; |
159 | struct trackpoint_attr_data *attr = data; | 164 | struct trackpoint_attr_data *attr = data; |
160 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 165 | bool *field = (void *)tp + attr->field_offset; |
161 | unsigned int value; | 166 | bool value; |
162 | int err; | 167 | int err; |
163 | 168 | ||
164 | err = kstrtouint(buf, 10, &value); | 169 | err = kstrtobool(buf, &value); |
165 | if (err) | 170 | if (err) |
166 | return err; | 171 | return err; |
167 | 172 | ||
168 | if (value > 1) | ||
169 | return -EINVAL; | ||
170 | |||
171 | if (attr->inverted) | 173 | if (attr->inverted) |
172 | value = !value; | 174 | value = !value; |
173 | 175 | ||
@@ -193,30 +195,6 @@ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ | |||
193 | &trackpoint_attr_##_name, \ | 195 | &trackpoint_attr_##_name, \ |
194 | trackpoint_show_int_attr, trackpoint_set_bit_attr) | 196 | trackpoint_show_int_attr, trackpoint_set_bit_attr) |
195 | 197 | ||
196 | #define TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name) \ | ||
197 | do { \ | ||
198 | struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \ | ||
199 | \ | ||
200 | trackpoint_update_bit(&_psmouse->ps2dev, \ | ||
201 | _attr->command, _attr->mask, _tp->_name); \ | ||
202 | } while (0) | ||
203 | |||
204 | #define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \ | ||
205 | do { \ | ||
206 | if (!_power_on || \ | ||
207 | _tp->_name != trackpoint_attr_##_name.power_on_default) { \ | ||
208 | if (!trackpoint_attr_##_name.mask) \ | ||
209 | trackpoint_write(&_psmouse->ps2dev, \ | ||
210 | trackpoint_attr_##_name.command, \ | ||
211 | _tp->_name); \ | ||
212 | else \ | ||
213 | TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name); \ | ||
214 | } \ | ||
215 | } while (0) | ||
216 | |||
217 | #define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \ | ||
218 | (_tp->_name = trackpoint_attr_##_name.power_on_default) | ||
219 | |||
220 | TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS); | 198 | TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS); |
221 | TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED); | 199 | TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED); |
222 | TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA); | 200 | TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA); |
@@ -229,13 +207,33 @@ TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); | |||
229 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); | 207 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); |
230 | TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); | 208 | TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); |
231 | 209 | ||
232 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0, | 210 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, false, |
233 | TP_DEF_PTSON); | 211 | TP_DEF_PTSON); |
234 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0, | 212 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, false, |
235 | TP_DEF_SKIPBACK); | 213 | TP_DEF_SKIPBACK); |
236 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1, | 214 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, true, |
237 | TP_DEF_EXT_DEV); | 215 | TP_DEF_EXT_DEV); |
238 | 216 | ||
217 | static bool trackpoint_is_attr_available(struct psmouse *psmouse, | ||
218 | struct attribute *attr) | ||
219 | { | ||
220 | struct trackpoint_data *tp = psmouse->private; | ||
221 | |||
222 | return tp->variant_id == TP_VARIANT_IBM || | ||
223 | attr == &psmouse_attr_sensitivity.dattr.attr || | ||
224 | attr == &psmouse_attr_press_to_select.dattr.attr; | ||
225 | } | ||
226 | |||
227 | static umode_t trackpoint_is_attr_visible(struct kobject *kobj, | ||
228 | struct attribute *attr, int n) | ||
229 | { | ||
230 | struct device *dev = container_of(kobj, struct device, kobj); | ||
231 | struct serio *serio = to_serio_port(dev); | ||
232 | struct psmouse *psmouse = serio_get_drvdata(serio); | ||
233 | |||
234 | return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0; | ||
235 | } | ||
236 | |||
239 | static struct attribute *trackpoint_attrs[] = { | 237 | static struct attribute *trackpoint_attrs[] = { |
240 | &psmouse_attr_sensitivity.dattr.attr, | 238 | &psmouse_attr_sensitivity.dattr.attr, |
241 | &psmouse_attr_speed.dattr.attr, | 239 | &psmouse_attr_speed.dattr.attr, |
@@ -255,24 +253,56 @@ static struct attribute *trackpoint_attrs[] = { | |||
255 | }; | 253 | }; |
256 | 254 | ||
257 | static struct attribute_group trackpoint_attr_group = { | 255 | static struct attribute_group trackpoint_attr_group = { |
258 | .attrs = trackpoint_attrs, | 256 | .is_visible = trackpoint_is_attr_visible, |
257 | .attrs = trackpoint_attrs, | ||
259 | }; | 258 | }; |
260 | 259 | ||
261 | static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id) | 260 | #define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \ |
262 | { | 261 | do { \ |
263 | unsigned char param[2] = { 0 }; | 262 | struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \ |
263 | \ | ||
264 | if ((!_power_on || _tp->_name != _attr->power_on_default) && \ | ||
265 | trackpoint_is_attr_available(_psmouse, \ | ||
266 | &psmouse_attr_##_name.dattr.attr)) { \ | ||
267 | if (!_attr->mask) \ | ||
268 | trackpoint_write(&_psmouse->ps2dev, \ | ||
269 | _attr->command, _tp->_name); \ | ||
270 | else \ | ||
271 | trackpoint_update_bit(&_psmouse->ps2dev, \ | ||
272 | _attr->command, _attr->mask, \ | ||
273 | _tp->_name); \ | ||
274 | } \ | ||
275 | } while (0) | ||
264 | 276 | ||
265 | if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) | 277 | #define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \ |
266 | return -1; | 278 | do { \ |
279 | _tp->_name = trackpoint_attr_##_name.power_on_default; \ | ||
280 | } while (0) | ||
267 | 281 | ||
268 | /* add new TP ID. */ | 282 | static int trackpoint_start_protocol(struct psmouse *psmouse, |
269 | if (!(param[0] & TP_MAGIC_IDENT)) | 283 | u8 *variant_id, u8 *firmware_id) |
270 | return -1; | 284 | { |
285 | u8 param[2] = { 0 }; | ||
286 | int error; | ||
271 | 287 | ||
272 | if (firmware_id) | 288 | error = ps2_command(&psmouse->ps2dev, |
273 | *firmware_id = param[1]; | 289 | param, MAKE_PS2_CMD(0, 2, TP_READ_ID)); |
290 | if (error) | ||
291 | return error; | ||
292 | |||
293 | switch (param[0]) { | ||
294 | case TP_VARIANT_IBM: | ||
295 | case TP_VARIANT_ALPS: | ||
296 | case TP_VARIANT_ELAN: | ||
297 | case TP_VARIANT_NXP: | ||
298 | if (variant_id) | ||
299 | *variant_id = param[0]; | ||
300 | if (firmware_id) | ||
301 | *firmware_id = param[1]; | ||
302 | return 0; | ||
303 | } | ||
274 | 304 | ||
275 | return 0; | 305 | return -ENODEV; |
276 | } | 306 | } |
277 | 307 | ||
278 | /* | 308 | /* |
@@ -285,7 +315,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state) | |||
285 | { | 315 | { |
286 | struct trackpoint_data *tp = psmouse->private; | 316 | struct trackpoint_data *tp = psmouse->private; |
287 | 317 | ||
288 | if (!in_power_on_state) { | 318 | if (!in_power_on_state && tp->variant_id == TP_VARIANT_IBM) { |
289 | /* | 319 | /* |
290 | * Disable features that may make device unusable | 320 | * Disable features that may make device unusable |
291 | * with this driver. | 321 | * with this driver. |
@@ -347,7 +377,8 @@ static void trackpoint_defaults(struct trackpoint_data *tp) | |||
347 | 377 | ||
348 | static void trackpoint_disconnect(struct psmouse *psmouse) | 378 | static void trackpoint_disconnect(struct psmouse *psmouse) |
349 | { | 379 | { |
350 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | 380 | device_remove_group(&psmouse->ps2dev.serio->dev, |
381 | &trackpoint_attr_group); | ||
351 | 382 | ||
352 | kfree(psmouse->private); | 383 | kfree(psmouse->private); |
353 | psmouse->private = NULL; | 384 | psmouse->private = NULL; |
@@ -355,14 +386,20 @@ static void trackpoint_disconnect(struct psmouse *psmouse) | |||
355 | 386 | ||
356 | static int trackpoint_reconnect(struct psmouse *psmouse) | 387 | static int trackpoint_reconnect(struct psmouse *psmouse) |
357 | { | 388 | { |
358 | int reset_fail; | 389 | struct trackpoint_data *tp = psmouse->private; |
390 | int error; | ||
391 | bool was_reset; | ||
359 | 392 | ||
360 | if (trackpoint_start_protocol(psmouse, NULL)) | 393 | error = trackpoint_start_protocol(psmouse, NULL, NULL); |
361 | return -1; | 394 | if (error) |
395 | return error; | ||
362 | 396 | ||
363 | reset_fail = trackpoint_power_on_reset(&psmouse->ps2dev); | 397 | was_reset = tp->variant_id == TP_VARIANT_IBM && |
364 | if (trackpoint_sync(psmouse, !reset_fail)) | 398 | trackpoint_power_on_reset(&psmouse->ps2dev) == 0; |
365 | return -1; | 399 | |
400 | error = trackpoint_sync(psmouse, was_reset); | ||
401 | if (error) | ||
402 | return error; | ||
366 | 403 | ||
367 | return 0; | 404 | return 0; |
368 | } | 405 | } |
@@ -370,46 +407,66 @@ static int trackpoint_reconnect(struct psmouse *psmouse) | |||
370 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | 407 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
371 | { | 408 | { |
372 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 409 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
373 | unsigned char firmware_id; | 410 | struct trackpoint_data *tp; |
374 | unsigned char button_info; | 411 | u8 variant_id; |
412 | u8 firmware_id; | ||
413 | u8 button_info; | ||
375 | int error; | 414 | int error; |
376 | 415 | ||
377 | if (trackpoint_start_protocol(psmouse, &firmware_id)) | 416 | error = trackpoint_start_protocol(psmouse, &variant_id, &firmware_id); |
378 | return -1; | 417 | if (error) |
418 | return error; | ||
379 | 419 | ||
380 | if (!set_properties) | 420 | if (!set_properties) |
381 | return 0; | 421 | return 0; |
382 | 422 | ||
383 | if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) { | 423 | tp = kzalloc(sizeof(*tp), GFP_KERNEL); |
384 | psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n"); | 424 | if (!tp) |
385 | button_info = 0x33; | ||
386 | } | ||
387 | |||
388 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | ||
389 | if (!psmouse->private) | ||
390 | return -ENOMEM; | 425 | return -ENOMEM; |
391 | 426 | ||
392 | psmouse->vendor = "IBM"; | 427 | trackpoint_defaults(tp); |
428 | tp->variant_id = variant_id; | ||
429 | tp->firmware_id = firmware_id; | ||
430 | |||
431 | psmouse->private = tp; | ||
432 | |||
433 | psmouse->vendor = trackpoint_variants[variant_id]; | ||
393 | psmouse->name = "TrackPoint"; | 434 | psmouse->name = "TrackPoint"; |
394 | 435 | ||
395 | psmouse->reconnect = trackpoint_reconnect; | 436 | psmouse->reconnect = trackpoint_reconnect; |
396 | psmouse->disconnect = trackpoint_disconnect; | 437 | psmouse->disconnect = trackpoint_disconnect; |
397 | 438 | ||
439 | if (variant_id != TP_VARIANT_IBM) { | ||
440 | /* Newer variants do not support extended button query. */ | ||
441 | button_info = 0x33; | ||
442 | } else { | ||
443 | error = trackpoint_read(ps2dev, TP_EXT_BTN, &button_info); | ||
444 | if (error) { | ||
445 | psmouse_warn(psmouse, | ||
446 | "failed to get extended button data, assuming 3 buttons\n"); | ||
447 | button_info = 0x33; | ||
448 | } else if (!button_info) { | ||
449 | psmouse_warn(psmouse, | ||
450 | "got 0 in extended button data, assuming 3 buttons\n"); | ||
451 | button_info = 0x33; | ||
452 | } | ||
453 | } | ||
454 | |||
398 | if ((button_info & 0x0f) >= 3) | 455 | if ((button_info & 0x0f) >= 3) |
399 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 456 | input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE); |
400 | 457 | ||
401 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); | 458 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); |
402 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); | 459 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); |
403 | 460 | ||
404 | trackpoint_defaults(psmouse->private); | 461 | if (variant_id != TP_VARIANT_IBM || |
405 | 462 | trackpoint_power_on_reset(ps2dev) != 0) { | |
406 | error = trackpoint_power_on_reset(ps2dev); | 463 | /* |
407 | 464 | * Write defaults to TP if we did not reset the trackpoint. | |
408 | /* Write defaults to TP only if reset fails. */ | 465 | */ |
409 | if (error) | ||
410 | trackpoint_sync(psmouse, false); | 466 | trackpoint_sync(psmouse, false); |
467 | } | ||
411 | 468 | ||
412 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 469 | error = device_add_group(&ps2dev->serio->dev, &trackpoint_attr_group); |
413 | if (error) { | 470 | if (error) { |
414 | psmouse_err(psmouse, | 471 | psmouse_err(psmouse, |
415 | "failed to create sysfs attributes, error: %d\n", | 472 | "failed to create sysfs attributes, error: %d\n", |
@@ -420,8 +477,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
420 | } | 477 | } |
421 | 478 | ||
422 | psmouse_info(psmouse, | 479 | psmouse_info(psmouse, |
423 | "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", | 480 | "%s TrackPoint firmware: 0x%02x, buttons: %d/%d\n", |
424 | firmware_id, | 481 | psmouse->vendor, firmware_id, |
425 | (button_info & 0xf0) >> 4, button_info & 0x0f); | 482 | (button_info & 0xf0) >> 4, button_info & 0x0f); |
426 | 483 | ||
427 | return 0; | 484 | return 0; |
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 88055755f82e..10a039148234 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -21,10 +21,16 @@ | |||
21 | #define TP_COMMAND 0xE2 /* Commands start with this */ | 21 | #define TP_COMMAND 0xE2 /* Commands start with this */ |
22 | 22 | ||
23 | #define TP_READ_ID 0xE1 /* Sent for device identification */ | 23 | #define TP_READ_ID 0xE1 /* Sent for device identification */ |
24 | #define TP_MAGIC_IDENT 0x03 /* Sent after a TP_READ_ID followed */ | ||
25 | /* by the firmware ID */ | ||
26 | /* Firmware ID includes 0x1, 0x2, 0x3 */ | ||
27 | 24 | ||
25 | /* | ||
26 | * Valid first byte responses to the "Read Secondary ID" (0xE1) command. | ||
27 | * 0x01 was the original IBM trackpoint, others implement very limited | ||
28 | * subset of trackpoint features. | ||
29 | */ | ||
30 | #define TP_VARIANT_IBM 0x01 | ||
31 | #define TP_VARIANT_ALPS 0x02 | ||
32 | #define TP_VARIANT_ELAN 0x03 | ||
33 | #define TP_VARIANT_NXP 0x04 | ||
28 | 34 | ||
29 | /* | 35 | /* |
30 | * Commands | 36 | * Commands |
@@ -136,18 +142,20 @@ | |||
136 | 142 | ||
137 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) | 143 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) |
138 | 144 | ||
139 | struct trackpoint_data | 145 | struct trackpoint_data { |
140 | { | 146 | u8 variant_id; |
141 | unsigned char sensitivity, speed, inertia, reach; | 147 | u8 firmware_id; |
142 | unsigned char draghys, mindrag; | 148 | |
143 | unsigned char thresh, upthresh; | 149 | u8 sensitivity, speed, inertia, reach; |
144 | unsigned char ztime, jenks; | 150 | u8 draghys, mindrag; |
145 | unsigned char drift_time; | 151 | u8 thresh, upthresh; |
152 | u8 ztime, jenks; | ||
153 | u8 drift_time; | ||
146 | 154 | ||
147 | /* toggles */ | 155 | /* toggles */ |
148 | unsigned char press_to_select; | 156 | bool press_to_select; |
149 | unsigned char skipback; | 157 | bool skipback; |
150 | unsigned char ext_dev; | 158 | bool ext_dev; |
151 | }; | 159 | }; |
152 | 160 | ||
153 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT | 161 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT |
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index ae966e333a2f..8a07ae147df6 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c | |||
@@ -570,14 +570,19 @@ static int rmi_f01_probe(struct rmi_function *fn) | |||
570 | 570 | ||
571 | dev_set_drvdata(&fn->dev, f01); | 571 | dev_set_drvdata(&fn->dev, f01); |
572 | 572 | ||
573 | error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group); | 573 | error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); |
574 | if (error) | 574 | if (error) |
575 | dev_warn(&fn->dev, | 575 | dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error); |
576 | "Failed to create attribute group: %d\n", error); | ||
577 | 576 | ||
578 | return 0; | 577 | return 0; |
579 | } | 578 | } |
580 | 579 | ||
580 | static void rmi_f01_remove(struct rmi_function *fn) | ||
581 | { | ||
582 | /* Note that the bus device is used, not the F01 device */ | ||
583 | sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); | ||
584 | } | ||
585 | |||
581 | static int rmi_f01_config(struct rmi_function *fn) | 586 | static int rmi_f01_config(struct rmi_function *fn) |
582 | { | 587 | { |
583 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | 588 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); |
@@ -717,6 +722,7 @@ struct rmi_function_handler rmi_f01_handler = { | |||
717 | }, | 722 | }, |
718 | .func = 0x01, | 723 | .func = 0x01, |
719 | .probe = rmi_f01_probe, | 724 | .probe = rmi_f01_probe, |
725 | .remove = rmi_f01_remove, | ||
720 | .config = rmi_f01_config, | 726 | .config = rmi_f01_config, |
721 | .attention = rmi_f01_attention, | 727 | .attention = rmi_f01_attention, |
722 | .suspend = rmi_f01_suspend, | 728 | .suspend = rmi_f01_suspend, |
diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c index 26b1cb8a88ec..675efa93d444 100644 --- a/drivers/input/touchscreen/s6sy761.c +++ b/drivers/input/touchscreen/s6sy761.c | |||
@@ -1,13 +1,8 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * Copyright (c) 2017 Samsung Electronics Co., Ltd. | 2 | // Samsung S6SY761 Touchscreen device driver |
3 | * Author: Andi Shyti <andi.shyti@samsung.com> | 3 | // |
4 | * | 4 | // Copyright (c) 2017 Samsung Electronics Co., Ltd. |
5 | * This program is free software; you can redistribute it and/or modify | 5 | // Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com> |
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * Samsung S6SY761 Touchscreen device driver | ||
10 | */ | ||
11 | 6 | ||
12 | #include <asm/unaligned.h> | 7 | #include <asm/unaligned.h> |
13 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index c12d01899939..2a123e20a42e 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c | |||
@@ -1,13 +1,8 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * Copyright (c) 2017 Samsung Electronics Co., Ltd. | 2 | // STMicroelectronics FTS Touchscreen device driver |
3 | * Author: Andi Shyti <andi.shyti@samsung.com> | 3 | // |
4 | * | 4 | // Copyright (c) 2017 Samsung Electronics Co., Ltd. |
5 | * This program is free software; you can redistribute it and/or modify | 5 | // Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com> |
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * STMicroelectronics FTS Touchscreen device driver | ||
10 | */ | ||
11 | 6 | ||
12 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
13 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |