Skip to contentSkip to conversation

Logitech PS/2++ updates

PATCH In review Eric Wong 3 participants 9 messages Mar 26, 2003 – Jun 20, 2003 Input drivers

lore
Share & tools
lore

Eric Wong

author
#0 lore raw

PATCH 1/1 Logitech PS/2++ updates

Updates to the PS/2++ mouse protocol used by Logitech, as well as SMS/Smart Scroll/Cruise Control and 800 cpi resolution control for those who want it. Up to 10 buttons are supported now, although only 8 are used at the moment on the MX500 and MX700.

drivers/input/mouse/psmouse.c +136 -8
diff -bruN a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c
@@ -21,9 +21,17 @@
 MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
 MODULE_DESCRIPTION("PS/2 mouse driver");
 MODULE_PARM(psmouse_noext, "1i");
+MODULE_PARM(psmouse_res, "i");
+MODULE_PARM_DESC(psmouse_res, "resolution, not all mice support all values");
+MODULE_PARM(psmouse_sms, "i");
+MODULE_PARM_DESC(psmouse_sms, "autorepeat, 1 = enabled (default) | 0 = disabled");
 MODULE_LICENSE("GPL");
 
+#define PSMOUSE_LOGITECH_SMS	1
+
 static int psmouse_noext;
+static int psmouse_res;
+static int psmouse_sms = PSMOUSE_LOGITECH_SMS;
 
 #define PSMOUSE_CMD_SETSCALE11	0x00e6
 #define PSMOUSE_CMD_SETRES	0x10e8
@@ -83,8 +91,47 @@
 /*
  * The PS2++ protocol is a little bit complex
  */
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {
 
-	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
+			switch (((packet[1] >> 4) & 0x0f) | (packet[0] & 0x30)) {
+
+			case 0x0d: /* Mouse extra info */
+
+				input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+					(int) (packet[2] & 8) - (int) (packet[2] & 7));
+				input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+
+				break;
+			case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
+
+				input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
+				input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+				input_report_key(dev, BTN_SMSUP, (packet[2] >> 3) & 1);
+				input_report_key(dev, BTN_SMSDOWN, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_H118, (packet[2] >> 5) & 1);
+				input_report_key(dev, BTN_H119, (packet[2] >> 6) & 1);
+
+				break;
+#ifdef DEBUG
+			default:
+				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
+					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
+#endif
+
+			}
+
+		packet[0] &= 0x0f;
+		packet[1] = 0;
+		packet[2] = 0;
+
+		}
+	}
+	
+	if (psmouse->type == PSMOUSE_PS2TPP) {
 
 		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
 
@@ -112,7 +159,6 @@
 				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
 					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
 #endif
-
 			}
 
 		packet[0] &= 0x0f;
@@ -385,9 +431,11 @@
 
 		int i;
 		static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
-		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, -1 };
+		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
 		static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
-							76, 80, 81, 83, 88, 96, 97, -1 };
+							76, 80, 81, 83, 88, 96, 97, 112, -1 };
+		static int logitech_P2[] = { 112, -1 };
+
 		psmouse->vendor = "Logitech";
 		psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
 
@@ -414,6 +462,17 @@
 					psmouse->name = "Wheel Mouse";
 				}
 
+			for (i = 0; logitech_P2[i] != -1; i++)
+				if (logitech_P2[i]  == psmouse->model) {
+					set_bit(BTN_SIDE, psmouse->dev.keybit);
+					set_bit(BTN_EXTRA, psmouse->dev.keybit);
+					set_bit(BTN_TASK, psmouse->dev.keybit);
+					set_bit(BTN_SMSUP, psmouse->dev.keybit);
+					set_bit(BTN_SMSDOWN, psmouse->dev.keybit);
+					set_bit(BTN_H118, psmouse->dev.keybit);
+					set_bit(BTN_H119, psmouse->dev.keybit);
+				}
+
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
  */
