NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/48200: New driver fjttchps2 for fujitsu touchscreen & touchpad ps2 controller
>Number: 48200
>Category: kern
>Synopsis: New driver fjttchps2 for fujitsu touchscreen & touchpad ps2
>controller
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Sep 10 02:25:00 +0000 2013
>Originator: Nat Sloss
>Release: NetBSD Current 6.99.23
>Organization:
>Environment:
NetBSD beast 6.99.23 NetBSD 6.99.23 (LOCKDEBUG) #4: Wed Jul 17 22:24:41 EST
2013 build@beast:/usr/src/sys/arch/i386/compile/obj/LOCKDEBUG i386
>Description:
I had written a driver for the touch screen and trackpad controller found in
Panasonic Toughbook CF18 and possibly it will work for earlier toughbooks and
other computers using a ps2 fujitsu touch screen controller.
Originally it was written for NetBSD 3.0.1 in 2009, I've since updated it for
NetBSD-current and I am submitting it in this PR in the hope that others might
find it useful.
>How-To-Repeat:
>Fix:
Simply add the following line to your kernel config:
options PMS_FUJITSU_TOUCHPANEL # Fujitsu touch panel.
Then apply these patches:
Index: sys/dev/pckbport/files.pckbport
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/files.pckbport,v
retrieving revision 1.8
diff -u -r1.8 files.pckbport
--- sys/dev/pckbport/files.pckbport 7 Sep 2011 19:05:13 -0000 1.8
+++ sys/dev/pckbport/files.pckbport 10 Sep 2013 02:06:28 -0000
@@ -16,8 +16,10 @@
obsolete defflag opt_pms.h PMS_DISABLE_POWERHOOK
defflag opt_pms.h PMS_SYNAPTICS_TOUCHPAD
defflag opt_pms.h PMS_ELANTECH_TOUCHPAD
+defflag opt_pms.h PMS_FUJITSU_TOUCHPANEL
device pms: wsmousedev
attach pms at pckbport
file dev/pckbport/pms.c pms
file dev/pckbport/synaptics.c pms & pms_synaptics_touchpad
file dev/pckbport/elantech.c pms & pms_elantech_touchpad
+file dev/pckbport/fjttchps2.c pms & pms_fujitsu_touchpanel
Index: sys/dev/pckbport/pms.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/pms.c,v
retrieving revision 1.35
diff -u -r1.35 pms.c
--- sys/dev/pckbport/pms.c 9 Sep 2011 14:29:47 -0000 1.35
+++ sys/dev/pckbport/pms.c 10 Sep 2013 02:07:05 -0000
@@ -1,5 +1,6 @@
/* $NetBSD: pms.c,v 1.35 2011/09/09 14:29:47 jakllsch Exp $ */
+
/*-
* Copyright (c) 2004 Kentaro Kurahone.
* Copyright (c) 2004 Ales Krenek.
@@ -46,6 +47,9 @@
#ifdef PMS_ELANTECH_TOUCHPAD
#include <dev/pckbport/elantechvar.h>
#endif
+#ifdef PMS_FUJITSU_TOUCHPANEL
+#include <dev/pckbport/fjttchps2var.h>
+#endif
#include <dev/pckbport/pmsreg.h>
#include <dev/pckbport/pmsvar.h>
@@ -207,6 +211,12 @@
sc->protocol = PMS_ELANTECH;
} else
#endif
+#ifdef PMS_FUJITSU_TOUCHPANEL
+ /* Probe for touchpanel touchpad. */
+ if (pms_tpanel_probe_init(sc) == 0) {
+ sc->protocol = PMS_FUJITSU;
+ } else
+#endif
/* Install generic handler. */
pckbport_set_inputhandler(sc->sc_kbctag, sc->sc_kbcslot,
pmsinput, sc, device_xname(sc->sc_dev));
@@ -255,6 +265,10 @@
if (sc->protocol == PMS_ELANTECH)
pms_elantech_enable(sc);
#endif
+#ifdef PMS_FUJITSU_TOUCHPANEL
+ if (sc->protocol == PMS_FUJITSU)
+ pms_tpanel_enable(sc);
+#endif
cmd[0] = PMS_DEV_ENABLE;
res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd,
--- sys/dev/pckbport/fjttchps2var.h.orig 2013-09-10 10:06:12.000000000
+1000
+++ sys/dev/pckbport/fjttchps2var.h 2013-09-10 09:46:06.000000000 +1000
@@ -0,0 +1,34 @@
+/*-
+ * Copyright (c) 2009-2013 Nathanial Sloss
<nathanialsloss%yahoo.com.au@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_PCKBCPORT_tpanelVAR_H_
+#define _DEV_PCKBCPORT_tpanelVAR_H_
+
+int pms_tpanel_probe_init(void *vsc);
+void pms_tpanel_enable(void *vsc);
+void pms_tpanel_resume(void *vsc);
+
+#endif
--- sys/dev/pckbport/fjttchps2.c.orig 2013-09-10 10:05:48.000000000 +1000
+++ sys/dev/pckbport/fjttchps2.c 2013-09-10 10:39:21.000000000 +1000
@@ -0,0 +1,304 @@
+/*-
+ * Copyright (c) 2009-2013 Nathanial Sloss
<nathanialsloss%yahoo.com.au@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_pms.h"
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/kernel.h>
+#include <machine/pio.h>
+
+#include <dev/pckbport/pckbportvar.h>
+
+#include <dev/pckbport/fjttchps2var.h>
+
+#include <dev/pckbport/pmsreg.h>
+#include <dev/pckbport/pmsvar.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+/*
+ * Absolute-mode packets are decoded and passed around using
+ * the following structure.
+ */
+
+struct tpanel_packet {
+ int sp_x; /* Unscaled absolute X/Y coordinates */
+ int sp_y;
+ u_char sp_z; /* Z (pressure) */
+ char sp_left; /* Left mouse button status */
+ char sp_right; /* Right mouse button status */
+ char sp_middle; /* Middle button status (possibly emulated) */
+ char sp_up; /* Up button status */
+ char sp_down; /* Down button status */
+};
+
+/* Masks for the first byte of a packet */
+#define PMS_LBUTMASK 0x01
+#define PMS_RBUTMASK 0x02
+#define PMS_MBUTMASK 0x04
+
+static void pms_tpanel_input(void *, int);
+
+int
+pms_tpanel_probe_init(void *vsc)
+{
+ struct pms_softc *psc = vsc;
+ /*
+ * This is suppossed to check DMI strings and ensure that the device
+ * is infact a CF-18 with a touch screen.
+ *
+ * At the moment the driver is force loaded.
+ *
+ * This will cause big problems if enabled on machines without the
+ * appropriate hardware.
+ */
+
+ pckbport_set_inputhandler(psc->sc_kbctag, psc->sc_kbcslot,
+ pms_tpanel_input, psc, device_xname(psc->sc_dev));
+
+ return (0);
+}
+
+void
+pms_tpanel_enable(void *vsc)
+{
+ struct pms_softc *psc = vsc;
+ u_char cmd[3];
+ int res = 0;
+
+ /*
+ * Enable the touchscreen.
+ *
+ *
+ * The cmd sequence below will enable abs. output for touch screen.
+ * Once sent, the touch screen will output data.
+ * This also has the effect on the CF-18(TS) to set the touchpad to
+ * absolute mode and then both devices use this driver.
+ */
+
+ cmd[0] = PMS_SET_SCALE11;
+ cmd[1] = PMS_SET_SAMPLE;
+ cmd[2] = 0x28;
+
+ res |= pckbport_enqueue_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 3, 0, 1,
NULL);
+
+ cmd[0] = PMS_SET_RES;
+ cmd[1] = 0x03;
+
+ res |= pckbport_enqueue_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 2, 0, 1,
NULL);
+
+ cmd[0] = PMS_SET_RES;
+ cmd[1] = 0x08;
+
+ res |= pckbport_enqueue_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 2, 0, 1,
NULL);
+
+ /* The above command will always report a failure though. */
+ res = 0;
+
+ cmd[0] = PMS_DEV_ENABLE;
+ cmd[1] = PMS_DEV_ENABLE;
+ cmd[2] = PMS_DEV_ENABLE;
+
+ res |= pckbport_enqueue_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 3, 0, 1,
NULL);
+
+ if (res) {
+ printf("%s: tpanel_enable: Error enabling device.\n",
+ device_xname(psc->sc_dev));
+ }
+}
+
+static void
+pms_tpanel_input(void *vsc, int data)
+{
+ struct pms_softc *sc = vsc;
+ u_int changed;
+ int dx, dy, dz = 0;
+ int newbuttons = 0;
+
+ if (!sc->sc_enabled) {
+ /* Interrupts are not expected. Discard the byte. */
+ return;
+ }
+
+ getmicrouptime(&sc->current);
+
+ if (sc->inputstate > 0) {
+ struct timeval diff;
+
+ timersub(&sc->current, &sc->last, &diff);
+ /*
+ * Empirically, the delay should be about 1700us on a standard
+ * PS/2 port. I have seen delays as large as 4500us (rarely)
+ * in regular use. When using a confused mouse, I generally
+ * see delays at least as large as 30,000us. -seebs
+ *
+ * The thinkpad trackball returns at 22-23ms. So we use
+ * >= 40ms. In the future, I'll implement adaptable timeout
+ * by increasing the timeout if the mouse reset happens
+ * too frequently -christos
+ */
+ if (diff.tv_sec > 0 || diff.tv_usec >= 40000) {
+ printf("pms_input: unusual delay (%ld.%06ld s), "
+ "scheduling reset\n",
+ (long)diff.tv_sec, (long)diff.tv_usec);
+ sc->inputstate = 0;
+ sc->sc_enabled = 0;
+ wakeup(&sc->sc_enabled);
+ return;
+ }
+ }
+ sc->last = sc->current;
+
+ if (sc->inputstate == 0) {
+ /*
+ * Some devices (seen on trackballs anytime, and on
+ * some mice shortly after reset) output garbage bytes
+ * between packets. Just ignore them.
+ */
+ if ((data & 0xc0) != 0)
+ return; /* not in sync yet, discard input */
+ }
+
+ sc->packet[sc->inputstate++] = data & 0xff;
+ switch (sc->inputstate) {
+ case 0:
+ /* no useful processing can be done yet */
+ break;
+
+ case 1:
+ /*
+ * Why should we test for bit 0x8 and insist on it here?
+ * The old (psm.c and psm_intelli.c) drivers didn't do
+ * it, and there are devices where it does harm (that's
+ * why it is not used if using PMS_STANDARD protocol).
+ * Anyway, it does not to cause any harm to accept packets
+ * without this bit.
+ */
+ sc->protocol = PMS_FUJITSU;
+
+ if (sc->packet[0] & 0x8)
+ sc->protocol = PMS_STANDARD;
+ break;
+
+ case 2:
+ break;
+
+ case 4:
+ break;
+ case 3:
+ /*
+ * This is only an endpoint for scroll protocols with 4
+ * bytes, or the standard protocol with 3.
+ */
+ if (sc->protocol != PMS_STANDARD && sc->inputstate == 3)
+ break;
+
+ newbuttons |= ((sc->packet[0] & PMS_LBUTMASK) ? 0x1 : 0) |
+ ((sc->packet[0] & PMS_MBUTMASK) ? 0x2 : 0) |
+ ((sc->packet[0] & PMS_RBUTMASK) ? 0x4 : 0);
+
+ dx = sc->packet[1];
+ if (dx >= 128)
+ dx -= 256;
+ if (dx == -128)
+ dx = -127;
+
+ dy = sc->packet[2];
+ if (dy >= 128)
+ dy -= 256;
+ if (dy == -128)
+ dy = -127;
+
+ sc->inputstate = 0;
+ changed = (sc->buttons ^ newbuttons);
+ sc->buttons = newbuttons;
+
+#ifdef PMSDEBUG
+ if (sc->protocol == PMS_STANDARD) {
+ DPRINTF(("pms: packet: 0x%02x%02x%02x\n",
+ sc->packet[0], sc->packet[1], sc->packet[2]));
+ } else {
+ DPRINTF(("pms: packet: 0x%02x%02x%02x%02x\n",
+ sc->packet[0], sc->packet[1], sc->packet[2],
+ sc->packet[3]));
+ }
+#endif
+ if (dx || dy || dz || changed) {
+#ifdef PMSDEBUG
+ DPRINTF(("pms: x %+03d y %+03d z %+03d "
+ "buttons 0x%02x\n", dx, dy, dz, sc->buttons));
+#endif
+ wsmouse_input(sc->sc_wsmousedev,
+ sc->buttons, dx, dy, dz, 0,
+ WSMOUSE_INPUT_DELTA);
+ }
+ memset(sc->packet, 0, 4);
+ break;
+
+ case 5:
+ break;
+
+ case 6:
+ if (sc->protocol == PMS_FUJITSU) {
+ dx = ((sc->packet[2] & 0x3f) |
+ ((sc->packet[1] & 0x3f) << 5));
+ dy = ((sc->packet[5] & 0x3f) |
+ ((sc->packet[4] & 0x3f) << 5));
+ dz = 0;
+ newbuttons = (sc->packet[0] & 0x04) >> 2;
+#ifdef tpanelDEBUG
+ printf("X coordinate: [%d], Y coordinate: [%d] Buttons:
[%d] \n",dx,dy,newbuttons);
+#endif
+ sc->inputstate = 0;
+ changed = (sc->buttons ^ newbuttons);
+ newbuttons = newbuttons & PMS_LBUTMASK;
+
+ if (dx || dy || dz || changed) {
+ wsmouse_input(sc->sc_wsmousedev,
+ newbuttons, dx, dy, dz, 0,
+ WSMOUSE_INPUT_ABSOLUTE_X|WSMOUSE_INPUT_ABSOLUTE_Y);
+ }
+ }
+
+ memset(sc->packet, 0, 4);
+ break;
+
+ /* If we get here, we have problems. */
+ default:
+ printf("pmsinput: very confused. resetting.\n");
+ sc->inputstate = 0;
+ sc->sc_enabled = 0;
+ wakeup(&sc->sc_enabled);
+ return;
+ }
+}
Unfortunately as of this time I am yet to write a manual page but it would be
minimal only informing that one needs to use this with the ws(4) X11 input
driver.
I hope others find this useful.
Regards,
Nat.
Home |
Main Index |
Thread Index |
Old Index