summaryrefslogtreecommitdiff
path: root/alps.patch
diff options
context:
space:
mode:
authorPeter Osterlund <petero2@telia.com>2003-10-26 09:05:04 +0100
committerPeter Osterlund <petero2@telia.com>2006-04-09 04:01:19 +0200
commitb1009fe08bab96d1dab6ac48c5382861019a7c10 (patch)
tree271a72f689339a143ff8c2eee4f335931020d6a6 /alps.patch
parent30d59997968289a8491e0b4f26d1ba6f160cd729 (diff)
Added the alps kernel patch for 2.6.0-test9.
Diffstat (limited to 'alps.patch')
-rw-r--r--alps.patch268
1 files changed, 268 insertions, 0 deletions
diff --git a/alps.patch b/alps.patch
new file mode 100644
index 0000000..ea39fe9
--- /dev/null
+++ b/alps.patch
@@ -0,0 +1,268 @@
+
+Vojtech Pavlik <vojtech@suse.cz> writes:
+
+> On Sun, Oct 05, 2003 at 06:55:31PM +0200, Peter Osterlund wrote:
+>
+> > I have updated your patch for kernel 2.6.0-test6-bk6 and made it
+> > report events compatible with the synaptics touchpad kernel driver.
+> > This should make it possible to use an ALPS device with the XFree86
+> > synaptics driver:
+> >
+> > http://w1.894.telia.com/~u89404340/touchpad/index.html
+> >
+> > Using this driver will give you edge scrolling and similar things.
+> >
+> > I don't have an ALPS GlidePoint so I haven't been able to test this
+> > patch at all. Test reports are appreciated. You probably need to
+> > change a few parameters in the X configuration, like edge parameters
+> > and finger pressure thresholds. Also note that the auto detection will
+> > not work with an ALPS device, so you have to use Protocol="event" and
+> > Device="/dev/input/eventN" for some value of N.
+>
+> Very nice. Could you also make it a separate file? I think it's enough
+> code to make that worth it ...
+
+Here is a new patch that moves the ALPS code to a separate file. The
+logic in ALPS_process_packet() has also gone through a few iterations
+with Johan Braennlund as a tester, so that it actually even works now,
+at least with his touchpad.
+
+Note though that the potential problems mentioned by Neil Brown in his
+initial announcement have not been dealt with:
+
+ It appears (but see 1) that it is not possible to reliably detect
+ an ALPS device.
+ ...
+ So the current code always sends the ALPS set-absolute-mode
+ sequence (4 disables before the enable) unless a
+ non-3-byte-protocol device was detected.
+
+ There are two consequences of always assuming an ALPS that may not
+ be good.
+ 1) The mouse always claims to generate various ABS events even
+ when there might not be any ABS-generating device behind the
+ mouse.
+ 2) The driver could misinterpret a normal mouse event that
+ overflowed in the negative direction for both X and Y as part
+ of an ALPS absolute event. This is because ALPS absolute
+ events are detected by checking if the top 5 bits of the first
+ byte are all one. I doubt this is a real problem as double
+ overflows are very unlikely (aren't they?)
+
+
+ linux-petero/drivers/input/mouse/Makefile | 2
+ linux-petero/drivers/input/mouse/alps.c | 131 ++++++++++++++++++++++++
+ linux-petero/drivers/input/mouse/alps.h | 17 +++
+ linux-petero/drivers/input/mouse/psmouse-base.c | 7 +
+ linux-petero/drivers/input/mouse/psmouse.h | 1
+ 5 files changed, 157 insertions(+), 1 deletion(-)
+
+diff -puN drivers/input/mouse/Makefile~alps drivers/input/mouse/Makefile
+--- linux/drivers/input/mouse/Makefile~alps 2003-10-26 08:33:30.000000000 +0100
++++ linux-petero/drivers/input/mouse/Makefile 2003-10-26 08:35:34.000000000 +0100
+@@ -14,4 +14,4 @@ obj-$(CONFIG_MOUSE_PC9800) += 98busmouse
+ obj-$(CONFIG_MOUSE_PS2) += psmouse.o
+ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
+
+-psmouse-objs := psmouse-base.o logips2pp.o synaptics.o
++psmouse-objs := psmouse-base.o logips2pp.o alps.o synaptics.o
+diff -puN drivers/input/mouse/alps.c~alps drivers/input/mouse/alps.c
+--- linux/drivers/input/mouse/alps.c~alps 2003-10-26 08:33:30.000000000 +0100
++++ linux-petero/drivers/input/mouse/alps.c 2003-10-26 08:33:30.000000000 +0100
+@@ -0,0 +1,131 @@
++/*
++ * ALPS touchpad PS/2 mouse driver
++ *
++ * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
++ * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
++ *
++ * 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 "alps.h"
++#include <linux/input.h>
++#include <linux/serio.h>
++#include "psmouse.h"
++
++static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
++{
++ dev->absmin[axis] = min;
++ dev->absmax[axis] = max;
++ dev->absfuzz[axis] = fuzz;
++ dev->absflat[axis] = flat;
++
++ set_bit(axis, dev->absbit);
++}
++
++/*
++ * If it is a 3-byte setting and we are allowed to use extensions,
++ * then it could be an ALPS Glidepoint, so send the init sequence just
++ * incase. i.e. 4 consecutive "disable"s before the "enable"
++ */
++
++void ALPS_initialize(struct psmouse *psmouse)
++{
++ if (psmouse->type < PSMOUSE_GENPS) {
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE);
++ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE);
++
++ set_bit(BTN_TOUCH, psmouse->dev.keybit);
++ set_bit(BTN_BACK, psmouse->dev.keybit);
++ set_bit(BTN_FORWARD, psmouse->dev.keybit);
++ set_bit(BTN_TOOL_FINGER, psmouse->dev.keybit);
++ set_bit(EV_ABS, psmouse->dev.evbit);
++ set_abs_params(&psmouse->dev, ABS_X, 0, 0, 0, 0);
++ set_abs_params(&psmouse->dev, ABS_Y, 0, 0, 0, 0);
++ set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
++ }
++}
++
++/*
++ * ALPS abolute Mode
++ * byte 0: 1 1 1 1 1 mid0 rig0 lef0
++ * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
++ * byte 2: 0 x10 x9 x8 x7 up1 fin ges
++ * byte 3: 0 y9 y8 y7 1 mid1 rig1 lef1
++ * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
++ * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
++ *
++ * On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad.
++ * We just 'or' them together for now.
++ * We also send 'ges'ture as BTN_TOUCH
++ *
++ * The touchpad on an 'Acer Aspire' has 4 buttons:
++ * left,right,up,down.
++ * This device always sets {mid,rig,lef}0 to 1 and
++ * reflects left,right,down,up in lef1,rig1,mid1,up1.
++ */
++
++static void ALPS_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
++{
++ unsigned char *packet = psmouse->packet;
++ struct input_dev *dev = &psmouse->dev;
++ int x, y, z;
++ int left = 0, right = 0, middle = 0;
++
++ input_regs(dev, regs);
++
++ x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3));
++ y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4));
++ z = packet[5];
++
++ if (z > 0) {
++ input_report_abs(dev, ABS_X, x);
++ input_report_abs(dev, ABS_Y, y);
++ }
++ input_report_abs(dev, ABS_PRESSURE, z);
++ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
++
++ if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
++ if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
++
++ left |= (packet[2] ) & 1;
++ left |= (packet[3] ) & 1;
++ right |= (packet[3] >> 1) & 1;
++ if (packet[0] == 0xff) {
++ input_report_key(dev, BTN_BACK, (packet[3] >> 2) & 1);
++ input_report_key(dev, BTN_FORWARD, (packet[2] >> 2) & 1);
++ } else {
++ left |= (packet[0] ) & 1;
++ right |= (packet[0] >> 1) & 1;
++ middle |= (packet[0] >> 2) & 1;
++ middle |= (packet[3] >> 2) & 1;
++ }
++
++ input_report_key(dev, BTN_LEFT, left);
++ input_report_key(dev, BTN_RIGHT, right);
++ input_report_key(dev, BTN_MIDDLE, middle);
++
++ input_sync(dev);
++}
++
++int ALPS_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
++{
++ if (psmouse->type >= PSMOUSE_GENPS)
++ return -1;
++
++ /* ALPS absolute mode packets start with 0b11111mrl
++ * Normal mouse packets are extremely unlikely to overflow both
++ * x and y
++ */
++ if ((psmouse->packet[0] & 0xf8) != 0xf8)
++ return -1;
++
++ if (psmouse->pktcnt == 6) {
++ ALPS_process_packet(psmouse, regs);
++ psmouse->pktcnt = 0;
++ }
++ return 0;
++}
+diff -puN drivers/input/mouse/alps.h~alps drivers/input/mouse/alps.h
+--- linux/drivers/input/mouse/alps.h~alps 2003-10-26 08:33:30.000000000 +0100
++++ linux-petero/drivers/input/mouse/alps.h 2003-10-26 08:33:30.000000000 +0100
+@@ -0,0 +1,17 @@
++/*
++ * ALPS touchpad PS/2 mouse driver
++ *
++ * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
++ *
++ * 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 _ALPS_H
++#define _ALPS_H
++struct psmouse;
++struct pt_regs;
++void ALPS_initialize(struct psmouse *psmouse);
++int ALPS_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
++#endif
+diff -puN drivers/input/mouse/psmouse-base.c~alps drivers/input/mouse/psmouse-base.c
+--- linux/drivers/input/mouse/psmouse-base.c~alps 2003-10-26 08:33:30.000000000 +0100
++++ linux-petero/drivers/input/mouse/psmouse-base.c 2003-10-26 08:35:34.000000000 +0100
+@@ -21,6 +21,7 @@
+ #include "psmouse.h"
+ #include "synaptics.h"
+ #include "logips2pp.h"
++#include "alps.h"
+
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("PS/2 mouse driver");
+@@ -179,6 +180,9 @@ static irqreturn_t psmouse_interrupt(str
+ goto out;
+ }
+
++ if (!psmouse_noext && !ALPS_process_byte(psmouse, regs))
++ goto out;
++
+ if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
+ psmouse_process_packet(psmouse, regs);
+ psmouse->pktcnt = 0;
+@@ -485,6 +489,9 @@ static void psmouse_initialize(struct ps
+ */
+
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);
++
++ if (!psmouse_noext)
++ ALPS_initialize(psmouse);
+ }
+
+ /*
+diff -puN drivers/input/mouse/psmouse.h~alps drivers/input/mouse/psmouse.h
+--- linux/drivers/input/mouse/psmouse.h~alps 2003-10-26 08:33:30.000000000 +0100
++++ linux-petero/drivers/input/mouse/psmouse.h 2003-10-26 08:35:34.000000000 +0100
+@@ -9,6 +9,7 @@
+ #define PSMOUSE_CMD_GETID 0x02f2
+ #define PSMOUSE_CMD_SETRATE 0x10f3
+ #define PSMOUSE_CMD_ENABLE 0x00f4
++#define PSMOUSE_CMD_DISABLE 0x00f5
+ #define PSMOUSE_CMD_RESET_DIS 0x00f6
+ #define PSMOUSE_CMD_RESET_BAT 0x02ff
+
+
+_