2003-06-21 13:39:54

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 1/11] input: HID devices can have the same logical max and min

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

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

[email protected], 2003-06-21 04:32:06-07:00, [email protected]
input: logical maximum and minimum can have the same value in HID.


hid-core.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Sat Jun 21 15:24:52 2003
+++ b/drivers/usb/input/hid-core.c Sat Jun 21 15:24:52 2003
@@ -215,7 +215,7 @@
return -1;
}

- if (parser->global.logical_maximum <= parser->global.logical_minimum) {
+ if (parser->global.logical_maximum < parser->global.logical_minimum) {
dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
return -1;
}


2003-06-21 13:38:07

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 7/11] input: Fixes for the uinput userspace

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

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

[email protected], 2003-06-21 04:43:13-07:00, [email protected]
input: Three fixes for the uinput userspace input device driver.


uinput.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c Sat Jun 21 15:25:36 2003
+++ b/drivers/input/misc/uinput.c Sat Jun 21 15:25:36 2003
@@ -49,11 +49,11 @@

udev = (struct uinput_device *)dev->private;

- udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
udev->buff[udev->head].type = type;
udev->buff[udev->head].code = code;
udev->buff[udev->head].value = value;
do_gettimeofday(&udev->buff[udev->head].time);
+ udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;

wake_up_interruptible(&udev->waitq);

@@ -82,6 +82,7 @@
udev->dev->event = uinput_dev_event;
udev->dev->upload_effect = uinput_dev_upload_effect;
udev->dev->erase_effect = uinput_dev_erase_effect;
+ udev->dev->private = udev;

init_waitqueue_head(&(udev->waitq));

@@ -264,7 +265,7 @@
return -ENODEV;

while ((udev->head != udev->tail) &&
- (retval + sizeof(struct uinput_device) <= count)) {
+ (retval + sizeof(struct input_event) <= count)) {
if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
sizeof(struct input_event))) return -EFAULT;
udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;

2003-06-21 13:39:54

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 4/11] input: Remove unused var from serio struct

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

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

[email protected], 2003-06-21 04:35:24-07:00, [email protected]
input: remove unused var from serio struct


serio.h | 1 -
1 files changed, 1 deletion(-)

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

diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h Sat Jun 21 15:25:14 2003
+++ b/include/linux/serio.h Sat Jun 21 15:25:14 2003
@@ -26,7 +26,6 @@
void *driver;
char *name;
char *phys;
- int number;

unsigned short idbus;
unsigned short idvendor;

2003-06-21 13:39:55

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 6/11] input: Add Logitech MX PS2++ support

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

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

[email protected], 2003-06-21 04:41:52-07:00, [email protected]
input: Add Logitech MX PS2++ support, move Logitech PS2++ code to a
separate source file, always enable Synaptics support. Some more
fixes in Synaptics code and documentation.


drivers/input/mouse/Kconfig | 17 --
drivers/input/mouse/Makefile | 5
drivers/input/mouse/logips2pp.c | 228 +++++++++++++++++++++++++++++++++++++
drivers/input/mouse/logips2pp.h | 17 ++
drivers/input/mouse/psmouse-base.c | 193 +++++++++----------------------
drivers/input/mouse/psmouse.h | 2
drivers/input/mouse/synaptics.c | 7 -
drivers/input/mouse/synaptics.h | 10 -
include/linux/input.h | 1
9 files changed, 315 insertions(+), 165 deletions(-)

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

diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/Kconfig Sat Jun 21 15:25:29 2003
@@ -19,7 +19,9 @@
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.
+ For Synaptics TouchPad support in XFree86 you'll need this XFree86
+ driver: http://w1.894.telia.com/~u89404340/touchpad/index.html

If unsure, say Y.

@@ -27,19 +29,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"
diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/Makefile Sat Jun 21 15:25:29 2003
@@ -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
diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/input/mouse/logips2pp.c Sat Jun 21 15:25:29 2003
@@ -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 *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);
+
+ if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
+ (param[2] & 3) == ((param[1] >> 2) & 3)) {
+ ps2pp_set_smartscroll(psmouse);
+ return PSMOUSE_PS2PP;
+ }
+ }
+ }
+
+ return 0;
+}
diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/input/mouse/logips2pp.h Sat Jun 21 15:25:29 2003
@@ -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
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/psmouse-base.c Sat Jun 21 15:25:29 2003
@@ -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 @@
* 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 @@
}

