All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dtor_core@ameritech.net>
To: Sau Dan Lee <danlee@informatik.uni-freiburg.de>
Cc: Kim Holviala <kim@holviala.com>,
	linux-kernel@vger.kernel.org,
	Tuukka Toivonen <tuukkat@ee.oulu.fi>
Subject: Re: /dev/psaux-Interface
Date: Thu, 22 Apr 2004 01:39:00 -0500	[thread overview]
Message-ID: <200404220139.02775.dtor_core@ameritech.net> (raw)
In-Reply-To: <xb7smexg5sm.fsf@savona.informatik.uni-freiburg.de>

On Wednesday 21 April 2004 02:15 am, Sau Dan Lee wrote:
> >>>>> "Dmitry" == Dmitry Torokhov <dtor_core@ameritech.net> writes:
> 
> 
>     >> Adding the complexity of various devices and protocols into
>     >> kernelspace is insane.
> 
>     Dmitry> The thing is that processing in kernel space is not that
>     Dmitry> complex.
> 
> Even so,  it's not easy to  get it right.  In  kernel programming, you
> have to take  care of many issues, such as whether  you have a process
> context, when to  use spinlock, wait queues, etc.  I  even had to care
> about fasync() when developing the psaux module, even though it's just
> copying a few lines of sample code from the kernel hacking guide.
>

OK, here you go. It is the first cut. The driver creates an absolute device
for the touchscreen and a fake pass-through port to for the pointing device
which works in relative mode. All fancy stuff can be done in userspace via
evdev.
 
Hopefully I got Y-axis direction correctly and init sequence may need some
work. It also hijacks proto=imsp parameter until I merge Kim's protocol
selection changes. I wish I could test it but I do not have a Lifebook so
comments and suggestions are welcome.

Apply on top of patches in:
http://www.geocities.com/dt_or/input/2.6.6-rc2/

-- 
Dmitry

===== drivers/input/mouse/Makefile 1.9 vs edited =====
--- 1.9/drivers/input/mouse/Makefile	Wed Mar  3 11:17:04 2004
+++ edited/drivers/input/mouse/Makefile	Thu Apr 22 00:20:31 2004
@@ -15,4 +15,4 @@
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 obj-$(CONFIG_MOUSE_VSXXXAA)	+= vsxxxaa.o
 
-psmouse-objs  := psmouse-base.o logips2pp.o synaptics.o
+psmouse-objs  := psmouse-base.o lbtouch.o logips2pp.o synaptics.o
===== drivers/input/mouse/psmouse-base.c 1.57 vs edited =====
--- 1.57/drivers/input/mouse/psmouse-base.c	Tue Apr 20 23:59:36 2004
+++ edited/drivers/input/mouse/psmouse-base.c	Thu Apr 22 00:59:31 2004
@@ -21,6 +21,7 @@
 #include "psmouse.h"
 #include "synaptics.h"
 #include "logips2pp.h"
+#include "lbtouch.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("PS/2 mouse driver");
@@ -53,7 +54,7 @@
 __obsolete_setup("psmouse_resetafter=");
 __obsolete_setup("psmouse_rate=");
 
