12 #include <linux/input.h>
13 #include <linux/serio.h>
19 #define PS2PP_KIND_WHEEL 1
20 #define PS2PP_KIND_MX 2
21 #define PS2PP_KIND_TP3 3
22 #define PS2PP_KIND_TRACKMAN 4
25 #define PS2PP_WHEEL 0x01
26 #define PS2PP_HWHEEL 0x02
27 #define PS2PP_SIDE_BTN 0x04
28 #define PS2PP_EXTRA_BTN 0x08
29 #define PS2PP_TASK_BTN 0x10
30 #define PS2PP_NAV_BTN 0x20
44 struct input_dev *
dev = psmouse->
dev;
54 if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {
57 switch ((packet[1] >> 4) | (packet[0] & 0x30)) {
62 (
int) (packet[2] & 8) - (
int) (packet[2] & 7));
63 input_report_key(dev,
BTN_SIDE, (packet[2] >> 4) & 1);
64 input_report_key(dev,
BTN_EXTRA, (packet[2] >> 5) & 1);
70 input_report_key(dev,
BTN_SIDE, (packet[2]) & 1);
71 input_report_key(dev,
BTN_EXTRA, (packet[2] >> 1) & 1);
72 input_report_key(dev,
BTN_BACK, (packet[2] >> 3) & 1);
73 input_report_key(dev,
BTN_FORWARD, (packet[2] >> 4) & 1);
74 input_report_key(dev,
BTN_TASK, (packet[2] >> 2) & 1);
80 input_report_rel(dev, packet[2] & 0x08 ?
REL_HWHEEL : REL_WHEEL,
81 (
int) ((packet[2] >> 4) & 8) - (
int) ((packet[2] >> 4) & 7));
82 packet[0] = packet[2] | 0x08;
87 "Received PS2++ packet #%x, but don't know how to handle.\n",
88 (packet[1] >> 4) | (packet[0] & 0x30));
93 input_report_rel(dev,
REL_X, packet[1] ? (
int) packet[1] - (
int) ((packet[0] << 4) & 0x100) : 0);
94 input_report_rel(dev,
REL_Y, packet[2] ? (
int) ((packet[0] << 3) & 0x100) - (
int) packet[2] : 0);
97 input_report_key(dev,
BTN_LEFT, packet[0] & 1);
98 input_report_key(dev,
BTN_MIDDLE, (packet[0] >> 2) & 1);
99 input_report_key(dev,
BTN_RIGHT, (packet[0] >> 1) & 1);
114 static int ps2pp_cmd(
struct psmouse *psmouse,
unsigned char *
param,
unsigned char command)
133 static void ps2pp_set_smartscroll(
struct psmouse *psmouse,
bool smartscroll)
136 unsigned char param[4];
138 ps2pp_cmd(psmouse, param, 0x32);
145 param[0] = smartscroll;
149 static ssize_t ps2pp_attr_show_smartscroll(
struct psmouse *psmouse,
155 static ssize_t ps2pp_attr_set_smartscroll(
struct psmouse *psmouse,
void *
data,
168 ps2pp_set_smartscroll(psmouse, value);
174 ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
182 static void ps2pp_set_resolution(
struct psmouse *psmouse,
unsigned int resolution)
184 if (resolution > 400) {
186 unsigned char param = 3;
197 static void ps2pp_disconnect(
struct psmouse *psmouse)
204 static const struct ps2pp_info ps2pp_list[] = {
255 if (model == ps2pp_list[i].model)
256 return &ps2pp_list[
i];
265 static void ps2pp_set_model_properties(
struct psmouse *psmouse,
269 struct input_dev *input_dev = psmouse->
dev;
291 switch (model_info->
kind) {
294 psmouse->
name =
"Wheel Mouse";
298 psmouse->
name =
"MX Mouse";
302 psmouse->
name =
"TouchPad 3";
306 psmouse->
name =
"TrackMan";
316 psmouse->
name =
"Mouse";
331 unsigned char param[4];
334 bool use_ps2pp =
false;
345 model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
348 if (!model || !buttons)
351 model_info = get_model_info(model);
360 param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
363 param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
366 param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
371 param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
377 param[0] = param[1] = param[2] = 0;
378 ps2pp_cmd(psmouse, param, 0x39);
379 ps2pp_cmd(psmouse, param, 0xDB);
381 if ((param[0] & 0x78) == 0x48 &&
382 (param[1] & 0xf3) == 0xc2 &&
383 (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
384 ps2pp_set_smartscroll(psmouse,
false);
390 psmouse_warn(psmouse,
"Detected unknown Logitech mouse model %d\n", model);
393 if (set_properties) {
394 psmouse->
vendor =
"Logitech";
406 &psmouse_attr_smartscroll.dattr);
409 "failed to create smartscroll sysfs attribute, error: %d\n",
420 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
423 return use_ps2pp ? 0 : -1;