@@ -534,6 +593,60 @@
 }
 
 /*
+ * SMS/Smart Scroll/Cruise Control for some newer Logitech mice 
+ * Defaults to enabled if we do nothing to it. Of course I put this in because
+ * I want it disabled :P
+ * 1 - enabled (if previously disabled, also default)
+ * 0/2 - disabled 
+ */
+static void psmouse_logitech_sms(struct psmouse *psmouse, unsigned char *param)
+{
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 3;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 2;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	if (psmouse_sms == 1) 
+		param[0] = 1;
+	else if	(psmouse_sms > 2)
+		return;
+	/* else leave param[0] == 0 to disable */
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Support 800 cpi resolution _only_ if the user wants it (there are good reasons
+ * to not use it even if the mouse supports it, and of course there are also good
+ * reasons to use it, let the user decide)
+ */
+static void psmouse_set_resolution(struct psmouse *psmouse, unsigned char *param)
+{
+	param[0] = 3;
+	if (psmouse_res >= 800) {
+	/* setting 400 cpi after doing the follwing enables 800 cpi */
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	} else if (psmouse_res && psmouse_res < 200) {
+		if (psmouse_res >= 100) 
+			param[0] = 2;
+		else if (psmouse_res >= 50)
+			param[0] = 1;
+		else if (psmouse_res)
+			param[0] = 0;
+	}
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
 
@@ -541,11 +654,12 @@
 {
 	unsigned char param[2];
 
+	psmouse_logitech_sms(psmouse, param);
+	
 /*
  * We set the mouse report rate to a highest possible value.
  * We try 100 first in case mouse fails to set 200.
  */
-
 	param[0] = 100;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 
@@ -555,9 +669,7 @@
 /*
  * We also set the resolution and scaling.
  */
-
-	param[0] = 3;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_set_resolution(psmouse, param);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 
 /*
@@ -668,7 +780,23 @@
 	psmouse_noext = 1;
 	return 1;
 }
+
+static int __init psmouse_res_setup(char *str)
+{
+	get_option(&str,&psmouse_res);
+	return 1;
+}
+
+static int __init psmouse_sms_setup(char *str)
+{
+	get_option(&str,&psmouse_sms);
+	return 1;
+}
+
 __setup("psmouse_noext", psmouse_setup);
+__setup("psmouse_res=", psmouse_res_setup);
+__setup("psmouse_sms=", psmouse_sms_setup);
+
 #endif
 
 int __init psmouse_init(void)
include/linux/input.h +5 -0
@@ -355,7 +355,12 @@
 #define BTN_SIDE		0x113
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
+#define BTN_TASK		0x115
 #define BTN_BACK		0x116
+#define BTN_SMSUP		0x116
+#define BTN_SMSDOWN		0x117
+#define BTN_H118		0x118
+#define BTN_H119		0x119
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
Signature · 1 line
Eric Wong
#1 lore raw
Quoted 4 lines · Eric Wong

Updates to the PS/2++ mouse protocol used by Logitech, as well as SMS/Smart Scroll/Cruise Control and 800 cpi resolution control for those who want it. Up to 10 buttons are supported now, although only 8 are used at the moment on the MX500 and MX700.

Going to merge this, but what are the H118 and H119 keys? Also what exactly "SMS" means?

Quoted 238 lines

diff -bruN a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c

drivers/input/mouse/psmouse.c +136 -8
@@ -21,9 +21,17 @@
 MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
 MODULE_DESCRIPTION("PS/2 mouse driver");
 MODULE_PARM(psmouse_noext, "1i");
+MODULE_PARM(psmouse_res, "i");
+MODULE_PARM_DESC(psmouse_res, "resolution, not all mice support all values");
+MODULE_PARM(psmouse_sms, "i");
+MODULE_PARM_DESC(psmouse_sms, "autorepeat, 1 = enabled (default) | 0 = disabled");
 MODULE_LICENSE("GPL");
 
+#define PSMOUSE_LOGITECH_SMS	1
+
 static int psmouse_noext;
+static int psmouse_res;
+static int psmouse_sms = PSMOUSE_LOGITECH_SMS;
 
 #define PSMOUSE_CMD_SETSCALE11	0x00e6
 #define PSMOUSE_CMD_SETRES	0x10e8
@@ -83,8 +91,47 @@
 /*
  * The PS2++ protocol is a little bit complex
  */
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {
 
-	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
+			switch (((packet[1] >> 4) & 0x0f) | (packet[0] & 0x30)) {
+
+			case 0x0d: /* Mouse extra info */
+
+				input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+					(int) (packet[2] & 8) - (int) (packet[2] & 7));
+				input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+
+				break;
+			case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
+
+				input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
+				input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+				input_report_key(dev, BTN_SMSUP, (packet[2] >> 3) & 1);
+				input_report_key(dev, BTN_SMSDOWN, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_H118, (packet[2] >> 5) & 1);
+				input_report_key(dev, BTN_H119, (packet[2] >> 6) & 1);
+
+				break;
+#ifdef DEBUG
+			default:
+				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
+					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
+#endif
+
+			}
+
+		packet[0] &= 0x0f;
+		packet[1] = 0;
+		packet[2] = 0;
+
+		}
+	}
+	
+	if (psmouse->type == PSMOUSE_PS2TPP) {
 
 		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
 
@@ -112,7 +159,6 @@
 				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
 					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
 #endif
-
 			}
 
 		packet[0] &= 0x0f;
@@ -385,9 +431,11 @@
 
 		int i;
 		static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
-		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, -1 };
+		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
 		static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
-							76, 80, 81, 83, 88, 96, 97, -1 };
+							76, 80, 81, 83, 88, 96, 97, 112, -1 };
+		static int logitech_P2[] = { 112, -1 };
+
 		psmouse->vendor = "Logitech";
 		psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
 
@@ -414,6 +462,17 @@
 					psmouse->name = "Wheel Mouse";
 				}
 
+			for (i = 0; logitech_P2[i] != -1; i++)
+				if (logitech_P2[i]  == psmouse->model) {
+					set_bit(BTN_SIDE, psmouse->dev.keybit);
+					set_bit(BTN_EXTRA, psmouse->dev.keybit);
+					set_bit(BTN_TASK, psmouse->dev.keybit);
+					set_bit(BTN_SMSUP, psmouse->dev.keybit);
+					set_bit(BTN_SMSDOWN, psmouse->dev.keybit);
+					set_bit(BTN_H118, psmouse->dev.keybit);
+					set_bit(BTN_H119, psmouse->dev.keybit);
+				}
+
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
  */