/*
- * 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 @@
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 @@
}

/*
+ * 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 @@
* 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 @@
* 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 @@
};

#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_resolution=", psmouse_resolution_setup);
+__setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
+
#endif

int __init psmouse_init(void)
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/psmouse.h Sat Jun 21 15:25:29 2003
@@ -46,4 +46,6 @@

int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);

+extern int psmouse_smartscroll;
+
#endif /* _PSMOUSE_H */
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/synaptics.c Sat Jun 21 15:25:29 2003
@@ -171,9 +171,9 @@
static int query_hardware(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
- int retries = 3;
+ int retries = 0;

- while ((retries++ <= 3) && synaptics_reset(psmouse))
+ while ((retries++ < 3) && synaptics_reset(psmouse))
printk(KERN_ERR "synaptics reset failed\n");

if (synaptics_identify(psmouse, &priv->identity))
@@ -266,8 +266,7 @@
* Functions to interpret the absolute mode packets
****************************************************************************/

-static void synaptics_parse_hw_state(struct synaptics_data *priv,
- struct synaptics_hw_state *hw)
+static void synaptics_parse_hw_state(struct synaptics_data *priv, struct synaptics_hw_state *hw)
{
unsigned char *buf = priv->proto_buf;

diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
--- a/drivers/input/mouse/synaptics.h Sat Jun 21 15:25:29 2003
+++ b/drivers/input/mouse/synaptics.h Sat Jun 21 15:25:29 2003
@@ -9,20 +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
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h Sat Jun 21 15:25:29 2003
+++ b/include/linux/input.h Sat Jun 21 15:25:29 2003
@@ -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

2003-06-21 13:38:03

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 5/11] input: Gameport was never closed after calibrating

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

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

[email protected], 2003-06-21 04:36:19-07:00, [email protected]
input: Fix gameport.c - gameport was never closed after calibrating


gameport.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
--- a/drivers/input/gameport/gameport.c Sat Jun 21 15:25:21 2003
+++ b/drivers/input/gameport/gameport.c Sat Jun 21 15:25:21 2003
@@ -84,6 +84,7 @@
if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
}

+ gameport_close(gameport);
return 59659 / (tx < 1 ? 1 : tx);

#else
@@ -93,11 +94,10 @@
j = jiffies; while (j == jiffies);
j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); }

+ gameport_close(gameport);
return t * HZ / 1000;

#endif
-
- gameport_close(gameport);
}

static void gameport_find_dev(struct gameport *gameport)

2003-06-21 13:39:55

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 2/11] input: Fix misdetection of PS/2 mice as AT keyboards

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

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

[email protected], 2003-06-21 04:33:11-07:00, [email protected]
input: Fix misdetection of PS2 mice as AT keyboards on non-PC machines
where ATKBD_CMD_RESET_BAT is used.


atkbd.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Sat Jun 21 15:24:59 2003
+++ b/drivers/input/keyboard/atkbd.c Sat Jun 21 15:24:59 2003
@@ -89,7 +89,7 @@
#define ATKBD_CMD_GETID 0x02f2
#define ATKBD_CMD_ENABLE 0x00f4
#define ATKBD_CMD_RESET_DIS 0x00f5
-#define ATKBD_CMD_RESET_BAT 0x01ff
+#define ATKBD_CMD_RESET_BAT 0x02ff
#define ATKBD_CMD_SETALL_MB 0x00f8
#define ATKBD_CMD_RESEND 0x00fe
#define ATKBD_CMD_EX_ENABLE 0x10ea
@@ -255,7 +255,8 @@

while (atkbd->cmdcnt && timeout--) {

- if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_RESET_BAT)
+ if (atkbd->cmdcnt == 1 &&
+ command == ATKBD_CMD_RESET_BAT && timeout > 100000)
timeout = 100000;

if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
@@ -270,6 +271,9 @@
if (param)
for (i = 0; i < receive; i++)
param[i] = atkbd->cmdbuf[(receive - 1) - i];
+
+ if (command == ATKBD_CMD_RESET_BAT && atkbd->cmdcnt == 1)
+ atkbd->cmdcnt = 0;

