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, ¶m, 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, ¶m, PSMOUSE_CMD_SETRATE)) + return -1; + + param = 3; + if (ps2_command(ps2dev, ¶m, 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, ¶m, 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);