@@ -534,6 +593,60 @@
 }
 
 /*
+ * SMS/Smart Scroll/Cruise Control for some newer Logitech mice 
+ * Defaults to enabled if we do nothing to it. Of course I put this in because
+ * I want it disabled :P
+ * 1 - enabled (if previously disabled, also default)
+ * 0/2 - disabled 
+ */
+static void psmouse_logitech_sms(struct psmouse *psmouse, unsigned char *param)
+{
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 3;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 2;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	if (psmouse_sms == 1) 
+		param[0] = 1;
+	else if	(psmouse_sms > 2)
+		return;
+	/* else leave param[0] == 0 to disable */
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Support 800 cpi resolution _only_ if the user wants it (there are good reasons
+ * to not use it even if the mouse supports it, and of course there are also good
+ * reasons to use it, let the user decide)
+ */
+static void psmouse_set_resolution(struct psmouse *psmouse, unsigned char *param)
+{
+	param[0] = 3;
+	if (psmouse_res >= 800) {
+	/* setting 400 cpi after doing the follwing enables 800 cpi */
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	} else if (psmouse_res && psmouse_res < 200) {
+		if (psmouse_res >= 100) 
+			param[0] = 2;
+		else if (psmouse_res >= 50)
+			param[0] = 1;
+		else if (psmouse_res)
+			param[0] = 0;
+	}
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
 
@@ -541,11 +654,12 @@
 {
 	unsigned char param[2];
 
+	psmouse_logitech_sms(psmouse, param);
+	
 /*
  * We set the mouse report rate to a highest possible value.
  * We try 100 first in case mouse fails to set 200.
  */
-
 	param[0] = 100;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 
@@ -555,9 +669,7 @@
 /*
  * We also set the resolution and scaling.
  */
-
-	param[0] = 3;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_set_resolution(psmouse, param);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 
 /*
@@ -668,7 +780,23 @@
 	psmouse_noext = 1;
 	return 1;
 }
+
+static int __init psmouse_res_setup(char *str)
+{
+	get_option(&str,&psmouse_res);
+	return 1;
+}
+
+static int __init psmouse_sms_setup(char *str)
+{
+	get_option(&str,&psmouse_sms);
+	return 1;
+}
+
 __setup("psmouse_noext", psmouse_setup);
+__setup("psmouse_res=", psmouse_res_setup);
+__setup("psmouse_sms=", psmouse_sms_setup);
+
 #endif
 
 int __init psmouse_init(void)
include/linux/input.h +5 -0
@@ -355,7 +355,12 @@
 #define BTN_SIDE		0x113
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
+#define BTN_TASK		0x115
 #define BTN_BACK		0x116
+#define BTN_SMSUP		0x116
+#define BTN_SMSDOWN		0x117
+#define BTN_H118		0x118
+#define BTN_H119		0x119
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
Signature · 2 lines
-- 
Eric Wong
Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR
author
#2 lore raw
Quoted 9 lines · Vojtech Pavlik
Quoted 4 lines · Eric Wong

Updates to the PS/2++ mouse protocol used by Logitech, as well as SMS/Smart Scroll/Cruise Control and 800 cpi resolution control for those who want it. Up to 10 buttons are supported now, although only 8 are used at the moment on the MX500 and MX700.

Going to merge this, but what are the H118 and H119 keys? Also what exactly "SMS" means?

SMS is SMartScroll, the two tiny autoscroll buttons above and below the wheel of the MX500/700. H118 and H119 (I just arbirarily named them) aren't used in any current mice to my knowledge, but are there are bits for them in the new PS/2++ packet for possible future use.

Quoted 242 lines
Quoted 238 lines

diff -bruN a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c

drivers/input/mouse/psmouse.c +136 -8
@@ -21,9 +21,17 @@
 MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
 MODULE_DESCRIPTION("PS/2 mouse driver");
 MODULE_PARM(psmouse_noext, "1i");
+MODULE_PARM(psmouse_res, "i");
+MODULE_PARM_DESC(psmouse_res, "resolution, not all mice support all values");
+MODULE_PARM(psmouse_sms, "i");
+MODULE_PARM_DESC(psmouse_sms, "autorepeat, 1 = enabled (default) | 0 = disabled");
 MODULE_LICENSE("GPL");
 
+#define PSMOUSE_LOGITECH_SMS	1
+
 static int psmouse_noext;
+static int psmouse_res;
+static int psmouse_sms = PSMOUSE_LOGITECH_SMS;
 
 #define PSMOUSE_CMD_SETSCALE11	0x00e6
 #define PSMOUSE_CMD_SETRES	0x10e8
@@ -83,8 +91,47 @@
 /*
  * The PS2++ protocol is a little bit complex
  */
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {
 
-	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
+			switch (((packet[1] >> 4) & 0x0f) | (packet[0] & 0x30)) {
+
+			case 0x0d: /* Mouse extra info */
+
+				input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+					(int) (packet[2] & 8) - (int) (packet[2] & 7));
+				input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+
+				break;
+			case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
+
+				input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
+				input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+				input_report_key(dev, BTN_SMSUP, (packet[2] >> 3) & 1);
+				input_report_key(dev, BTN_SMSDOWN, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_H118, (packet[2] >> 5) & 1);
+				input_report_key(dev, BTN_H119, (packet[2] >> 6) & 1);
+
+				break;
+#ifdef DEBUG
+			default:
+				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
+					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
+#endif
+
+			}
+
+		packet[0] &= 0x0f;
+		packet[1] = 0;
+		packet[2] = 0;
+
+		}
+	}
+	
+	if (psmouse->type == PSMOUSE_PS2TPP) {
 
 		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
 
@@ -112,7 +159,6 @@
 				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
 					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
 #endif
-
 			}
 
 		packet[0] &= 0x0f;
@@ -385,9 +431,11 @@
 
 		int i;
 		static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
-		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, -1 };
+		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
 		static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
-							76, 80, 81, 83, 88, 96, 97, -1 };
+							76, 80, 81, 83, 88, 96, 97, 112, -1 };
+		static int logitech_P2[] = { 112, -1 };
+
 		psmouse->vendor = "Logitech";
 		psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
 
@@ -414,6 +462,17 @@
 					psmouse->name = "Wheel Mouse";
 				}
 
+			for (i = 0; logitech_P2[i] != -1; i++)
+				if (logitech_P2[i]  == psmouse->model) {
+					set_bit(BTN_SIDE, psmouse->dev.keybit);
+					set_bit(BTN_EXTRA, psmouse->dev.keybit);
+					set_bit(BTN_TASK, psmouse->dev.keybit);
+					set_bit(BTN_SMSUP, psmouse->dev.keybit);
+					set_bit(BTN_SMSDOWN, psmouse->dev.keybit);
+					set_bit(BTN_H118, psmouse->dev.keybit);
+					set_bit(BTN_H119, psmouse->dev.keybit);
+				}
+
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
  */
