NetBSD Problem Report #48200

From www@NetBSD.org  Tue Sep 10 02:24:49 2013
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 70CD9715D9
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 10 Sep 2013 02:24:49 +0000 (UTC)
Message-Id: <20130910022447.12216715DA@mollari.NetBSD.org>
Date: Tue, 10 Sep 2013 02:24:47 +0000 (UTC)
From: nathanialsloss@yahoo.com.au
Reply-To: nathanialsloss@yahoo.com.au
To: gnats-bugs@NetBSD.org
Subject: New driver fjttchps2 for fujitsu touchscreen & touchpad ps2 controller
X-Send-Pr-Version: www-1.0

>Number:         48200
>Category:       kern
>Synopsis:       New driver fjttchps2 for fujitsu touchscreen & touchpad ps2 controller
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    nat
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 10 02:25:00 +0000 2013
>Last-Modified:  Fri Nov 04 15:14:03 +0000 2016
>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>
+ * 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>
+ * 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.

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->nat
Responsible-Changed-By: maya@NetBSD.org
Responsible-Changed-When: Fri, 04 Nov 2016 15:14:03 +0000
Responsible-Changed-Why:
ping


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.