if (atkbd->cmdcnt) {
atkbd->cmdcnt = 0;

2003-06-21 13:46:29

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 11/11] input: Make GC_PSX_DELAY lower and configurable

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

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

[email protected], 2003-06-21 04:49:07-07:00, [email protected]
input: make GC_PSX_DELAY lower (25 usec instead of 60), to burn less
CPU time while reading PSX pads, and make it a module parameter also,
for devices which would need the huge value of 60.


gamecon.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)

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

diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c Sat Jun 21 15:26:06 2003
+++ b/drivers/input/joystick/gamecon.c Sat Jun 21 15:26:06 2003
@@ -46,6 +46,7 @@
MODULE_PARM(gc, "2-6i");
MODULE_PARM(gc_2,"2-6i");
MODULE_PARM(gc_3,"2-6i");
+MODULE_PARM(gc_psx_delay, "i");

#define GC_SNES 1
#define GC_NES 2
@@ -213,7 +214,7 @@
*
*/

-#define GC_PSX_DELAY 60 /* 60 usec */
+#define GC_PSX_DELAY 25 /* 25 usec */
#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */

#define GC_PSX_MOUSE 1 /* Mouse */
@@ -230,6 +231,7 @@
#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */
#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */

+static int gc_psx_delay = GC_PSX_DELAY;
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
@@ -246,10 +248,10 @@
for (i = 0; i < 8; i++, b >>= 1) {
cmd = (b & 1) ? GC_PSX_COMMAND : 0;
parport_write_data(gc->pd->port, cmd | GC_PSX_POWER);
- udelay(GC_PSX_DELAY);
+ udelay(gc_psx_delay);
data |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0;
parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
- udelay(GC_PSX_DELAY);
+ udelay(gc_psx_delay);
}
return data;
}
@@ -265,9 +267,9 @@
unsigned long flags;

parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */
- udelay(GC_PSX_DELAY * 2);
+ udelay(gc_psx_delay * 2);
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */
- udelay(GC_PSX_DELAY * 2);
+ udelay(gc_psx_delay * 2);

local_irq_save(flags);

@@ -649,9 +651,15 @@
for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1];
return 1;
}
+static int __init gc_psx_setup(char *str)
+{
+ get_option(&str, &gc_psx_delay);
+ return 1;
+}
__setup("gc=", gc_setup);
__setup("gc_2=", gc_setup_2);
__setup("gc_3=", gc_setup_3);
+__setup("gc_psx_delay=", gc_psx_setup);
#endif

int __init gc_init(void)

2003-06-21 13:46:43

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 3/11] input: Add locking to serio.c

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

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

[email protected], 2003-06-21 04:34:11-07:00, [email protected]
input: Add locking to serio.c


serio.c | 13 +++++++++++++
1 files changed, 13 insertions(+)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c Sat Jun 21 15:25:06 2003
+++ b/drivers/input/serio/serio.c Sat Jun 21 15:25:06 2003
@@ -58,6 +58,7 @@
struct list_head node;
};

+static DECLARE_MUTEX(serio_sem);
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_dev_list);
static LIST_HEAD(serio_event_list);
@@ -90,9 +91,11 @@

switch (event->type) {
case SERIO_RESCAN :
+ down(&serio_sem);
if (event->serio->dev && event->serio->dev->disconnect)
event->serio->dev->disconnect(event->serio);
serio_find_dev(event->serio);
+ up(&serio_sem);
break;
default:
break;
@@ -153,30 +156,37 @@

void serio_register_port(struct serio *serio)
{
+ down(&serio_sem);
list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio);
+ up(&serio_sem);
}

void serio_unregister_port(struct serio *serio)
{
+ down(&serio_sem);
list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
+ up(&serio_sem);
}

void serio_register_device(struct serio_dev *dev)
{
struct serio *serio;
+ down(&serio_sem);
list_add_tail(&dev->node, &serio_dev_list);
list_for_each_entry(serio, &serio_list, node)
if (!serio->dev && dev->connect)
dev->connect(serio, dev);
+ up(&serio_sem);
}