@@ -534,6 +593,60 @@
 }
 
 /*
+ * SMS/Smart Scroll/Cruise Control for some newer Logitech mice 
+ * Defaults to enabled if we do nothing to it. Of course I put this in because
+ * I want it disabled :P
+ * 1 - enabled (if previously disabled, also default)
+ * 0/2 - disabled 
+ */
+static void psmouse_logitech_sms(struct psmouse *psmouse, unsigned char *param)
+{
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 3;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 2;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	if (psmouse_sms == 1) 
+		param[0] = 1;
+	else if	(psmouse_sms > 2)
+		return;
+	/* else leave param[0] == 0 to disable */
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Support 800 cpi resolution _only_ if the user wants it (there are good reasons
+ * to not use it even if the mouse supports it, and of course there are also good
+ * reasons to use it, let the user decide)
+ */
+static void psmouse_set_resolution(struct psmouse *psmouse, unsigned char *param)
+{
+	param[0] = 3;
+	if (psmouse_res >= 800) {
+	/* setting 400 cpi after doing the follwing enables 800 cpi */
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+		psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	} else if (psmouse_res && psmouse_res < 200) {
+		if (psmouse_res >= 100) 
+			param[0] = 2;
+		else if (psmouse_res >= 50)
+			param[0] = 1;
+		else if (psmouse_res)
+			param[0] = 0;
+	}
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
 
@@ -541,11 +654,12 @@
 {
 	unsigned char param[2];
 
+	psmouse_logitech_sms(psmouse, param);
+	
 /*
  * We set the mouse report rate to a highest possible value.
  * We try 100 first in case mouse fails to set 200.
  */
-
 	param[0] = 100;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 
@@ -555,9 +669,7 @@
 /*
  * We also set the resolution and scaling.
  */
-
-	param[0] = 3;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_set_resolution(psmouse, param);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 
 /*
@@ -668,7 +780,23 @@
 	psmouse_noext = 1;
 	return 1;
 }
+
+static int __init psmouse_res_setup(char *str)
+{
+	get_option(&str,&psmouse_res);
+	return 1;
+}
+
+static int __init psmouse_sms_setup(char *str)
+{
+	get_option(&str,&psmouse_sms);
+	return 1;
+}
+
 __setup("psmouse_noext", psmouse_setup);
+__setup("psmouse_res=", psmouse_res_setup);
+__setup("psmouse_sms=", psmouse_sms_setup);
+
 #endif
 
 int __init psmouse_init(void)
include/linux/input.h +5 -0
@@ -355,7 +355,12 @@
 #define BTN_SIDE		0x113
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
+#define BTN_TASK		0x115
 #define BTN_BACK		0x116
+#define BTN_SMSUP		0x116
+#define BTN_SMSDOWN		0x117
+#define BTN_H118		0x118
+#define BTN_H119		0x119
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
Signature · 2 lines
-- 
Eric Wong
Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR
Signature · 1 line
Eric Wong
#3 lore raw
Quoted 8 lines · Eric Wong
Quoted 7 lines · Vojtech Pavlik
Quoted 4 lines · Eric Wong

Updates to the PS/2++ mouse protocol used by Logitech, as well as SMS/Smart Scroll/Cruise Control and 800 cpi resolution control for those who want it. Up to 10 buttons are supported now, although only 8 are used at the moment on the MX500 and MX700.

Quoted 7 lines
Quoted 2 lines

Going to merge this, but what are the H118 and H119 keys? Also what exactly "SMS" means?

SMS is SMartScroll, the two tiny autoscroll buttons above and below the wheel of the MX500/700. H118 and H119 (I just arbirarily named them) aren't used in any current mice to my knowledge, but are there are bits for them in the new PS/2++ packet for possible future use.

Ok. How about these two patches against 2.5.71? Your changes are merged into the second one.

Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR

You can pull this changeset from:
bk://kernel.bkbits.net/vojtech/input

===================================================================

[email protected], 2003-06-14 18:33:19+02:00, [email protected]
input: Add Synaptics touchpad absolute mode support.

 b/drivers/input/mouse/Kconfig        |   13 
 b/drivers/input/mouse/Makefile       |    5 
 b/drivers/input/mouse/psmouse-base.c |  661 +++++++++++++++++++++++++++++++++
 b/drivers/input/mouse/psmouse.h      |   49 ++
 b/drivers/input/mouse/synaptics.c    |  390 +++++++++++++++++++
 b/drivers/input/mouse/synaptics.h    |  105 +++++
 b/include/linux/input.h              |    1 
 drivers/input/mouse/psmouse.c        |  689 -----------------------------------
 8 files changed, 1224 insertions(+), 689 deletions(-)

===================================================================

drivers/input/mouse/Kconfig +13 -0
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
@@ -28,6 +28,19 @@
 	  The module will be called psmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
+config MOUSE_PS2_SYNAPTICS
+	bool "Synaptics TouchPad"
+	default n
+	depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
+	---help---
+	  Say Y here if you have a Synaptics TouchPad connected to your system.
+	  This touchpad is found on many modern laptop computers.
+	  Note that you also need a user space driver to interpret the data
+	  generated by the kernel. A compatible driver for XFree86 is available
+	  from http://...
+
+	  If unsure, say Y.
+
 config MOUSE_SERIAL
 	tristate "Serial mouse"
 	depends on INPUT && INPUT_MOUSE && SERIO
drivers/input/mouse/Makefile +5 -0
diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
@@ -13,3 +13,8 @@
 obj-$(CONFIG_MOUSE_PC9800)	+= 98busmouse.o
 obj-$(CONFIG_MOUSE_PS2)		+= psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
+
+psmouse-objs  := psmouse-base.o
+ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
+        psmouse-objs += synaptics.o
+endif
drivers/input/mouse/psmouse-base.c new file +661 -0

661 lines not on this page · raw message

drivers/input/mouse/psmouse.c deleted +0 -689

689 lines not on this page · raw message

drivers/input/mouse/psmouse.h new file +49 -0

49 lines not on this page · raw message

drivers/input/mouse/synaptics.c new file +390 -0

390 lines not on this page · raw message

drivers/input/mouse/synaptics.h new file +105 -0

105 lines not on this page · raw message

include/linux/input.h +1 -0
diff -Nru a/include/linux/input.h b/include/linux/input.h
@@ -530,6 +530,7 @@
 
 #define MSC_SERIAL		0x00
 #define MSC_PULSELED		0x01
+#define MSC_GESTURE		0x02
 #define MSC_MAX			0x07
 
 /*

You can pull this changeset from:
bk://kernel.bkbits.net/vojtech/input

===================================================================

[email protected], 2003-06-15 10:35:42+02:00, [email protected]
input: Add Logitech MX PS2++ support, move Logitech PS2++ code to a separate source file, always enable Synaptics support.

 drivers/input/mouse/Kconfig        |   15 --
 drivers/input/mouse/Makefile       |    5 
 drivers/input/mouse/logips2pp.c    |  231 +++++++++++++++++++++++++++++++++++++
 drivers/input/mouse/logips2pp.h    |   17 ++
 drivers/input/mouse/psmouse-base.c |  193 +++++++++---------------------
 drivers/input/mouse/psmouse.h      |    2 
 include/linux/input.h              |    1 
 7 files changed, 313 insertions(+), 151 deletions(-)

===================================================================

drivers/input/mouse/Kconfig +1 -14
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
@@ -19,7 +19,7 @@
 	  Say Y here if you have a PS/2 mouse connected to your system. This
 	  includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
 	  mice with wheels and extra buttons, Microsoft, Logitech or Genius
-	  compatible.
+	  compatible. Support for Synaptics TouchPads is also included.
 
 	  If unsure, say Y.
 
@@ -27,19 +27,6 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  The module will be called psmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
-
-config MOUSE_PS2_SYNAPTICS
-	bool "Synaptics TouchPad"
-	default n
-	depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
-	---help---
-	  Say Y here if you have a Synaptics TouchPad connected to your system.
-	  This touchpad is found on many modern laptop computers.
-	  Note that you also need a user space driver to interpret the data
-	  generated by the kernel. A compatible driver for XFree86 is available
-	  from http://...
-
-	  If unsure, say Y.
 
 config MOUSE_SERIAL
 	tristate "Serial mouse"
drivers/input/mouse/Makefile +1 -4
diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
@@ -14,7 +14,4 @@
 obj-$(CONFIG_MOUSE_PS2)		+= psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 
-psmouse-objs  := psmouse-base.o
-ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
-        psmouse-objs += synaptics.o
-endif
+psmouse-objs  := psmouse-base.o logips2pp.o synaptics.o
drivers/input/mouse/logips2pp.c new file +231 -0

231 lines not on this page · raw message

drivers/input/mouse/logips2pp.h new file +17 -0
diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
@@ -0,0 +1,17 @@
+/*
+ * Logitech PS/2++ mouse driver header
+ *
+ * Copyright (c) 2003 Vojtech Pavlik <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _LOGIPS2PP_H
+#define _LOGIPS2PP_H
+struct psmouse;
+void ps2pp_process_packet(struct psmouse *psmouse);
+void ps2pp_set_800dpi(struct psmouse *psmouse);
+int ps2pp_detect_model(struct psmouse *psmouse);
+#endif
drivers/input/mouse/psmouse-base.c +60 -133

255 lines not on this page · raw message

drivers/input/mouse/psmouse.h +2 -0
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
@@ -46,4 +46,6 @@
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
 
+extern int psmouse_smartscroll;
+
 #endif /* _PSMOUSE_H */
include/linux/input.h +1 -0
diff -Nru a/include/linux/input.h b/include/linux/input.h
@@ -358,6 +358,7 @@
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
 #define BTN_BACK		0x116
+#define BTN_TASK		0x117
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
author
#4 lore raw
Quoted 6 lines · Vojtech Pavlik
Quoted 2 lines · Eric Wong
Quoted 1 line · Vojtech Pavlik

On Tue, Mar 25, 2003 at 06:55:38PM -0800, Eric Wong wrote:

Ok. How about these two patches against 2.5.71? Your changes are merged into the second one.

Took a few days to find that little PS/2 adapter that came with my mouse, moving sucks :(

Two errors I fixed:
1. ps2pp_detect_model needs the *param argument
2. ps2pp_set_smartscroll only works after the Magic Knock has inititialized it
3. Unrelated to PS2++, remove the CONFIG_MOUSE_PS2_SYNAPTICS check in synaptics.h since it's enabled by default.

I've updated the patch and rediffed against 2.5.72, see attachment.

Signature · 1 line
Eric Wong
drivers/input/mouse/Kconfig +1 -14
diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/Kconfig linux-2.5.72-np2/drivers/input/mouse/Kconfig
@@ -19,7 +19,7 @@ config MOUSE_PS2
 	  Say Y here if you have a PS/2 mouse connected to your system. This
 	  includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
 	  mice with wheels and extra buttons, Microsoft, Logitech or Genius
-	  compatible.
+	  compatible. Support for Synaptics TouchPads is also included.
 
 	  If unsure, say Y.
 
@@ -28,19 +28,6 @@ config MOUSE_PS2
 	  The module will be called psmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
-config MOUSE_PS2_SYNAPTICS
-	bool "Synaptics TouchPad"
-	default n
-	depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
-	---help---
-	  Say Y here if you have a Synaptics TouchPad connected to your system.
-	  This touchpad is found on many modern laptop computers.
-	  Note that you also need a user space driver to interpret the data
-	  generated by the kernel. A compatible driver for XFree86 is available
-	  from http://...
-
-	  If unsure, say Y.
-
 config MOUSE_SERIAL
 	tristate "Serial mouse"
 	depends on INPUT && INPUT_MOUSE && SERIO
drivers/input/mouse/Makefile +1 -4
diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/Makefile linux-2.5.72-np2/drivers/input/mouse/Makefile
@@ -14,7 +14,4 @@ obj-$(CONFIG_MOUSE_PC9800)	+= 98busmouse
 obj-$(CONFIG_MOUSE_PS2)		+= psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 
-psmouse-objs  := psmouse-base.o
-ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
-        psmouse-objs += synaptics.o
-endif
+psmouse-objs  := psmouse-base.o logips2pp.o synaptics.o
drivers/input/mouse/logips2pp.c +228 -0

228 lines not on this page · raw message

drivers/input/mouse/logips2pp.h +17 -0
diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/logips2pp.h linux-2.5.72-np2/drivers/input/mouse/logips2pp.h
@@ -0,0 +1,17 @@
+/*
+ * Logitech PS/2++ mouse driver header
+ *
+ * Copyright (c) 2003 Vojtech Pavlik <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _LOGIPS2PP_H
+#define _LOGIPS2PP_H
+struct psmouse;
+void ps2pp_process_packet(struct psmouse *psmouse);
+void ps2pp_set_800dpi(struct psmouse *psmouse);
+int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param);
+#endif
drivers/input/mouse/psmouse-base.c +60 -133

255 lines not on this page · raw message

drivers/input/mouse/psmouse.h +2 -0
diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/psmouse.h linux-2.5.72-np2/drivers/input/mouse/psmouse.h
@@ -46,4 +46,6 @@ struct psmouse {
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
 
+extern int psmouse_smartscroll;
+
 #endif /* _PSMOUSE_H */
drivers/input/mouse/synaptics.h +0 -11
diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/synaptics.h linux-2.5.72-np2/drivers/input/mouse/synaptics.h
@@ -9,21 +9,10 @@
 #ifndef _SYNAPTICS_H
 #define _SYNAPTICS_H
 
-#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
-
 extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
 extern int synaptics_init(struct psmouse *psmouse);
 extern void synaptics_disconnect(struct psmouse *psmouse);
 
-#else
-
-static inline void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) {}
-static inline int synaptics_init(struct psmouse *psmouse) { return -1; }
-static inline void synaptics_disconnect(struct psmouse *psmouse) {}
-
-#endif
-
-
 /* synaptics queries */
 #define SYN_QUE_IDENTIFY		0x00
 #define SYN_QUE_MODES			0x01
include/linux/input.h +1 -0
diff -ruNp linux-2.5.72-vanilla/include/linux/input.h linux-2.5.72-np2/include/linux/input.h
@@ -358,6 +358,7 @@ struct input_absinfo {
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
 #define BTN_BACK		0x116
+#define BTN_TASK		0x117
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
#5 lore raw
Quoted 11 lines · Eric Wong
Quoted 6 lines · Vojtech Pavlik
Quoted 2 lines · Eric Wong
Quoted 1 line · Vojtech Pavlik

On Tue, Mar 25, 2003 at 06:55:38PM -0800, Eric Wong wrote:

Ok. How about these two patches against 2.5.71? Your changes are merged into the second one.

Took a few days to find that little PS/2 adapter that came with my mouse, moving sucks :(

Quoted 7 lines

Two errors I fixed:
1. ps2pp_detect_model needs the *param argument
2. ps2pp_set_smartscroll only works after the Magic Knock has inititialized it
3. Unrelated to PS2++, remove the CONFIG_MOUSE_PS2_SYNAPTICS check in synaptics.h since it's enabled by default.

I've updated the patch and rediffed against 2.5.72, see attachment.

Thanks, I merged the fixes into my kernel tree.

Quoted 609 lines

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/Kconfig linux-2.5.72-np2/drivers/input/mouse/Kconfig

drivers/input/mouse/Kconfig +1 -14
@@ -19,7 +19,7 @@ config MOUSE_PS2
 	  Say Y here if you have a PS/2 mouse connected to your system. This
 	  includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
 	  mice with wheels and extra buttons, Microsoft, Logitech or Genius
-	  compatible.
+	  compatible. Support for Synaptics TouchPads is also included.
 
 	  If unsure, say Y.
 
@@ -28,19 +28,6 @@ config MOUSE_PS2
 	  The module will be called psmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
-config MOUSE_PS2_SYNAPTICS
-	bool "Synaptics TouchPad"
-	default n
-	depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
-	---help---
-	  Say Y here if you have a Synaptics TouchPad connected to your system.
-	  This touchpad is found on many modern laptop computers.
-	  Note that you also need a user space driver to interpret the data
-	  generated by the kernel. A compatible driver for XFree86 is available
-	  from http://...
-
-	  If unsure, say Y.
-
 config MOUSE_SERIAL
 	tristate "Serial mouse"
 	depends on INPUT && INPUT_MOUSE && SERIO

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/Makefile linux-2.5.72-np2/drivers/input/mouse/Makefile

drivers/input/mouse/Makefile +1 -4
@@ -14,7 +14,4 @@ obj-$(CONFIG_MOUSE_PC9800)	+= 98busmouse
 obj-$(CONFIG_MOUSE_PS2)		+= psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 
-psmouse-objs  := psmouse-base.o
-ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
-        psmouse-objs += synaptics.o
-endif
+psmouse-objs  := psmouse-base.o logips2pp.o synaptics.o

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/logips2pp.c linux-2.5.72-np2/drivers/input/mouse/logips2pp.c

drivers/input/mouse/logips2pp.c +228 -0
@@ -0,0 +1,228 @@
+/*
+ * Logitech PS/2++ mouse driver
+ *
+ * Copyright (c) 1999-2003 Vojtech Pavlik <[email protected]>
+ * Copyright (c) 2003 Eric Wong <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+#include "psmouse.h"
+#include "logips2pp.h"
+
+/*
+ * Process a PS2++ or PS2T++ packet.
+ */
+
+void ps2pp_process_packet(struct psmouse *psmouse)
+{
+	struct input_dev *dev = &psmouse->dev;
+        unsigned char *packet = psmouse->packet;
+
+	if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {
+
+		switch ((packet[1] >> 4) | (packet[0] & 0x30)) {
+
+			case 0x0d: /* Mouse extra info */
+
+				input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+					(int) (packet[2] & 8) - (int) (packet[2] & 7));
+				input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+
+				break;
+
+			case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
+
+				input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
+				input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
+				input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1);
+				input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1);
+				input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+
+				break;
+
+			case 0x0f: /* TouchPad extra info */
+
+				input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
+					(int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
+				packet[0] = packet[2] | 0x08;
+				break;
+
+#ifdef DEBUG
+			default:
+				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
+					(packet[1] >> 4) | (packet[0] & 0x30));
+#endif
+		}
+
+		packet[0] &= 0x0f;
+		packet[1] = 0;
+		packet[2] = 0;
+
+	}
+}
+
+/*
+ * ps2pp_cmd() sends a PS2++ command, sliced into two bit
+ * pieces through the SETRES command. This is needed to send extended
+ * commands to mice on notebooks that try to understand the PS/2 protocol
+ * Ugly.
+ */
+
+static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
+{
+	unsigned char d;
+	int i;
+
+	if (psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11))
+		return -1;
+
+	for (i = 6; i >= 0; i -= 2) {
+		d = (command >> i) & 3;
+		if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+			return -1;
+	}
+
+	if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * SmartScroll / CruiseControl for some newer Logitech mice Defaults to
+ * enabled if we do nothing to it. Of course I put this in because I want it
+ * disabled :P
+ * 1 - enabled (if previously disabled, also default)
+ * 0/2 - disabled 
+ */
+
+static void ps2pp_set_smartscroll(struct psmouse *psmouse)
+{
+	unsigned char param[4];
+
+	ps2pp_cmd(psmouse, param, 0x32);
+
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+
+	if (psmouse_smartscroll == 1) 
+		param[0] = 1;
+	else
+	if (psmouse_smartscroll > 2)
+		return;
+
+	/* else leave param[0] == 0 to disable */
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Support 800 dpi resolution _only_ if the user wants it (there are good
+ * reasons to not use it even if the mouse supports it, and of course there are
+ * also good reasons to use it, let the user decide).
+ */
+
+void ps2pp_set_800dpi(struct psmouse *psmouse)
+{
+	unsigned char param = 3;
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+	psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
+ * touchpad.
+ */
+
+int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+{
+	int i;
+	static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
+	static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
+	static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
+						76, 80, 81, 83, 88, 96, 97, 112, -1 };
+	static int logitech_mx[] = { 112, -1 };
+
+	psmouse->vendor = "Logitech";
+	psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+
+	if (param[1] < 3)
+		clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+	if (param[1] < 2)
+		clear_bit(BTN_RIGHT, psmouse->dev.keybit);
+
+	psmouse->type = PSMOUSE_PS2;
+
+	for (i = 0; logitech_ps2pp[i] != -1; i++)
+		if (logitech_ps2pp[i] == psmouse->model)
+			psmouse->type = PSMOUSE_PS2PP;
+
+	if (psmouse->type == PSMOUSE_PS2PP) {
+
+		for (i = 0; logitech_4btn[i] != -1; i++)
+			if (logitech_4btn[i] == psmouse->model)
+				set_bit(BTN_SIDE, psmouse->dev.keybit);
+
+		for (i = 0; logitech_wheel[i] != -1; i++)
+			if (logitech_wheel[i] == psmouse->model) {
+				set_bit(REL_WHEEL, psmouse->dev.relbit);
+				psmouse->name = "Wheel Mouse";
+			}
+
+		for (i = 0; logitech_mx[i] != -1; i++)
+			if (logitech_mx[i]  == psmouse->model) {
+				set_bit(BTN_SIDE, psmouse->dev.keybit);
+				set_bit(BTN_EXTRA, psmouse->dev.keybit);
+				set_bit(BTN_BACK, psmouse->dev.keybit);
+				set_bit(BTN_FORWARD, psmouse->dev.keybit);
+				set_bit(BTN_TASK, psmouse->dev.keybit);
+				psmouse->name = "MX Mouse";
+			}
+
+/*
+ * Do Logitech PS2++ / PS2T++ magic init.
+ */
+
+		if (psmouse->model == 97) { /* TouchPad 3 */
+
+			set_bit(REL_WHEEL, psmouse->dev.relbit);
+			set_bit(REL_HWHEEL, psmouse->dev.relbit);
+
+			param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
+			psmouse_command(psmouse, param, 0x30d1);
+			param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
+			psmouse_command(psmouse, param, 0x30d1);
+			param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
+			psmouse_command(psmouse, param, 0x30d1);
+
+			param[0] = 0;
+			if (!psmouse_command(psmouse, param, 0x13d1) &&
+				param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+				psmouse->name = "TouchPad 3";
+				return PSMOUSE_PS2TPP;
+			}
+
+		} else {
+			param[0] = param[1] = param[2] = 0;
+
+			ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
+			ps2pp_cmd(psmouse, param, 0xDB);
+
+			ps2pp_set_smartscroll(psmouse);
+
+			if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
+				(param[2] & 3) == ((param[1] >> 2) & 3))
+					return PSMOUSE_PS2PP;
+		}
+	}
+
+	return 0;
+}

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/logips2pp.h linux-2.5.72-np2/drivers/input/mouse/logips2pp.h

drivers/input/mouse/logips2pp.h +17 -0
@@ -0,0 +1,17 @@
+/*
+ * Logitech PS/2++ mouse driver header
+ *
+ * Copyright (c) 2003 Vojtech Pavlik <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _LOGIPS2PP_H
+#define _LOGIPS2PP_H
+struct psmouse;
+void ps2pp_process_packet(struct psmouse *psmouse);
+void ps2pp_set_800dpi(struct psmouse *psmouse);
+int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param);
+#endif

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/psmouse-base.c linux-2.5.72-np2/drivers/input/mouse/psmouse-base.c

drivers/input/mouse/psmouse-base.c +60 -133
@@ -19,13 +19,23 @@
 #include <linux/init.h>
 #include "psmouse.h"
 #include "synaptics.h"
+#include "logips2pp.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
 MODULE_DESCRIPTION("PS/2 mouse driver");
 MODULE_PARM(psmouse_noext, "1i");
+MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
+MODULE_PARM(psmouse_resolution, "i");
+MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+MODULE_PARM(psmouse_smartscroll, "i");
+MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 MODULE_LICENSE("GPL");
 
+#define PSMOUSE_LOGITECH_SMARTSCROLL	1
+
 static int psmouse_noext;
+int psmouse_resolution;
+int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
 
 static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "Synaptics"};
 
@@ -45,43 +55,8 @@ static void psmouse_process_packet(struc
  * The PS2++ protocol is a little bit complex
  */
 
-	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
-
-		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
-
-			switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)) {
-
-			case 1: /* Mouse extra info */
-
-				input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
-					(int) (packet[2] & 8) - (int) (packet[2] & 7));
-				input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
-				input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
-					
-				break;
-
-			case 3: /* TouchPad extra info */
-
-				input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
-					(int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
-				packet[0] = packet[2] | 0x08;
-
-				break;
-
-#ifdef DEBUG
-			default:
-				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
-					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
-#endif
-
-			}
-
-		packet[0] &= 0x0f;
-		packet[1] = 0;
-		packet[2] = 0;
-
-		}
-	}
+	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP)
+		ps2pp_process_packet(psmouse);
 
 /*
  * Scroll wheel on IntelliMice, scroll buttons on NetMice
@@ -259,33 +234,6 @@ int psmouse_command(struct psmouse *psmo
 }
 
 /*
- * psmouse_ps2pp_cmd() sends a PS2++ command, sliced into two bit
- * pieces through the SETRES command. This is needed to send extended
- * commands to mice on notebooks that try to understand the PS/2 protocol
- * Ugly.
- */
-
-static int psmouse_ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
-{
-	unsigned char d;
-	int i;
-
-	if (psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11))
-		return -1;
-
-	for (i = 6; i >= 0; i -= 2) {
-		d = (command >> i) & 3;
-		if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
-			return -1;
-	}
-
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
-		return -1;
-
-	return 0;
-}
-
-/*
  * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
  * the mouse may have.
  */