-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
+static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "LBPS/2" };
 
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
@@ -414,6 +415,15 @@
 			      unsigned int max_proto, int set_properties)
 {
 	int synaptics_hardware = 0;
+
+	if (max_proto == PSMOUSE_IMEX && lbtouch_init(psmouse, set_properties)) {
+		if (set_properties) {
+			psmouse->vendor = "Fujitsu";
+			psmouse->name = "Lifebook Touchscreen";
+		}
+
+		return PSMOUSE_LBTOUCH;
+	}
 
 /*
  * Try Synaptics TouchPad
===== drivers/input/mouse/psmouse.h 1.10 vs edited =====
--- 1.10/drivers/input/mouse/psmouse.h	Tue Apr 20 17:42:10 2004
+++ edited/drivers/input/mouse/psmouse.h	Thu Apr 22 00:14:52 2004
@@ -72,6 +72,7 @@
 #define PSMOUSE_IMPS		5
 #define PSMOUSE_IMEX		6
 #define PSMOUSE_SYNAPTICS 	7
+#define PSMOUSE_LBTOUCH 	8
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
===== drivers/input/mouse/lbtouch.c 1.0 vs 1.1 =====
--- /dev/null	Fri Aug 30 18:31:37 2002
+++ 1.1/drivers/input/mouse/lbtouch.c	Thu Apr 22 01:21:26 2004
@@ -0,0 +1,203 @@
+/*
+ *  Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * Lifebook touchscreen driver for Linux
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+
+#include "psmouse.h"
+#include "lbtouch.h"
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Fujitsu Lifebook touchscreen driver");
+MODULE_LICENSE("GPL");
+
+/* The default values are taken from Kenan Esau's driver */
+static int limits[4] = { 86, 955, 37, 937 };
+static int num_limits __initdata = 0;
+module_param_array_named(lbt_size, limits, int, num_limits, 0);
+MODULE_PARM_DESC(lbt_size, "Effective usable area of Lifebook touchscreen (left,right,bottom,up)");
+
+
+/*****************************************************************************
+ *	Lifebook pass-through PS/2 port support
+ ****************************************************************************/
+static int lbtouch_pt_write(struct serio *port, unsigned char c)
+{
+	switch (c) {
+		case PSMOUSE_CMD_RESET_BAT & 0xff:
+			serio_interrupt(port, PSMOUSE_RET_ACK, 0, NULL);
+			serio_interrupt(port, PSMOUSE_RET_BAT, 0, NULL);
+			serio_interrupt(port, PSMOUSE_RET_ID, 0, NULL);
+			break;
+
+		case PSMOUSE_CMD_GETID & 0xff:
+			serio_interrupt(port, PSMOUSE_RET_ACK, 0, NULL);
+			serio_interrupt(port, 0x00, 0, NULL);
+			break;
+
+		case PSMOUSE_CMD_ENABLE & 0xff:
+		case PSMOUSE_CMD_RESET_DIS & 0xff:
+			serio_interrupt(port, PSMOUSE_RET_ACK, 0, NULL);
+			break;
+
+		default:
+			serio_interrupt(port, PSMOUSE_RET_NAK, 0, NULL);
+			break;
+	}
+
+	return 0;
+}
+
+static void lbtouch_pass_pt_packet(struct serio *ptport, unsigned char *packet)
+{
+	struct psmouse *child = ptport->private;
+
+	if (child && child->state == PSMOUSE_ACTIVATED) {
+		serio_interrupt(ptport, packet[0], 0, NULL);
+		serio_interrupt(ptport, packet[1], 0, NULL);
+		serio_interrupt(ptport, packet[2], 0, NULL);
+	}
+}
+
+static void lbtouch_pt_create(struct psmouse *psmouse)
+{
+	struct psmouse_ptport *port;
+
+	psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
+	if (!port) {
+		printk(KERN_ERR "lbtouch: not enough memory to allocate pass-through port\n");
+		return;
+	}
+
+	memset(port, 0, sizeof(struct psmouse_ptport));
+
+	port->serio.type = SERIO_PS_PSTHRU;
+	port->serio.name = "Lifebook pass-through";
+	port->serio.phys = "lbtouch-pt/serio0";
+	port->serio.write = lbtouch_pt_write;
+	port->serio.driver = psmouse;
+}
+
+/*****************************************************************************
+ *	Functions to interpret the absolute mode packets
+ ****************************************************************************/
+
+static psmouse_ret_t lbtouch_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+{
+	struct input_dev *dev = &psmouse->dev;
+	unsigned char *p = psmouse->packet;
+	int x, y, touch;
+
+	input_regs(dev, regs);
+
+	if (psmouse->pktcnt < 3)
+		return PSMOUSE_GOOD_DATA;
+
+	if (p[0] & 0x80) {
+	        x = ((unsigned int)(p[0] & 0x30) << 4) + p[1];
+        	y = ((unsigned int)(p[0] & 0xc0) << 2) + p[2];
+		touch = p[0] & 0x04 ? 1 : 0;
+
+		input_report_key(dev, BTN_TOUCH, touch);
+		if (touch) {
+			input_report_abs(dev, ABS_X, x - limits[0]);
+			input_report_abs(dev, ABS_Y, limits[3] + limits[3] - y);
+		}
+
+		if ((p[0] &= 0x03) != 0 && psmouse->ptport && psmouse->ptport->serio.dev) {
+			p[1] = p[2] = 0;
+			lbtouch_pass_pt_packet(&psmouse->ptport->serio, p);
+		}
+	} else if (psmouse->ptport && psmouse->ptport->serio.dev) {
+		lbtouch_pass_pt_packet(&psmouse->ptport->serio, p);
+	}
+
+	return PSMOUSE_FULL_PACKET;
+}
+
+/*****************************************************************************
+ *	Driver initialization/cleanup functions
+ ****************************************************************************/
+
+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);
+}
+
+static void lbtouch_disconnect(struct psmouse *psmouse)
+{
+	unsigned char param[1];
+
+	param[0] = 0x06;
+
+	if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
+		printk(KERN_WARNING "lbtouch.c: Failed to restore touchscreen PS/2 emulation\n");
+}
+
+int lbtouch_init(struct psmouse *psmouse, int set_properties)
+{
+	unsigned char param[1];
+
+	if (psmouse->serio->type != SERIO_8042)
+		return 0;
+
+	param[0] = 0x07;
+	if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE) ||
+	    psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE)) {
+		printk(KERN_ERR "lbtouch.c: Failed to enable touchscreen native mode\n");
+		return 0;
+	}
+
+	if (set_properties) {
+		set_bit(EV_ABS, psmouse->dev.evbit);
+		set_abs_params(&psmouse->dev, ABS_X, limits[0], limits[1], 0, 0);
+		set_abs_params(&psmouse->dev, ABS_Y, limits[2], limits[3], 0, 0);
+
+		set_bit(EV_KEY, psmouse->dev.evbit);
+		set_bit(BTN_TOUCH, psmouse->dev.keybit);
+
+		clear_bit(EV_REL, psmouse->dev.evbit);
+		clear_bit(REL_X, psmouse->dev.relbit);
+		clear_bit(REL_Y, psmouse->dev.relbit);
+
+		psmouse->protocol_handler = lbtouch_process_byte;
+		psmouse->disconnect = lbtouch_disconnect;
+
+		lbtouch_pt_create(psmouse);
+	}
+
+	return 1;
+}
===== drivers/input/mouse/lbtouch.h 1.0 vs 1.1 =====
--- /dev/null	Fri Aug 30 18:31:37 2002
+++ 1.1/drivers/input/mouse/lbtouch.h	Thu Apr 22 01:21:29 2004
@@ -0,0 +1,16 @@
+/*
+ * Fujistsu Lifebook PS/2 touchscreen driver header
+ *
+ * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * 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 _LBTOUCH_H
+#define _LBTOUCH_H
+
+int lbtouch_init(struct psmouse *psmouse, int set_properties);
+
+#endif

  reply	other threads:[~2004-04-22  6:39 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.GSO.4.58.0402271451420.11281@stekt37>
2004-04-19  8:35 ` /dev/psaux-Interface Tuukka Toivonen
2004-04-19  8:52   ` /dev/psaux-Interface Andrew Morton
2004-04-19  9:53     ` /dev/psaux-Interface Kim Holviala
2004-04-19 10:16     ` /dev/psaux-Interface Sau Dan Lee
2004-04-19 10:53       ` /dev/psaux-Interface Arjan van de Ven
2004-04-19 11:18         ` /dev/psaux-Interface Jamie Lokier
2004-04-19 11:47           ` /dev/psaux-Interface Sau Dan Lee
2004-04-21 10:48         ` /dev/psaux-Interface Neil Brown
2004-04-21 11:24           ` /dev/psaux-Interface Sau Dan Lee
2004-04-21 11:52             ` /dev/psaux-Interface Tuukka Toivonen
2004-04-21 14:14               ` /dev/psaux-Interface Sau Dan Lee
2004-04-21 12:38             ` /dev/psaux-Interface Neil Brown
2004-04-21 14:21               ` /dev/psaux-Interface Sau Dan Lee
2004-04-20 12:56   ` /dev/psaux-Interface Dmitry Torokhov
2004-04-20 20:41     ` /dev/psaux-Interface Kim Holviala
     [not found]     ` <xb71xmhhmej.fsf@savona.informatik.uni-freiburg.de>
2004-04-21  6:51       ` /dev/psaux-Interface Dmitry Torokhov
2004-04-21  7:15         ` /dev/psaux-Interface Sau Dan Lee
2004-04-22  6:39           ` Dmitry Torokhov [this message]
2004-04-22  7:06             ` /dev/psaux-Interface Sau Dan Lee
2004-04-22  7:23               ` /dev/psaux-Interface Dmitry Torokhov
2004-04-21  7:18 /dev/psaux-Interface Sau Dan Lee
2004-04-21  7:21 ` /dev/psaux-Interface Kim Holviala
2004-04-21  8:13   ` /dev/psaux-Interface Sau Dan Lee
  -- strict thread matches above, loose matches on Subject: below --
2004-04-19 13:50 /dev/psaux-Interface tabris
2004-02-27 11:45 /dev/psaux-Interface Bernhard Gruber
2004-02-27 20:19 ` /dev/psaux-Interface Bernhard Gruber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200404220139.02775.dtor_core@ameritech.net \
    --to=dtor_core@ameritech.net \
    --cc=danlee@informatik.uni-freiburg.de \
    --cc=kim@holviala.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tuukkat@ee.oulu.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.