From: Dmitry Torokhov <dtor_core@ameritech.net>

make open and close serio methods optional


---

 25-akpm/drivers/input/mouse/lbtouch.c   |  203 ++++++++++++++++++++++++++++++++
 25-akpm/drivers/input/mouse/lbtouch.h   |   16 ++
 25-akpm/drivers/input/mouse/synaptics.c |   11 -
 25-akpm/drivers/input/serio/parkbd.c    |   11 -
 25-akpm/drivers/input/serio/q40kbd.c    |   11 -
 25-akpm/drivers/input/serio/serio.c     |    5 
 25-akpm/drivers/input/serio/serport.c   |   10 -
 7 files changed, 224 insertions(+), 43 deletions(-)

diff -puN /dev/null drivers/input/mouse/lbtouch.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/drivers/input/mouse/lbtouch.c	2004-04-22 01:11:00.944147328 -0700
@@ -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;
+}
diff -puN /dev/null drivers/input/mouse/lbtouch.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/drivers/input/mouse/lbtouch.h	2004-04-22 01:11:00.944147328 -0700
@@ -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
diff -puN drivers/input/mouse/synaptics.c~new-set-of-input-patches-serio-open-close-optional drivers/input/mouse/synaptics.c
--- 25/drivers/input/mouse/synaptics.c~new-set-of-input-patches-serio-open-close-optional	2004-04-22 01:11:00.931149304 -0700
+++ 25-akpm/drivers/input/mouse/synaptics.c	2004-04-22 01:11:00.945147176 -0700
@@ -212,15 +212,6 @@ static int synaptics_set_mode(struct psm
 /*****************************************************************************
  *	Synaptics pass-through PS/2 port support
  ****************************************************************************/
-static int synaptics_pt_open(struct serio *port)
-{
-	return 0;
-}
-
-static void synaptics_pt_close(struct serio *port)
-{
-}
-
 static int synaptics_pt_write(struct serio *port, unsigned char c)
 {
 	struct psmouse *parent = port->driver;
@@ -282,8 +273,6 @@ static void synaptics_pt_create(struct p
 	port->serio.name = "Synaptics pass-through";
 	port->serio.phys = "synaptics-pt/serio0";
 	port->serio.write = synaptics_pt_write;
-	port->serio.open = synaptics_pt_open;
-	port->serio.close = synaptics_pt_close;
 	port->serio.driver = psmouse;
 
 	port->activate = synaptics_pt_activate;
diff -puN drivers/input/serio/parkbd.c~new-set-of-input-patches-serio-open-close-optional drivers/input/serio/parkbd.c
--- 25/drivers/input/serio/parkbd.c~new-set-of-input-patches-serio-open-close-optional	2004-04-22 01:11:00.933149000 -0700
+++ 25-akpm/drivers/input/serio/parkbd.c	2004-04-22 01:11:00.945147176 -0700
@@ -86,20 +86,9 @@ static int parkbd_write(struct serio *po
 	return 0;
 }
 
-static int parkbd_open(struct serio *port)
-{
-	return 0;
-}
-
-static void parkbd_close(struct serio *port)
-{
-}
-
 static struct serio parkbd_port =
 {
 	.write	= parkbd_write,
-	.open	= parkbd_open,
-	.close	= parkbd_close,
 	.name	= parkbd_name,
 	.phys	= parkbd_phys,
 };
diff -puN drivers/input/serio/q40kbd.c~new-set-of-input-patches-serio-open-close-optional drivers/input/serio/q40kbd.c
--- 25/drivers/input/serio/q40kbd.c~new-set-of-input-patches-serio-open-close-optional	2004-04-22 01:11:00.934148848 -0700
+++ 25-akpm/drivers/input/serio/q40kbd.c	2004-04-22 01:11:00.946147024 -0700
@@ -47,23 +47,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@u
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-
-static int q40kbd_open(struct serio *port)
-{
-	return 0;
-}
-static void q40kbd_close(struct serio *port)
-{
-}
-
 static struct serio q40kbd_port =
 {
 	.type	= SERIO_8042,
 	.name	= "Q40 kbd port",
 	.phys	= "Q40",
 	.write	= NULL,
-	.open	= q40kbd_open,
-	.close	= q40kbd_close,
 };
 
 static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
diff -puN drivers/input/serio/serio.c~new-set-of-input-patches-serio-open-close-optional drivers/input/serio/serio.c
--- 25/drivers/input/serio/serio.c~new-set-of-input-patches-serio-open-close-optional	2004-04-22 01:11:00.936148544 -0700
+++ 25-akpm/drivers/input/serio/serio.c	2004-04-22 01:11:00.946147024 -0700
@@ -290,7 +290,7 @@ void serio_unregister_device(struct seri
 int serio_open(struct serio *serio, struct serio_dev *dev)
 {
 	serio->dev = dev;
-	if (serio->open(serio)) {
+	if (serio->open && serio->open(serio)) {
 		serio->dev = NULL;
 		return -1;
 	}
@@ -300,7 +300,8 @@ int serio_open(struct serio *serio, stru
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
-	serio->close(serio);
+	if (serio->close)
+		serio->close(serio);
 	serio->dev = NULL;
 }
 
diff -puN drivers/input/serio/serport.c~new-set-of-input-patches-serio-open-close-optional drivers/input/serio/serport.c
--- 25/drivers/input/serio/serport.c~new-set-of-input-patches-serio-open-close-optional	2004-04-22 01:11:00.938148240 -0700
+++ 25-akpm/drivers/input/serio/serport.c	2004-04-22 01:11:00.947146872 -0700
@@ -48,11 +48,6 @@ static int serport_serio_write(struct se
 	return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
 }
 
-static int serport_serio_open(struct serio *serio)
-{
-        return 0;
-}
-
 static void serport_serio_close(struct serio *serio)
 {
 	struct serport *serport = serio->driver;
@@ -87,7 +82,6 @@ static int serport_ldisc_open(struct tty
 
 	serport->serio.type = SERIO_RS232;
 	serport->serio.write = serport_serio_write;
-	serport->serio.open = serport_serio_open;
 	serport->serio.close = serport_serio_close;
 	serport->serio.driver = serport;
 
@@ -135,7 +129,7 @@ static int serport_ldisc_room(struct tty
 }
 
 /*
- * serport_ldisc_read() just waits indefinitely if everything goes well. 
+ * serport_ldisc_read() just waits indefinitely if everything goes well.
  * However, when the serio driver closes the serio port, it finishes,
  * returning 0 characters.
  */
@@ -165,7 +159,7 @@ static ssize_t serport_ldisc_read(struct
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
-	
+
 	if (cmd == SPIOCSTYPE)
 		return get_user(serport->serio.type, (unsigned long *) arg);
 

_