@@ -353,73 +301,13 @@ static int psmouse_extensions(struct psm
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	param[1] = 0;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
 
 	if (param[1]) {
-
-		int i;
-		static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
-		static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, -1 };
-		static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
-							76, 80, 81, 83, 88, 96, 97, -1 };
-		psmouse->vendor = "Logitech";
-		psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
-
-		if (param[1] < 3)
-			clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
-		if (param[1] < 2)
-			clear_bit(BTN_RIGHT, psmouse->dev.keybit);
-
-		psmouse->type = PSMOUSE_PS2;
-
-		for (i = 0; logitech_ps2pp[i] != -1; i++)
-			if (logitech_ps2pp[i] == psmouse->model)
-				psmouse->type = PSMOUSE_PS2PP;
-
-		if (psmouse->type == PSMOUSE_PS2PP) {
-
-			for (i = 0; logitech_4btn[i] != -1; i++)
-				if (logitech_4btn[i] == psmouse->model)
-					set_bit(BTN_SIDE, psmouse->dev.keybit);
-
-			for (i = 0; logitech_wheel[i] != -1; i++)
-				if (logitech_wheel[i] == psmouse->model) {
-					set_bit(REL_WHEEL, psmouse->dev.relbit);
-					psmouse->name = "Wheel Mouse";
-				}
-
-/*
- * Do Logitech PS2++ / PS2T++ magic init.
- */
-
-			if (psmouse->model == 97) { /* TouchPad 3 */
-
-				set_bit(REL_WHEEL, psmouse->dev.relbit);
-				set_bit(REL_HWHEEL, psmouse->dev.relbit);
-
-				param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
-				psmouse_command(psmouse, param, 0x30d1);
-				param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
-				psmouse_command(psmouse, param, 0x30d1);
-				param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
-				psmouse_command(psmouse, param, 0x30d1);
-
-				param[0] = 0;
-				if (!psmouse_command(psmouse, param, 0x13d1) &&
-					param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14)
-					return PSMOUSE_PS2TPP;
-
-			} else {
-				param[0] = param[1] = param[2] = 0;
-
-				psmouse_ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
-				psmouse_ps2pp_cmd(psmouse, param, 0xDB);
-
-				if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
-					(param[2] & 3) == ((param[1] >> 2) & 3))
-						return PSMOUSE_PS2PP;
-			}
-		}
+		int type = ps2pp_detect_model(psmouse, param);
+		if (type)
+			return type;
 	}
 
 /*
@@ -508,6 +396,31 @@ static int psmouse_probe(struct psmouse 
 }
 
 /*
+ * Here we set the mouse resolution.
+ */
+
+static void psmouse_set_resolution(struct psmouse *psmouse)
+{
+	unsigned char param[1];
+
+	if (psmouse->type == PSMOUSE_PS2PP && psmouse_resolution > 400) {
+		ps2pp_set_800dpi(psmouse);
+		return;
+	}
+
+	if (!psmouse_resolution || psmouse_resolution >= 200)
+		param[0] = 3;
+	else if (psmouse_resolution >= 100)
+		param[0] = 2;
+	else if (psmouse_resolution >= 50)
+		param[0] = 1;
+	else if (psmouse_resolution)
+		param[0] = 0;
+
+        psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
 
@@ -519,7 +432,6 @@ static void psmouse_initialize(struct ps
  * We set the mouse report rate to a highest possible value.
  * We try 100 first in case mouse fails to set 200.
  */
-
 	param[0] = 100;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 
@@ -530,8 +442,7 @@ static void psmouse_initialize(struct ps
  * We also set the resolution and scaling.
  */
 
-	param[0] = 3;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_set_resolution(psmouse);
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 
 /*
@@ -638,12 +549,28 @@ static struct serio_dev psmouse_dev = {
 };
 
 #ifndef MODULE
-static int __init psmouse_setup(char *str)
+static int __init psmouse_noext_setup(char *str)
 {
 	psmouse_noext = 1;
 	return 1;
 }
-__setup("psmouse_noext", psmouse_setup);
+
+static int __init psmouse_resolution_setup(char *str)
+{
+	get_option(&str, &psmouse_resolution);
+	return 1;
+}
+
+static int __init psmouse_smartscroll_setup(char *str)
+{
+	get_option(&str, &psmouse_smartscroll);
+	return 1;
+}
+
+__setup("psmouse_noext", psmouse_noext_setup);
+__setup("psmouse_res=", psmouse_resolution_setup);
+__setup("psmouse_sms=", psmouse_smartscroll_setup);
+
 #endif
 
 int __init psmouse_init(void)

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/psmouse.h linux-2.5.72-np2/drivers/input/mouse/psmouse.h

drivers/input/mouse/psmouse.h +2 -0
@@ -46,4 +46,6 @@ struct psmouse {
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
 
+extern int psmouse_smartscroll;
+
 #endif /* _PSMOUSE_H */

diff -ruNp linux-2.5.72-vanilla/drivers/input/mouse/synaptics.h linux-2.5.72-np2/drivers/input/mouse/synaptics.h

drivers/input/mouse/synaptics.h +0 -11
@@ -9,21 +9,10 @@
 #ifndef _SYNAPTICS_H
 #define _SYNAPTICS_H
 
-#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
-
 extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
 extern int synaptics_init(struct psmouse *psmouse);
 extern void synaptics_disconnect(struct psmouse *psmouse);
 
-#else
-
-static inline void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) {}
-static inline int synaptics_init(struct psmouse *psmouse) { return -1; }
-static inline void synaptics_disconnect(struct psmouse *psmouse) {}
-
-#endif
-
-
 /* synaptics queries */
 #define SYN_QUE_IDENTIFY		0x00
 #define SYN_QUE_MODES			0x01

diff -ruNp linux-2.5.72-vanilla/include/linux/input.h linux-2.5.72-np2/include/linux/input.h

include/linux/input.h +1 -0
@@ -358,6 +358,7 @@ struct input_absinfo {
 #define BTN_EXTRA		0x114
 #define BTN_FORWARD		0x115
 #define BTN_BACK		0x116
+#define BTN_TASK		0x117
 
 #define BTN_JOYSTICK		0x120
 #define BTN_TRIGGER		0x120
Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR
#6 lore raw
In reply to Eric Wong
Quoted 4 lines · Eric Wong

Updates to the PS/2++ mouse protocol used by Logitech, as well as SMS/Smart Scroll/Cruise Control and 800 cpi resolution control for those who want it. Up to 10 buttons are supported now, although only 8 are used at the moment on the MX500 and MX700.

Nice.

drivers/input/mouse/psmouse.c line 96

Quoted 7 lines

/*
* The PS2++ protocol is a little bit complex
*/

drivers/input/mouse/psmouse.c +3 -0
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {

Hmm, is this change needed? This

if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {

condition is from Logitech docs and should work with any PS2PP device. It doesn't with yours?

Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR
#7 lore raw
Quoted 11 lines · Vojtech Pavlik

drivers/input/mouse/psmouse.c line 96

Quoted 7 lines · Eric Wong

/*
* The PS2++ protocol is a little bit complex
*/

drivers/input/mouse/psmouse.c +3 -0
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {

Hmm, is this change needed? This

Quoted 4 lines

if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {

condition is from Logitech docs and should work with any PS2PP device. It doesn't with yours?

The updated PS2PP uses 6 bits to determine packet-type instead of 4 as used previously, so compatibility with the touchpad protocol was broken if I recall correctly.

NEW (6 t bits):
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

packet0   E    1   t5   t4    1    M    R    L   
packet1  t3   t2   t1   t0   d2   d1    1    0  
packet2  d8   d7   d6   d5   d4   d3   d2   d1 

OLD (4 t bits)
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

packet0   E    1   t3   t2    1    M    R    L   
packet1   ?    ?   t1   t0   d2   d1    1    0  
packet2  d8   d7   d6   d5   d4   d3   d2   d1 

E is set if it's an external device

Signature · 1 line
Eric Wong
#8 lore raw
Quoted 27 lines · Eric Wong
Quoted 11 lines · Vojtech Pavlik

drivers/input/mouse/psmouse.c line 96

Quoted 7 lines · Eric Wong

/*
* The PS2++ protocol is a little bit complex
*/

drivers/input/mouse/psmouse.c +3 -0
+	if (psmouse->type == PSMOUSE_PS2PP) { 
+
+		if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02 ) {

Hmm, is this change needed? This

Quoted 4 lines

if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {

condition is from Logitech docs and should work with any PS2PP device. It doesn't with yours?

The updated PS2PP uses 6 bits to determine packet-type instead of 4 as used previously, so compatibility with the touchpad protocol was broken if I recall correctly.

NEW (6 t bits):
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

packet0   E    1   t5   t4    1    M    R    L   
packet1  t3   t2   t1   t0   d2   d1    1    0  
packet2  d8   d7   d6   d5   d4   d3   d2   d1 
Quoted 7 lines

OLD (4 t bits)
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

packet0   E    1   t3   t2    1    M    R    L   
packet1   ?    ?   t1   t0   d2   d1    1    0  
packet2  d8   d7   d6   d5   d4   d3   d2   d1 

E is set if it's an external device

Thanks for the info. I didn't expect Logitech to ever need more than 16 special packets bits.

Signature · 2 lines
Vojtech Pavlik
SuSE Labs, SuSE CR