Hi!

I've reimplemented the Lifebook touchscreen driver using libps2 and
input, to make it short and fitting into the kernel drivers.

Please comment on code and test for functionality!

PS.: The driver should register two input devices. It doesn't yet,
since that isn't very straightforward in the psmouse framework.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR
[EMAIL PROTECTED], 2005-02-11 21:03:32+01:00, [EMAIL PROTECTED]
  input: Fujitsu Lifebook driver, experimental.
  
  Signed-off-by: Vojtech Pavlik <[EMAIL PROTECTED]>


 Makefile       |    2 
 lifebook.c     |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lifebook.h     |   16 ++++++
 psmouse-base.c |    6 ++
 psmouse.h      |    1 
 5 files changed, 157 insertions(+), 2 deletions(-)


diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile      2005-02-11 21:04:00 +01:00
+++ b/drivers/input/mouse/Makefile      2005-02-11 21:04:00 +01:00
@@ -15,4 +15,4 @@
 obj-$(CONFIG_MOUSE_HIL)                += hil_ptr.o
 obj-$(CONFIG_MOUSE_VSXXXAA)    += vsxxxaa.o
 
-psmouse-objs  := psmouse-base.o alps.o logips2pp.o synaptics.o
+psmouse-objs  := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o
diff -Nru a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/drivers/input/mouse/lifebook.c    2005-02-11 21:04:00 +01:00
@@ -0,0 +1,134 @@
+/*
+ * Fujitsu B-series Lifebook PS/2 TouchScreen driver
+ *
+ * Copyright (c) 2005 Vojtech Pavlik <[EMAIL PROTECTED]>
+ *
+ * TouchSceeen detection, absolute mode setting and packet layout is taken from
+ * Harald Hoyer's description of the device.
+ *
+ * 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 <linux/serio.h>
+#include <linux/libps2.h>
+
+#include "psmouse.h"
+#include "lifebook.h"
+
+static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct 
pt_regs *regs)
+{
+       unsigned char *packet = psmouse->packet;
+       struct input_dev *dev = &psmouse->dev;
+
+       if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+               if (psmouse->pktcnt == 3) {
+
+                       input_regs(dev, regs);
+                       input_report_key(dev, BTN_LEFT,    packet[0]       & 1);
+                       input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
+                       input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);
+                       input_report_rel(dev, REL_X, packet[1] ?
+                               (int) packet[1] - (int) ((packet[0] << 4) & 
0x100) : 0);
+                       input_report_rel(dev, REL_Y, packet[2] ?
+                               (int) ((packet[0] << 3) & 0x100) - (int) 
packet[2] : 0);
+                       input_sync(dev);
+
+                       return PSMOUSE_FULL_PACKET;
+               }
+               return PSMOUSE_GOOD_DATA;
+       }
+
+       if ((psmouse->packet[0] & 0x0b) == 0x00) { /* Absolute packet */
+               if (psmouse->pktcnt == 3) {
+
+                       input_regs(dev, regs);
+                       input_report_key(dev, BTN_TOUCH,   packet[0]       & 4);
+                       input_report_rel(dev, ABS_X, ((packet[0] & 0x30) << 4) 
| packet[1]);
+                       input_report_rel(dev, ABS_Y, ((packet[0] & 0xc0) << 2) 
| packet[2]);
+                       input_sync(dev);
+
+                       return PSMOUSE_FULL_PACKET;
+               }
+               return PSMOUSE_GOOD_DATA;
+       }
+
+       return PSMOUSE_BAD_DATA;
+}
+
+static int lifebook_reconnect(struct psmouse *psmouse)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char param;
+
+       param = 7;
+       if (ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES))
+               return -1;
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+               return -1;
+
+       return 0;
+}
+
+static void lifebook_disconnect(struct psmouse *psmouse)
+{
+       psmouse_reset(psmouse);
+}
+
+int lifebook_detect(struct psmouse *psmouse, int set_properties)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char param;
+
+/*
+ * This might be a magic knock sequence, or just a part of
+ * a standard mouse init for the mouse behind the screen.
+ * Rate of 40 also seems pretty low, but that's what the
+ * Windows driver supposedly does.
+ */
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11))
+               return -1;
+
+       param = 40;
+       if (ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRATE))
+               return -1;
+
+       param = 3;
+       if (ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES))
+               return -1;
+
+/*
+ * This should fail on normal mice, SETRES only accepts
+ * values from 0 to 3.
+ */
+
+       param = 7;
+       if (ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES))
+               return -1;
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+               return -1;
+
+       if (set_properties) {
+               psmouse->vendor = "Fujitsu Lifebook";
+               psmouse->name = "TouchScreen";
+       }
+
+       psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+       psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | 
BIT(BTN_RIGHT);
+       psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_set_abs_params(&psmouse->dev, ABS_X, 130, 885, 0, 0);
+       input_set_abs_params(&psmouse->dev, ABS_Y, 272, 830, 0, 0);
+
+       psmouse->protocol_handler = lifebook_process_byte;
+       psmouse->disconnect = lifebook_disconnect;
+       psmouse->reconnect = lifebook_reconnect;
+       psmouse->pktsize = 3;
+
+       return 0;
+}
diff -Nru a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/drivers/input/mouse/lifebook.h    2005-02-11 21:04:00 +01:00
@@ -0,0 +1,16 @@
+/*
+ * Fujitsu B-series Lifebook PS/2 TouchScreen driver
+ *
+ * Copyright (c) 2005 Vojtech Pavlik
+ *
+ * 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 _LIFEBOOK_H
+#define _LIFEBOOK_H
+
+int lifebook_detect(struct psmouse *psmouse, int set_properties);
+
+#endif
diff -Nru a/drivers/input/mouse/psmouse-base.c 
b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c        2005-02-11 21:04:00 +01:00
+++ b/drivers/input/mouse/psmouse-base.c        2005-02-11 21:04:00 +01:00
@@ -24,6 +24,7 @@
 #include "synaptics.h"
 #include "logips2pp.h"
 #include "alps.h"
+#include "lifebook.h"
 
 #define DRIVER_DESC    "PS/2 mouse driver"
 
@@ -62,7 +63,7 @@
 __obsolete_setup("psmouse_resetafter=");
 __obsolete_setup("psmouse_rate=");
 
-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", 
"GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" };
+static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", 
"GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2", "LBPS/2" };
 
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
@@ -462,6 +463,9 @@
                        max_proto = PSMOUSE_IMEX;
                }
        }
+
+       if (max_proto > PSMOUSE_IMEX && lifebook_detect(psmouse, 
set_properties) == 0)
+               return PSMOUSE_LIFEBOOK;
 
        if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) 
== 0)
                return PSMOUSE_GENPS;
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h     2005-02-11 21:04:00 +01:00
+++ b/drivers/input/mouse/psmouse.h     2005-02-11 21:04:00 +01:00
@@ -77,6 +77,7 @@
        PSMOUSE_IMEX,
        PSMOUSE_SYNAPTICS,
        PSMOUSE_ALPS,
+       PSMOUSE_LIFEBOOK,
 };
 
 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);

Reply via email to