void serio_unregister_device(struct serio_dev *dev)
{
struct serio *serio;

+ down(&serio_sem);
list_del_init(&dev->node);

list_for_each_entry(serio, &serio_list, node) {
@@ -184,8 +194,10 @@
dev->disconnect(serio);
serio_find_dev(serio);
}
+ up(&serio_sem);
}

+/* called from serio_dev->connect/disconnect methods under serio_sem */
int serio_open(struct serio *serio, struct serio_dev *dev)
{
if (serio->open(serio))
@@ -194,6 +206,7 @@
return 0;
}

+/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
serio->close(serio);

2003-06-21 13:46:39

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 10/11] input: Fixes for sidewinder.c

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

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

[email protected], 2003-06-21 04:48:10-07:00, [email protected]
input: Fixes for sidewinder.c: Workaround for
misbehaving 3DPro joysticks, don't trust FreestylePro
1-bit data packet for data width recognition, invert
FreestylePro buttons.


sidewinder.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)

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

diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
--- a/drivers/input/joystick/sidewinder.c Sat Jun 21 15:25:59 2003
+++ b/drivers/input/joystick/sidewinder.c Sat Jun 21 15:25:59 2003
@@ -378,10 +378,10 @@
for (j = 0; j < 6; j++)
input_report_key(dev, sw_btn[SW_ID_FSP][j], !GB(j+10,1));

- input_report_key(dev, BTN_TR, GB(26,1));
- input_report_key(dev, BTN_START, GB(27,1));
- input_report_key(dev, BTN_MODE, GB(38,1));
- input_report_key(dev, BTN_SELECT, GB(39,1));
+ input_report_key(dev, BTN_TR, !GB(26,1));
+ input_report_key(dev, BTN_START, !GB(27,1));
+ input_report_key(dev, BTN_MODE, !GB(38,1));
+ input_report_key(dev, BTN_SELECT, !GB(39,1));

input_sync(dev);

@@ -602,7 +602,6 @@
gameport->phys, gameport->io, gameport->speed);

i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Read normal packet */
- m |= sw_guess_mode(buf, i); /* Data packet (1-bit) can carry mode info [FSP] */
udelay(SW_TIMEOUT);
dbg("Init 1: Mode %d. Length %d.", m , i);

@@ -676,6 +675,8 @@
} else
sw->type = SW_ID_PP;
break;
+ case 66:
+ sw->bits = 3;
case 198:
sw->length = 22;
case 64:

2003-06-21 13:46:41

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 8/11] input: Change order of search for beeper devices in keyboard.c

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

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

[email protected], 2003-06-21 04:44:26-07:00, [email protected]
input: Change order of search for beeper devices in keyboard.c,
so that it is easier to replace a beeper with a different
driver


keyboard.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c Sat Jun 21 15:25:44 2003
+++ b/drivers/char/keyboard.c Sat Jun 21 15:25:44 2003
@@ -242,7 +242,7 @@
del_timer(&kd_mksound_timer);

if (hz) {
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each_prev(node,&kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) {

2003-06-21 13:46:42

by Vojtech Pavlik

[permalink] [raw]
Subject: [PATCH 9/11] input: Fix double kfree of device->rdesc in hid-core

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

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

[email protected], 2003-06-21 04:45:44-07:00, [email protected]
input: fix double kfree of device->rdesc on hid_parse_parse error
path in hid-core.c


hid-core.c | 5 -----
1 files changed, 5 deletions(-)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Sat Jun 21 15:25:51 2003
+++ b/drivers/usb/input/hid-core.c Sat Jun 21 15:25:51 2003
@@ -674,7 +674,6 @@

if (item.format != HID_ITEM_FORMAT_SHORT) {
dbg("unexpected long global item");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -684,7 +683,6 @@
if (dispatch_type[item.type](parser, &item)) {
dbg("item %u %u %u %u parsing failed\n",
item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -694,7 +692,6 @@
if (start == end) {
if (parser->collection_stack_ptr) {
dbg("unbalanced collection at end of report description");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -702,7 +699,6 @@
}
if (parser->local.delimiter_depth) {
dbg("unbalanced delimiter at end of report description");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -714,7 +710,6 @@
}

dbg("item fetching failed at offset %d\n", (int)(end - start));
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);