aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2017-03-22 18:27:53 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-02-02 19:49:01 -0500
commit592c352b95db8db9c0d71795183ec1f6ee5c4213 (patch)
tree6d7dbc3d3745128a3994a5e868d85a3507e85c44
parentba667650c568d55f6b80be54951b098f86939f2d (diff)
Input: logips2pp - clean up code
- switch to using BIT() macros - use u8 instead of unsigned char for byte data - use input_set_capability() instead of manipulating capabilities bits directly - use sign_extend32() when extracting wheel data. - do not abuse -1 as error code, propagate errors from various calls. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/mouse/logips2pp.c142
1 files changed, 83 insertions, 59 deletions
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index b7d17db632fc..3c8d7051ef5e 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -9,9 +9,11 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/bitops.h>
12#include <linux/input.h> 13#include <linux/input.h>
13#include <linux/serio.h> 14#include <linux/serio.h>
14#include <linux/libps2.h> 15#include <linux/libps2.h>
16#include <linux/types.h>
15#include "psmouse.h" 17#include "psmouse.h"
16#include "logips2pp.h" 18#include "logips2pp.h"
17 19
@@ -22,12 +24,12 @@
22#define PS2PP_KIND_TRACKMAN 4 24#define PS2PP_KIND_TRACKMAN 4
23 25
24/* Logitech mouse features */ 26/* Logitech mouse features */
25#define PS2PP_WHEEL 0x01 27#define PS2PP_WHEEL BIT(0)
26#define PS2PP_HWHEEL 0x02 28#define PS2PP_HWHEEL BIT(1)
27#define PS2PP_SIDE_BTN 0x04 29#define PS2PP_SIDE_BTN BIT(2)
28#define PS2PP_EXTRA_BTN 0x08 30#define PS2PP_EXTRA_BTN BIT(3)
29#define PS2PP_TASK_BTN 0x10 31#define PS2PP_TASK_BTN BIT(4)
30#define PS2PP_NAV_BTN 0x20 32#define PS2PP_NAV_BTN BIT(5)
31 33
32struct ps2pp_info { 34struct ps2pp_info {
33 u8 model; 35 u8 model;
@@ -42,7 +44,7 @@ struct ps2pp_info {
42static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) 44static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
43{ 45{
44 struct input_dev *dev = psmouse->dev; 46 struct input_dev *dev = psmouse->dev;
45 unsigned char *packet = psmouse->packet; 47 u8 *packet = psmouse->packet;
46 48
47 if (psmouse->pktcnt < 3) 49 if (psmouse->pktcnt < 3)
48 return PSMOUSE_GOOD_DATA; 50 return PSMOUSE_GOOD_DATA;
@@ -58,28 +60,30 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
58 60
59 case 0x0d: /* Mouse extra info */ 61 case 0x0d: /* Mouse extra info */
60 62
61 input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, 63 input_report_rel(dev,
62 (int) (packet[2] & 8) - (int) (packet[2] & 7)); 64 packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
63 input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); 65 -sign_extend32(packet[2], 3));
64 input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); 66 input_report_key(dev, BTN_SIDE, packet[2] & BIT(4));
67 input_report_key(dev, BTN_EXTRA, packet[2] & BIT(5));
65 68
66 break; 69 break;
67 70
68 case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ 71 case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
69 72
70 input_report_key(dev, BTN_SIDE, (packet[2]) & 1); 73 input_report_key(dev, BTN_SIDE, packet[2] & BIT(0));
71 input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); 74 input_report_key(dev, BTN_EXTRA, packet[2] & BIT(1));
72 input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); 75 input_report_key(dev, BTN_TASK, packet[2] & BIT(2));
73 input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); 76 input_report_key(dev, BTN_BACK, packet[2] & BIT(3));
74 input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); 77 input_report_key(dev, BTN_FORWARD, packet[2] & BIT(4));
75 78
76 break; 79 break;
77 80
78 case 0x0f: /* TouchPad extra info */ 81 case 0x0f: /* TouchPad extra info */
79 82
80 input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, 83 input_report_rel(dev,
81 (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); 84 packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
82 packet[0] = packet[2] | 0x08; 85 -sign_extend32(packet[2] >> 4, 3));
86 packet[0] = packet[2] | BIT(3);
83 break; 87 break;
84 88
85 default: 89 default:
@@ -109,13 +113,17 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
109 * Ugly. 113 * Ugly.
110 */ 114 */
111 115
112static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command) 116static int ps2pp_cmd(struct psmouse *psmouse, u8 *param, u8 command)
113{ 117{
114 if (psmouse_sliced_command(psmouse, command)) 118 int error;
115 return -1; 119
120 error = psmouse_sliced_command(psmouse, command);
121 if (error)
122 return error;
116 123
117 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300)) 124 error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300);
118 return -1; 125 if (error)
126 return error;
119 127
120 return 0; 128 return 0;
121} 129}
@@ -131,7 +139,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
131static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll) 139static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
132{ 140{
133 struct ps2dev *ps2dev = &psmouse->ps2dev; 141 struct ps2dev *ps2dev = &psmouse->ps2dev;
134 unsigned char param[4]; 142 u8 param[4];
135 143
136 ps2pp_cmd(psmouse, param, 0x32); 144 ps2pp_cmd(psmouse, param, 0x32);
137 145
@@ -169,7 +177,7 @@ static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
169} 177}
170 178
171PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL, 179PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
172 ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll); 180 ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
173 181
174/* 182/*
175 * Support 800 dpi resolution _only_ if the user wants it (there are good 183 * Support 800 dpi resolution _only_ if the user wants it (there are good
@@ -177,11 +185,12 @@ PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
177 * also good reasons to use it, let the user decide). 185 * also good reasons to use it, let the user decide).
178 */ 186 */
179 187
180static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution) 188static void ps2pp_set_resolution(struct psmouse *psmouse,
189 unsigned int resolution)
181{ 190{
182 if (resolution > 400) { 191 if (resolution > 400) {
183 struct ps2dev *ps2dev = &psmouse->ps2dev; 192 struct ps2dev *ps2dev = &psmouse->ps2dev;
184 unsigned char param = 3; 193 u8 param = 3;
185 194
186 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); 195 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
187 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); 196 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
@@ -194,7 +203,8 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio
194 203
195static void ps2pp_disconnect(struct psmouse *psmouse) 204static void ps2pp_disconnect(struct psmouse *psmouse)
196{ 205{
197 device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr); 206 device_remove_file(&psmouse->ps2dev.serio->dev,
207 &psmouse_attr_smartscroll.dattr);
198} 208}
199 209
200static const struct ps2pp_info *get_model_info(unsigned char model) 210static const struct ps2pp_info *get_model_info(unsigned char model)
@@ -267,24 +277,24 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
267 struct input_dev *input_dev = psmouse->dev; 277 struct input_dev *input_dev = psmouse->dev;
268 278
269 if (model_info->features & PS2PP_SIDE_BTN) 279 if (model_info->features & PS2PP_SIDE_BTN)
270 __set_bit(BTN_SIDE, input_dev->keybit); 280 input_set_capability(input_dev, EV_KEY, BTN_SIDE);
271 281
272 if (model_info->features & PS2PP_EXTRA_BTN) 282 if (model_info->features & PS2PP_EXTRA_BTN)
273 __set_bit(BTN_EXTRA, input_dev->keybit); 283 input_set_capability(input_dev, EV_KEY, BTN_EXTRA);
274 284
275 if (model_info->features & PS2PP_TASK_BTN) 285 if (model_info->features & PS2PP_TASK_BTN)
276 __set_bit(BTN_TASK, input_dev->keybit); 286 input_set_capability(input_dev, EV_KEY, BTN_TASK);
277 287
278 if (model_info->features & PS2PP_NAV_BTN) { 288 if (model_info->features & PS2PP_NAV_BTN) {
279 __set_bit(BTN_FORWARD, input_dev->keybit); 289 input_set_capability(input_dev, EV_KEY, BTN_FORWARD);
280 __set_bit(BTN_BACK, input_dev->keybit); 290 input_set_capability(input_dev, EV_KEY, BTN_BACK);
281 } 291 }
282 292
283 if (model_info->features & PS2PP_WHEEL) 293 if (model_info->features & PS2PP_WHEEL)
284 __set_bit(REL_WHEEL, input_dev->relbit); 294 input_set_capability(input_dev, EV_REL, REL_WHEEL);
285 295
286 if (model_info->features & PS2PP_HWHEEL) 296 if (model_info->features & PS2PP_HWHEEL)
287 __set_bit(REL_HWHEEL, input_dev->relbit); 297 input_set_capability(input_dev, EV_REL, REL_HWHEEL);
288 298
289 switch (model_info->kind) { 299 switch (model_info->kind) {
290 300
@@ -316,6 +326,30 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
316 } 326 }
317} 327}
318 328
329static int ps2pp_setup_protocol(struct psmouse *psmouse,
330 const struct ps2pp_info *model_info)
331{
332 int error;
333
334 psmouse->protocol_handler = ps2pp_process_byte;
335 psmouse->pktsize = 3;
336
337 if (model_info->kind != PS2PP_KIND_TP3) {
338 psmouse->set_resolution = ps2pp_set_resolution;
339 psmouse->disconnect = ps2pp_disconnect;
340
341 error = device_create_file(&psmouse->ps2dev.serio->dev,
342 &psmouse_attr_smartscroll.dattr);
343 if (error) {
344 psmouse_err(psmouse,
345 "failed to create smartscroll sysfs attribute, error: %d\n",
346 error);
347 return error;
348 }
349 }
350
351 return 0;
352}
319 353
320/* 354/*
321 * Logitech magic init. Detect whether the mouse is a Logitech one 355 * Logitech magic init. Detect whether the mouse is a Logitech one
@@ -326,9 +360,9 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
326int ps2pp_detect(struct psmouse *psmouse, bool set_properties) 360int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
327{ 361{
328 struct ps2dev *ps2dev = &psmouse->ps2dev; 362 struct ps2dev *ps2dev = &psmouse->ps2dev;
329 unsigned char param[4];
330 unsigned char model, buttons;
331 const struct ps2pp_info *model_info; 363 const struct ps2pp_info *model_info;
364 u8 param[4];
365 u8 model, buttons;
332 bool use_ps2pp = false; 366 bool use_ps2pp = false;
333 int error; 367 int error;
334 368
@@ -344,7 +378,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
344 buttons = param[1]; 378 buttons = param[1];
345 379
346 if (!model || !buttons) 380 if (!model || !buttons)
347 return -1; 381 return -ENXIO;
348 382
349 model_info = get_model_info(model); 383 model_info = get_model_info(model);
350 if (model_info) { 384 if (model_info) {
@@ -366,7 +400,8 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
366 400
367 param[0] = 0; 401 param[0] = 0;
368 if (!ps2_command(ps2dev, param, 0x13d1) && 402 if (!ps2_command(ps2dev, param, 0x13d1) &&
369 param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { 403 param[0] == 0x06 && param[1] == 0x00 &&
404 param[2] == 0x14) {
370 use_ps2pp = true; 405 use_ps2pp = true;
371 } 406 }
372 407
@@ -385,7 +420,9 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
385 } 420 }
386 421
387 } else { 422 } else {
388 psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model); 423 psmouse_warn(psmouse,
424 "Detected unknown Logitech mouse model %d\n",
425 model);
389 } 426 }
390 427
391 if (set_properties) { 428 if (set_properties) {
@@ -393,31 +430,18 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
393 psmouse->model = model; 430 psmouse->model = model;
394 431
395 if (use_ps2pp) { 432 if (use_ps2pp) {
396 psmouse->protocol_handler = ps2pp_process_byte; 433 error = ps2pp_setup_protocol(psmouse, model_info);
397 psmouse->pktsize = 3; 434 if (error)
398 435 return error;
399 if (model_info->kind != PS2PP_KIND_TP3) {
400 psmouse->set_resolution = ps2pp_set_resolution;
401 psmouse->disconnect = ps2pp_disconnect;
402
403 error = device_create_file(&ps2dev->serio->dev,
404 &psmouse_attr_smartscroll.dattr);
405 if (error) {
406 psmouse_err(psmouse,
407 "failed to create smartscroll sysfs attribute, error: %d\n",
408 error);
409 return -1;
410 }
411 }
412 } 436 }
413 437
414 if (buttons >= 3) 438 if (buttons >= 3)
415 __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 439 input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
416 440
417 if (model_info) 441 if (model_info)
418 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); 442 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
419 } 443 }
420 444
421 return use_ps2pp ? 0 : -1; 445 return use_ps2pp ? 0 : -ENXIO;
422} 446}
423 447