linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATCH 2.6.11-rc4]: IBM TrackPoint configuration support
@ 2005-02-14  0:32 Stephen Evanchik
  2005-02-14  1:31 ` Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Evanchik @ 2005-02-14  0:32 UTC (permalink / raw)
  To: Vojtech Pavlik, Dmitry Torokhov, linux-kernel

Here is the latest IBM TrackPoint patch. I believe I made all of the
necessary changes in this release including the removal of the
middle-to-scroll functionality. One item I didn't address was a
comment about checking the return code of ps2_command ..

I looked at other usages and it wasn't clear to me how to actually
implement something that is sane. In some places an error causes a
return out of the function and in others the return value is ignored.
Should I check each return value or the first ?

Any comments are greatly appreciated. I have tested this on my T23 as
well as a T40 and T42p ..

Stephen


diff -uNr a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile	2005-02-13 12:47:32.000000000 -0500
+++ b/drivers/input/mouse/Makefile	2005-02-13 12:46:30.000000000 -0500
@@ -14,4 +14,4 @@
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.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 trackpoint.o
diff -uNr a/drivers/input/mouse/psmouse-base.c
b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2005-02-13 12:47:32.000000000 -0500
+++ b/drivers/input/mouse/psmouse-base.c	2005-02-13 17:33:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include "psmouse.h"
 #include "synaptics.h"
 #include "logips2pp.h"
+#include "trackpoint.h"
 #include "alps.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
@@ -482,6 +483,16 @@
 		return PSMOUSE_IMPS;
 
 /*
+ * Try to initialize the IBM TrackPoint
+ */
+	if (max_proto > PSMOUSE_PS2 && trackpoint_init(psmouse) == 0) {
+		psmouse->vendor = "IBM";
+		psmouse->name = "TrackPoint";
+ 
+		return PSMOUSE_PS2;
+	}
+
+/*
  * Okay, all failed, we have a standard mouse here. The number of the buttons
  * is still a question, though. We assume 3.
  */
diff -uNr a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
--- a/drivers/input/mouse/trackpoint.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/input/mouse/trackpoint.c	2005-02-13 19:26:09.000000000 -0500
@@ -0,0 +1,347 @@
+/*
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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.
+ *
+ * Trademarks are the property of their respective owners.
+ *
+ * 13/02/2005 - Removed middle button scroll, see Xorg for
+ *		scroll emulation.
+ *
+ * 03/02/2005 - Remove proc and module parameters
+ * 		Added sysfs attributes
+ *
+ * 29/01/2005 - Fixed UltraNav support
+ *		Moved to libps2 interface
+ *		Renamed internal property variables to be consistent with reference docs
+ *		Fixed negative inertia not being set properly
+ *		Added middle button scroll module parameter
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/serio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/libps2.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include "psmouse.h"
+#include "trackpoint.h"
+
+
+PSMOUSE_DEFINE_ATTR(sensitivity);
+PSMOUSE_DEFINE_ATTR(speed);
+PSMOUSE_DEFINE_ATTR(inertia);
+PSMOUSE_DEFINE_ATTR(reach);
+PSMOUSE_DEFINE_ATTR(draghys);
+PSMOUSE_DEFINE_ATTR(mindrag);
+PSMOUSE_DEFINE_ATTR(thresh);
+PSMOUSE_DEFINE_ATTR(upthresh);
+PSMOUSE_DEFINE_ATTR(ztime);
+PSMOUSE_DEFINE_ATTR(jenks);
+PSMOUSE_DEFINE_ATTR(ptson);
+PSMOUSE_DEFINE_ATTR(skipback);
+PSMOUSE_DEFINE_ATTR(mb);
+PSMOUSE_DEFINE_ATTR(ext_dev);
+PSMOUSE_DEFINE_ATTR(transparent);
+
+
+#define MAKE_ATTR_READ(_item) \
+        static ssize_t psmouse_attr_show_##_item(struct psmouse
*psmouse, char *buf) \
+        { \
+                struct trackpoint_data *tp = psmouse->private; \
+                return sprintf(buf, "%lu\n", (unsigned long)tp->_item); \
+        }
+
+#define MAKE_ATTR_WRITE(_item, command) \
+        static ssize_t psmouse_attr_set_##_item(struct psmouse
*psmouse, const char *buf, size_t count) \
+        { \
+		char *rest; \
+                unsigned long value; \
+                struct trackpoint_data *tp = psmouse->private; \
+                value = simple_strtoul(buf, &rest, 10); \
+		if(*rest) \
+			return -EINVAL; \
+		tp->_item = value; \
+                trackpoint_write(&psmouse->ps2dev, command, tp->_item); \
+                return count; \
+        }
+
+#define MAKE_ATTR_TOGGLE(_item, command, mask) \
+        static ssize_t psmouse_attr_set_##_item(struct psmouse
*psmouse, const char *buf, size_t count) \
+        { \
+                unsigned char toggle; \
+                struct trackpoint_data *tp = psmouse->private; \
+                toggle = (buf[0] == '1') ? 1 : 0; \
+                if( toggle != tp->_item) { \
+                        tp->_item = toggle; \
+                        trackpoint_toggle_bit(&psmouse->ps2dev,
command, mask); \
+                } \
+                return count; \
+        }
+
+
+/*
+ * Device IO: read, write and toggle bit
+ */
+static void trackpoint_command(struct ps2dev *ps2dev, unsigned char cmd)
+{	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, cmd));
+}
+
+static void trackpoint_read(struct ps2dev *ps2dev, unsigned char loc,
unsigned char *results)
+{
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc));
+}
+
+static void trackpoint_write(struct ps2dev *ps2dev, unsigned char
loc, unsigned char val)
+{	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, val));
+}
+
+static int trackpoint_toggle_bit(struct ps2dev *ps2dev, unsigned char
loc, unsigned char mask)
+{
+	/* Bad things will happen if the loc param isn't in this range */
+	if(loc < 0x20 || loc >= 0x2F)
+		return -1;
+	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_TOGGLE));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, mask));
+	
+	return 0;
+}
+
+
+MAKE_ATTR_WRITE(sensitivity, TP_SENS);
+MAKE_ATTR_READ(sensitivity);
+
+MAKE_ATTR_WRITE(speed, TP_SPEED);
+MAKE_ATTR_READ(speed);
+
+MAKE_ATTR_WRITE(inertia, TP_INERTIA);
+MAKE_ATTR_READ(inertia);
+
+MAKE_ATTR_WRITE(reach, TP_REACH);
+MAKE_ATTR_READ(reach);
+
+MAKE_ATTR_WRITE(draghys, TP_DRAGHYS);
+MAKE_ATTR_READ(draghys);
+
+MAKE_ATTR_WRITE(mindrag, TP_MINDRAG);
+MAKE_ATTR_READ(mindrag);
+
+MAKE_ATTR_WRITE(thresh, TP_THRESH);
+MAKE_ATTR_READ(thresh);
+
+MAKE_ATTR_WRITE(upthresh, TP_UP_THRESH);
+MAKE_ATTR_READ(upthresh);
+
+MAKE_ATTR_WRITE(ztime, TP_Z_TIME);
+MAKE_ATTR_READ(ztime);
+
+MAKE_ATTR_WRITE(jenks, TP_JENKS_CURV);
+MAKE_ATTR_READ(jenks);
+
+MAKE_ATTR_TOGGLE(ptson, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+MAKE_ATTR_READ(ptson);
+
+MAKE_ATTR_TOGGLE(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK);
+MAKE_ATTR_READ(skipback);
+
+MAKE_ATTR_TOGGLE(mb, TP_TOGGLE_MB, TP_MASK_MB);
+MAKE_ATTR_READ(mb);
+
+MAKE_ATTR_TOGGLE(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+MAKE_ATTR_READ(ext_dev);
+
+/* MAKE_ATTR_WRITE( ) for Soft Transparent mode */
+static ssize_t psmouse_attr_set_transparent(struct psmouse *psmouse,
const char *buf, size_t count)
+{
+	unsigned char command;
+
+	struct trackpoint_data *tp = psmouse->private;
+
+	tp->transparent = (buf[0] == '1') ? 1 : 0;
+
+	command = (tp->transparent) ? TP_SET_SOFT_TRANS : TP_CANCEL_SOFT_TRANS;
+
+	trackpoint_command(&psmouse->ps2dev, command);
+
+	return count;
+}
+
+MAKE_ATTR_READ(transparent);
+
+
+void trackpoint_disconnect(struct psmouse *psmouse)
+{
+	struct serio *serio = psmouse->ps2dev.serio;
+
+	device_remove_file(&serio->dev, &psmouse_attr_sensitivity);
+	device_remove_file(&serio->dev, &psmouse_attr_speed);
+	device_remove_file(&serio->dev, &psmouse_attr_inertia);
+	device_remove_file(&serio->dev, &psmouse_attr_reach);
+	device_remove_file(&serio->dev, &psmouse_attr_draghys);
+	device_remove_file(&serio->dev, &psmouse_attr_mindrag);
+	device_remove_file(&serio->dev, &psmouse_attr_thresh);
+	device_remove_file(&serio->dev, &psmouse_attr_upthresh);
+	device_remove_file(&serio->dev, &psmouse_attr_ztime);
+	device_remove_file(&serio->dev, &psmouse_attr_jenks);
+	device_remove_file(&serio->dev, &psmouse_attr_ptson);
+	device_remove_file(&serio->dev, &psmouse_attr_skipback);
+	device_remove_file(&serio->dev, &psmouse_attr_mb);
+	device_remove_file(&serio->dev, &psmouse_attr_ext_dev);
+	device_remove_file(&serio->dev, &psmouse_attr_transparent);
+
+	kfree(psmouse->private);
+
+	psmouse->private = NULL;
+}
+
+int trackpoint_sync(struct psmouse *psmouse)
+{
+	unsigned char toggle;
+	struct trackpoint_data *tp = psmouse->private;
+
+
+	/* Push the config to the device */
+	
+	trackpoint_write(&psmouse->ps2dev, TP_SENS, tp->sensitivity);
+	trackpoint_write(&psmouse->ps2dev, TP_INERTIA, tp->inertia);
+	trackpoint_write(&psmouse->ps2dev, TP_SPEED, tp->speed);
+
+	trackpoint_write(&psmouse->ps2dev, TP_REACH, tp->reach);
+	trackpoint_write(&psmouse->ps2dev, TP_DRAGHYS, tp->draghys);
+	trackpoint_write(&psmouse->ps2dev, TP_MINDRAG, tp->mindrag);
+
+	trackpoint_write(&psmouse->ps2dev, TP_THRESH, tp->thresh);
+	trackpoint_write(&psmouse->ps2dev, TP_UP_THRESH, tp->upthresh);
+
+	trackpoint_write(&psmouse->ps2dev, TP_Z_TIME, tp->ztime);
+	trackpoint_write(&psmouse->ps2dev, TP_JENKS_CURV, tp->jenks);
+
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_PTSON, &toggle);
+	if(((toggle & TP_MASK_PTSON) == TP_MASK_PTSON)!= tp->ptson)
+		 trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_MB, &toggle);
+	if(((toggle & TP_MASK_MB) == TP_MASK_MB) != tp->mb)
+		 trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_MB, TP_MASK_MB);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle);
+	if(((toggle & TP_MASK_TWOHAND) == TP_MASK_TWOHAND) != tp->twohand)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, TP_MASK_TWOHAND);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK, &toggle);
+	if(((toggle & TP_MASK_SKIPBACK) == TP_MASK_SKIPBACK) != tp->skipback)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK,
TP_MASK_SKIPBACK);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_MB, &toggle);
+	if(((toggle & TP_MASK_MB) == TP_MASK_MB) != tp->mb)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_MB, TP_MASK_MB);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG, &toggle);
+	if(((toggle & TP_MASK_SOURCE_TAG) == TP_MASK_SOURCE_TAG) != tp->source_tag)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG,
TP_MASK_SOURCE_TAG);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, &toggle);
+	if(((toggle & TP_MASK_EXT_DEV) == TP_MASK_EXT_DEV) != tp->skipback)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+
+
+
+	return 0;
+}
+
+static void trackpoint_defaults(struct trackpoint_data *tp)
+{
+	tp->ptson = TP_DEF_PTSON;
+	tp->sensitivity = TP_DEF_SENS;
+	tp->speed = TP_DEF_SPEED;
+	tp->reach = TP_DEF_REACH;
+
+	tp->draghys = TP_DEF_DRAGHYS;
+	tp->mindrag = TP_DEF_MINDRAG;
+
+	tp->thresh = TP_DEF_THRESH;
+	tp->upthresh = TP_DEF_UP_THRESH;
+
+	tp->ztime = TP_DEF_Z_TIME;
+	tp->jenks = TP_DEF_JENKS_CURV;
+
+	tp->mb = TP_DEF_MB;
+
+	tp->inertia = TP_DEF_INERTIA;
+	tp->skipback = TP_DEF_SKIPBACK;
+	tp->ext_dev = TP_DEF_EXT_DEV;
+}
+
+
+
+int trackpoint_init(struct psmouse *psmouse)
+{
+	unsigned char param[2];
+	struct trackpoint_data *priv;
+
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	struct serio *serio = ps2dev->serio;
+
+	param[0] = param[1] = 0;
+
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_DISABLE_EXT));
+
+	ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID));
+
+	if(param[0] != TP_MAGIC_IDENT) 
+		return -1;
+
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_ENABLE_EXT));
+
+	psmouse->private = priv = kmalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
+
+	if(!priv) 
+		return -1;
+
+	memset(priv, 0, sizeof(struct trackpoint_data));
+
+	priv->firmware_id = param[1];
+	trackpoint_defaults(priv);
+
+	trackpoint_sync(psmouse);
+
+	psmouse->reconnect = trackpoint_init;
+	psmouse->disconnect = trackpoint_disconnect;
+
+	device_create_file(&serio->dev, &psmouse_attr_sensitivity);
+	device_create_file(&serio->dev, &psmouse_attr_speed);
+	device_create_file(&serio->dev, &psmouse_attr_inertia);
+	device_create_file(&serio->dev, &psmouse_attr_reach);
+	device_create_file(&serio->dev, &psmouse_attr_draghys);
+	device_create_file(&serio->dev, &psmouse_attr_mindrag);
+	device_create_file(&serio->dev, &psmouse_attr_thresh);
+	device_create_file(&serio->dev, &psmouse_attr_upthresh);
+	device_create_file(&serio->dev, &psmouse_attr_ztime);
+	device_create_file(&serio->dev, &psmouse_attr_jenks);
+	device_create_file(&serio->dev, &psmouse_attr_ptson);
+	device_create_file(&serio->dev, &psmouse_attr_skipback);
+	device_create_file(&serio->dev, &psmouse_attr_mb);
+	device_create_file(&serio->dev, &psmouse_attr_ext_dev);
+	device_create_file(&serio->dev, &psmouse_attr_transparent);
+
+	printk(KERN_INFO "IBM TrackPoint firmware: 0x%02X\n", param[1]);
+
+	return 0;
+}
+
diff -uNr a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
--- a/drivers/input/mouse/trackpoint.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/input/mouse/trackpoint.h	2005-02-13 19:27:30.000000000 -0500
@@ -0,0 +1,157 @@
+/*
+ * IBM TrackPoint PS/2 mouse driver
+ *
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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 _TRACKPOINT_H
+#define _TRACKPOINT_H
+
+/*
+ * These constants are from the TrackPoint System
+ * Engineering documentation Version 4 from IBM Watson
+ * research:
+ * 	http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
+ */
+
+#define TP_COMMAND	(0xE2)	/* Commands start with this */
+
+#define TP_READ_ID	(0xE1)	/* Sent for device identification */
+#define TP_MAGIC_IDENT	(0x01)	/* Sent after a TP_READ_ID followed */
+				/* by the firmware ID */
+
+
+/*
+ * Commands
+ */
+#define TP_RECALIB	(0x51)	/* Recalibrate */
+#define TP_POWER_DOWN	(0x44)	/* Can only be undone through HW reset */
+#define TP_EXT_DEV	(0x21)	/* Determines if external device is connected (RO) */
+#define TP_EXT_BTN	(0x4B)	/* Read extended button status */
+#define TP_POR		(0x7F)	/* Execute Power on Reset */
+#define TP_POR_RESULTS	(0x25)	/* Read Power on Self test results */
+#define TP_DISABLE_EXT	(0x40)	/* Disable external pointing device */
+#define TP_ENABLE_EXT	(0x41)	/* Enable external pointing device */
+
+/*
+ * Mode manipulation
+ */
+#define TP_SET_SOFT_TRANS (0x4E) /* Set mode */
+#define TP_CANCEL_SOFT_TRANS (0xB9) /* Cancel mode */
+#define TP_SET_HARD_TRANS (0x45) /* Mode can only be set */
+
+
+/*
+ * Register oriented commands/properties
+ */
+#define TP_WRITE_MEM	(0x81)
+#define TP_READ_MEM	(0x80)	/* Not used in this implementation */
+
+/*
+* RAM Locations for properties
+ */
+#define TP_SENS		(0x4A)	/* Sensitivity */
+#define TP_MB 		(0x4C)	/* Read Middle Button Status (RO) */
+#define TP_INERTIA	(0x4D)	/* Negative Inertia */
+#define TP_SPEED	(0x60)	/* Speed of TP Cursor */
+#define TP_REACH	(0x57)	/* Backup for Z-axis press */
+#define TP_DRAGHYS	(0x58)	/* Drag Hysteresis */
+				/* (how hard it is to drag */
+				/* with Z-axis pressed) */
+
+#define TP_MINDRAG	(0x59)	/* Minimum amount of force needed */
+				/* to trigger dragging */
+
+#define TP_THRESH	(0x5C)	/* Minimum value for a Z-axis press */
+#define TP_UP_THRESH	(0x5A)	/* Used to generate a 'click' on Z-axis */
+#define TP_Z_TIME	(0x5E)	/* How sharp of a press */
+#define TP_JENKS_CURV	(0x5D)	/* Minimum curvature for double click */
+
+/*
+ * Toggling Flag bits
+ */
+#define TP_TOGGLE (0x47) /* Toggle command */
+
+#define TP_TOGGLE_MB		(0x23)	/* Disable/Enable Middle Button */
+#define TP_TOGGLE_DRIFT		(0x23)	/* Drift Correction */
+#define TP_TOGGLE_BURST		(0x28)	/* Burst Mode */
+#define TP_TOGGLE_PTSON		(0x2C)	/* Press to Select */
+#define TP_TOGGLE_HARD_TRANS	(0x2C)	/* Alternate method to set Hard
Transparency */
+#define TP_TOGGLE_TWOHAND	(0x2D)	/* Two handed */
+#define TP_TOGGLE_STICKY_TWO	(0x2D)	/* Sticky two handed */
+#define TP_TOGGLE_SKIPBACK	(0x2D)	/* Suppress movement */
+					/* after drag release */
+#define TP_TOGGLE_EXT_DEV	(0x23)  /* Toggle external device */
+#define TP_TOGGLE_SOURCE_TAG	(0x20)  /* Bit 3 of the first packet
will be set to
+					   to the origin of the packet (external or TP) */
+
+/*
+ * Various makses for registers 
+ * XOR'd to current contents for new value
+ */
+#define TP_MASK_PTSON		(0x01)
+#define TP_MASK_SKIPBACK	(0x08)
+#define TP_MASK_TWOHAND		(0x01)
+#define TP_MASK_STICKY_TWO	(0x04)
+#define TP_MASK_HARD_TRANS	(0x80)
+#define TP_MASK_BURST		(0x80)
+#define TP_MASK_MB		(0x01)
+#define TP_MASK_DRIFT		(0x80)
+#define TP_MASK_EXT_DEV		(0x02)
+#define TP_MASK_SOURCE_TAG	(0x80)
+
+/* Power on Self Test Results */
+#define TP_POR_SUCCESS		(0x3B)
+
+/*
+ * Default power on values
+ */
+#define TP_DEF_SENS	(0x80)
+#define TP_DEF_INERTIA	(0x06)
+#define TP_DEF_SPEED	(0x61)
+#define TP_DEF_REACH	(0x0A)
+
+#define TP_DEF_DRAGHYS   (0xFF)
+#define TP_DEF_MINDRAG	 (0x14)
+
+#define TP_DEF_THRESH     (0x08)
+#define TP_DEF_UP_THRESH  (0xFF)
+#define TP_DEF_Z_TIME     (0x26)
+#define TP_DEF_JENKS_CURV (0x87)
+
+/* Toggles */
+#define TP_DEF_MB	 (0x00)
+#define TP_DEF_PTSON	 (0x00)
+#define TP_DEF_SKIPBACK  (0x00)
+#define TP_DEF_EXT_DEV   (0x01)
+
+#define MAKE_PS2_CMD(params, results, cmd) ((params<<12) |
(results<<8) | (cmd))
+
+
+
+struct trackpoint_data
+{
+	unsigned char firmware_id;
+
+	unsigned char sensitivity, speed, inertia, reach;
+	unsigned char draghys, mindrag;
+	unsigned char thresh, upthresh;
+	unsigned char ztime, jenks;
+
+	unsigned char ptson; /* Press to Select */
+	unsigned char twohand, skipback;
+	unsigned char mb;
+
+	unsigned char ext_dev;
+	unsigned char transparent;
+	unsigned char source_tag;
+
+};
+
+extern int trackpoint_init (struct psmouse *psmouse);
+
+#endif /* _TRACKPOINT_H */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH 2.6.11-rc4]: IBM TrackPoint configuration support
  2005-02-14  0:32 PATCH 2.6.11-rc4]: IBM TrackPoint configuration support Stephen Evanchik
@ 2005-02-14  1:31 ` Dmitry Torokhov
  2005-02-15 14:16   ` Vojtech Pavlik
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2005-02-14  1:31 UTC (permalink / raw)
  To: Stephen Evanchik; +Cc: Vojtech Pavlik, linux-kernel

On Sunday 13 February 2005 19:32, Stephen Evanchik wrote:
> Here is the latest IBM TrackPoint patch. I believe I made all of the
> necessary changes in this release including the removal of the
> middle-to-scroll functionality. One item I didn't address was a
> comment about checking the return code of ps2_command ..
> 
> I looked at other usages and it wasn't clear to me how to actually
> implement something that is sane. In some places an error causes a
> return out of the function and in others the return value is ignored.
> Should I check each return value or the first ?

I would check all 3 ps2_command calls in trackpoint_init and leave
the rest as is.

One more thing - I'd like to see more descriptive names of sysfs
attributes, for example I'd change "ptson" to "press_to_select",
"mb" to "middle_btn", etc.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH 2.6.11-rc4]: IBM TrackPoint configuration support
  2005-02-14  1:31 ` Dmitry Torokhov
@ 2005-02-15 14:16   ` Vojtech Pavlik
  2005-02-16  4:13     ` Stephen Evanchik
  0 siblings, 1 reply; 5+ messages in thread
From: Vojtech Pavlik @ 2005-02-15 14:16 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Stephen Evanchik, linux-kernel

On Sun, Feb 13, 2005 at 08:31:01PM -0500, Dmitry Torokhov wrote:
> On Sunday 13 February 2005 19:32, Stephen Evanchik wrote:
> > Here is the latest IBM TrackPoint patch. I believe I made all of the
> > necessary changes in this release including the removal of the
> > middle-to-scroll functionality. One item I didn't address was a
> > comment about checking the return code of ps2_command ..
> > 
> > I looked at other usages and it wasn't clear to me how to actually
> > implement something that is sane. In some places an error causes a
> > return out of the function and in others the return value is ignored.
> > Should I check each return value or the first ?
> 
> I would check all 3 ps2_command calls in trackpoint_init and leave
> the rest as is.
> 
> One more thing - I'd like to see more descriptive names of sysfs
> attributes, for example I'd change "ptson" to "press_to_select",
> "mb" to "middle_btn", etc.
 
Stephen, if you fix the above, and send me the patch, I'll merge it,
there isn't any other problem with it.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH 2.6.11-rc4]: IBM TrackPoint configuration support
  2005-02-15 14:16   ` Vojtech Pavlik
@ 2005-02-16  4:13     ` Stephen Evanchik
  2005-02-16  5:20       ` Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Evanchik @ 2005-02-16  4:13 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Dmitry Torokhov, linux-kernel

On Tue, 15 Feb 2005 15:16:18 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
 
> Stephen, if you fix the above, and send me the patch, I'll merge it,
> there isn't any other problem with it.

Ok, more descriptive names, I noticed that psmouse->disconnect wasn't
being called when my laptop suspended so I made the reconnect function
sync the in memory configuration with what is actually on the device.

Also, I removed the external port disable commands in trackpoint_init
-- they didn't seem to do anything on my T23.



Stephen


diff -uNr a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile	2005-02-13 12:47:32.000000000 -0500
+++ b/drivers/input/mouse/Makefile	2005-02-13 12:46:30.000000000 -0500
@@ -14,4 +14,4 @@
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.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 trackpoint.o
diff -uNr a/drivers/input/mouse/psmouse-base.c
b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2005-02-13 12:47:32.000000000 -0500
+++ b/drivers/input/mouse/psmouse-base.c	2005-02-13 17:33:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include "psmouse.h"
 #include "synaptics.h"
 #include "logips2pp.h"
+#include "trackpoint.h"
 #include "alps.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
@@ -482,6 +483,16 @@
 		return PSMOUSE_IMPS;
 
 /*
+ * Try to initialize the IBM TrackPoint
+ */
+	if (max_proto > PSMOUSE_PS2 && trackpoint_init(psmouse) == 0) {
+		psmouse->vendor = "IBM";
+		psmouse->name = "TrackPoint";
+ 
+		return PSMOUSE_PS2;
+	}
+
+/*
  * Okay, all failed, we have a standard mouse here. The number of the buttons
  * is still a question, though. We assume 3.
  */
diff -uNr a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
--- a/drivers/input/mouse/trackpoint.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/input/mouse/trackpoint.c	2005-02-15 23:05:08.000000000 -0500
@@ -0,0 +1,344 @@
+/*
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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.
+ *
+ * Trademarks are the property of their respective owners.
+ *
+ * 13/02/2005 - Removed middle button scroll, see Xorg for
+ *		scroll emulation.
+ *
+ * 03/02/2005 - Remove proc and module parameters
+ * 		Added sysfs attributes
+ *
+ * 29/01/2005 - Fixed UltraNav support
+ *		Moved to libps2 interface
+ *		Renamed internal property variables to be consistent with reference docs
+ *		Fixed negative inertia not being set properly
+ *		Added middle button scroll module parameter
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/serio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/libps2.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include "psmouse.h"
+#include "trackpoint.h"
+
+
+PSMOUSE_DEFINE_ATTR(sensitivity);
+PSMOUSE_DEFINE_ATTR(speed);
+PSMOUSE_DEFINE_ATTR(inertia);
+PSMOUSE_DEFINE_ATTR(reach);
+PSMOUSE_DEFINE_ATTR(draghys);
+PSMOUSE_DEFINE_ATTR(mindrag);
+PSMOUSE_DEFINE_ATTR(thresh);
+PSMOUSE_DEFINE_ATTR(upthresh);
+PSMOUSE_DEFINE_ATTR(ztime);
+PSMOUSE_DEFINE_ATTR(jenks);
+PSMOUSE_DEFINE_ATTR(press_to_select);
+PSMOUSE_DEFINE_ATTR(skipback);
+PSMOUSE_DEFINE_ATTR(middle_btn_disable);
+PSMOUSE_DEFINE_ATTR(ext_dev);
+PSMOUSE_DEFINE_ATTR(transparent);
+
+
+#define MAKE_ATTR_READ(_item) \
+        static ssize_t psmouse_attr_show_##_item(struct psmouse
*psmouse, char *buf) \
+        { \
+                struct trackpoint_data *tp = psmouse->private; \
+                return sprintf(buf, "%lu\n", (unsigned long)tp->_item); \
+        }
+
+#define MAKE_ATTR_WRITE(_item, command) \
+        static ssize_t psmouse_attr_set_##_item(struct psmouse
*psmouse, const char *buf, size_t count) \
+        { \
+		char *rest; \
+                unsigned long value; \
+                struct trackpoint_data *tp = psmouse->private; \
+                value = simple_strtoul(buf, &rest, 10); \
+		if(*rest) \
+			return -EINVAL; \
+		tp->_item = value; \
+                trackpoint_write(&psmouse->ps2dev, command, tp->_item); \
+                return count; \
+        }
+
+#define MAKE_ATTR_TOGGLE(_item, command, mask) \
+        static ssize_t psmouse_attr_set_##_item(struct psmouse
*psmouse, const char *buf, size_t count) \
+        { \
+                unsigned char toggle; \
+                struct trackpoint_data *tp = psmouse->private; \
+                toggle = (buf[0] == '1') ? 1 : 0; \
+                if( toggle != tp->_item) { \
+                        tp->_item = toggle; \
+                        trackpoint_toggle_bit(&psmouse->ps2dev,
command, mask); \
+                } \
+                return count; \
+        }
+
+
+/*
+ * Device IO: read, write and toggle bit
+ */
+static void trackpoint_command(struct ps2dev *ps2dev, unsigned char cmd)
+{	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, cmd));
+}
+
+static void trackpoint_read(struct ps2dev *ps2dev, unsigned char loc,
unsigned char *results)
+{
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc));
+}
+
+static void trackpoint_write(struct ps2dev *ps2dev, unsigned char
loc, unsigned char val)
+{	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, val));
+}
+
+static int trackpoint_toggle_bit(struct ps2dev *ps2dev, unsigned char
loc, unsigned char mask)
+{
+	/* Bad things will happen if the loc param isn't in this range */
+	if(loc < 0x20 || loc >= 0x2F)
+		return -1;
+	
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_TOGGLE));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc));
+	ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, mask));
+	
+	return 0;
+}
+
+
+MAKE_ATTR_WRITE(sensitivity, TP_SENS);
+MAKE_ATTR_READ(sensitivity);
+
+MAKE_ATTR_WRITE(speed, TP_SPEED);
+MAKE_ATTR_READ(speed);
+
+MAKE_ATTR_WRITE(inertia, TP_INERTIA);
+MAKE_ATTR_READ(inertia);
+
+MAKE_ATTR_WRITE(reach, TP_REACH);
+MAKE_ATTR_READ(reach);
+
+MAKE_ATTR_WRITE(draghys, TP_DRAGHYS);
+MAKE_ATTR_READ(draghys);
+
+MAKE_ATTR_WRITE(mindrag, TP_MINDRAG);
+MAKE_ATTR_READ(mindrag);
+
+MAKE_ATTR_WRITE(thresh, TP_THRESH);
+MAKE_ATTR_READ(thresh);
+
+MAKE_ATTR_WRITE(upthresh, TP_UP_THRESH);
+MAKE_ATTR_READ(upthresh);
+
+MAKE_ATTR_WRITE(ztime, TP_Z_TIME);
+MAKE_ATTR_READ(ztime);
+
+MAKE_ATTR_WRITE(jenks, TP_JENKS_CURV);
+MAKE_ATTR_READ(jenks);
+
+MAKE_ATTR_TOGGLE(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+MAKE_ATTR_READ(press_to_select);
+
+MAKE_ATTR_TOGGLE(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK);
+MAKE_ATTR_READ(skipback);
+
+MAKE_ATTR_TOGGLE(middle_btn_disable, TP_TOGGLE_MB, TP_MASK_MB);
+MAKE_ATTR_READ(middle_btn_disable);
+
+MAKE_ATTR_TOGGLE(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+MAKE_ATTR_READ(ext_dev);
+
+/* MAKE_ATTR_WRITE( ) for Soft Transparent mode */
+static ssize_t psmouse_attr_set_transparent(struct psmouse *psmouse,
const char *buf, size_t count)
+{
+	unsigned char command;
+
+	struct trackpoint_data *tp = psmouse->private;
+
+	tp->transparent = (buf[0] == '1') ? 1 : 0;
+
+	command = (tp->transparent) ? TP_SET_SOFT_TRANS : TP_CANCEL_SOFT_TRANS;
+
+	trackpoint_command(&psmouse->ps2dev, command);
+
+	return count;
+}
+
+MAKE_ATTR_READ(transparent);
+
+
+static void trackpoint_disconnect(struct psmouse *psmouse)
+{
+	struct serio *serio = psmouse->ps2dev.serio;
+
+	device_remove_file(&serio->dev, &psmouse_attr_sensitivity);
+	device_remove_file(&serio->dev, &psmouse_attr_speed);
+	device_remove_file(&serio->dev, &psmouse_attr_inertia);
+	device_remove_file(&serio->dev, &psmouse_attr_reach);
+	device_remove_file(&serio->dev, &psmouse_attr_draghys);
+	device_remove_file(&serio->dev, &psmouse_attr_mindrag);
+	device_remove_file(&serio->dev, &psmouse_attr_thresh);
+	device_remove_file(&serio->dev, &psmouse_attr_upthresh);
+	device_remove_file(&serio->dev, &psmouse_attr_ztime);
+	device_remove_file(&serio->dev, &psmouse_attr_jenks);
+	device_remove_file(&serio->dev, &psmouse_attr_press_to_select);
+	device_remove_file(&serio->dev, &psmouse_attr_skipback);
+	device_remove_file(&serio->dev, &psmouse_attr_middle_btn_disable);
+	device_remove_file(&serio->dev, &psmouse_attr_ext_dev);
+	device_remove_file(&serio->dev, &psmouse_attr_transparent);
+
+	kfree(psmouse->private);
+
+	psmouse->private = NULL;
+}
+
+static int trackpoint_sync(struct psmouse *psmouse)
+{
+	unsigned char toggle;
+	struct trackpoint_data *tp = psmouse->private;
+
+
+	/* Push the config to the device */
+	
+	trackpoint_write(&psmouse->ps2dev, TP_SENS, tp->sensitivity);
+	trackpoint_write(&psmouse->ps2dev, TP_INERTIA, tp->inertia);
+	trackpoint_write(&psmouse->ps2dev, TP_SPEED, tp->speed);
+
+	trackpoint_write(&psmouse->ps2dev, TP_REACH, tp->reach);
+	trackpoint_write(&psmouse->ps2dev, TP_DRAGHYS, tp->draghys);
+	trackpoint_write(&psmouse->ps2dev, TP_MINDRAG, tp->mindrag);
+
+	trackpoint_write(&psmouse->ps2dev, TP_THRESH, tp->thresh);
+	trackpoint_write(&psmouse->ps2dev, TP_UP_THRESH, tp->upthresh);
+
+	trackpoint_write(&psmouse->ps2dev, TP_Z_TIME, tp->ztime);
+	trackpoint_write(&psmouse->ps2dev, TP_JENKS_CURV, tp->jenks);
+
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_PTSON, &toggle);
+	if(((toggle & TP_MASK_PTSON) == TP_MASK_PTSON)!= tp->press_to_select)
+		 trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_PTSON, TP_MASK_PTSON);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_MB, &toggle);
+	if(((toggle & TP_MASK_MB) == TP_MASK_MB) != tp->middle_btn_disable)
+		 trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_MB, TP_MASK_MB);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle);
+	if(((toggle & TP_MASK_TWOHAND) == TP_MASK_TWOHAND) != tp->twohand)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, TP_MASK_TWOHAND);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK, &toggle);
+	if(((toggle & TP_MASK_SKIPBACK) == TP_MASK_SKIPBACK) != tp->skipback)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SKIPBACK,
TP_MASK_SKIPBACK);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_MB, &toggle);
+	if(((toggle & TP_MASK_MB) == TP_MASK_MB) != tp->middle_btn_disable)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_MB, TP_MASK_MB);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG, &toggle);
+	if(((toggle & TP_MASK_SOURCE_TAG) == TP_MASK_SOURCE_TAG) != tp->source_tag)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_SOURCE_TAG,
TP_MASK_SOURCE_TAG);
+
+	trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, &toggle);
+	if(((toggle & TP_MASK_EXT_DEV) == TP_MASK_EXT_DEV) != tp->skipback)
+		trackpoint_toggle_bit(&psmouse->ps2dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+
+
+
+	return 0;
+}
+
+static void trackpoint_defaults(struct trackpoint_data *tp)
+{
+	tp->press_to_select = TP_DEF_PTSON;
+	tp->sensitivity = TP_DEF_SENS;
+	tp->speed = TP_DEF_SPEED;
+	tp->reach = TP_DEF_REACH;
+
+	tp->draghys = TP_DEF_DRAGHYS;
+	tp->mindrag = TP_DEF_MINDRAG;
+
+	tp->thresh = TP_DEF_THRESH;
+	tp->upthresh = TP_DEF_UP_THRESH;
+
+	tp->ztime = TP_DEF_Z_TIME;
+	tp->jenks = TP_DEF_JENKS_CURV;
+
+	tp->middle_btn_disable = TP_DEF_MB;
+
+	tp->inertia = TP_DEF_INERTIA;
+	tp->skipback = TP_DEF_SKIPBACK;
+	tp->ext_dev = TP_DEF_EXT_DEV;
+}
+
+
+
+int trackpoint_init(struct psmouse *psmouse)
+{
+	unsigned char param[2];
+	struct trackpoint_data *priv;
+
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	struct serio *serio = ps2dev->serio;
+
+	param[0] = param[1] = 0;
+
+	if(ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
+		return -1;
+
+	if(param[0] != TP_MAGIC_IDENT) 
+		return -1;
+
+	psmouse->private = priv = kmalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
+
+	if(!priv) 
+		return -1;
+
+	memset(priv, 0, sizeof(struct trackpoint_data));
+
+	priv->firmware_id = param[1];
+	trackpoint_defaults(priv);
+
+	trackpoint_sync(psmouse);
+
+	psmouse->reconnect = trackpoint_sync;
+	psmouse->disconnect = trackpoint_disconnect;
+
+	device_create_file(&serio->dev, &psmouse_attr_sensitivity);
+	device_create_file(&serio->dev, &psmouse_attr_speed);
+	device_create_file(&serio->dev, &psmouse_attr_inertia);
+	device_create_file(&serio->dev, &psmouse_attr_reach);
+	device_create_file(&serio->dev, &psmouse_attr_draghys);
+	device_create_file(&serio->dev, &psmouse_attr_mindrag);
+	device_create_file(&serio->dev, &psmouse_attr_thresh);
+	device_create_file(&serio->dev, &psmouse_attr_upthresh);
+	device_create_file(&serio->dev, &psmouse_attr_ztime);
+	device_create_file(&serio->dev, &psmouse_attr_jenks);
+	device_create_file(&serio->dev, &psmouse_attr_press_to_select);
+	device_create_file(&serio->dev, &psmouse_attr_skipback);
+	device_create_file(&serio->dev, &psmouse_attr_middle_btn_disable);
+	device_create_file(&serio->dev, &psmouse_attr_ext_dev);
+	device_create_file(&serio->dev, &psmouse_attr_transparent);
+
+	printk(KERN_INFO "IBM TrackPoint firmware: 0x%02X\n", param[1]);
+
+	return 0;
+}
+
diff -uNr a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
--- a/drivers/input/mouse/trackpoint.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/input/mouse/trackpoint.h	2005-02-15 22:59:49.000000000 -0500
@@ -0,0 +1,157 @@
+/*
+ * IBM TrackPoint PS/2 mouse driver
+ *
+ * Stephen Evanchik <evanchsa@gmail.com>
+ *
+ * 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 _TRACKPOINT_H
+#define _TRACKPOINT_H
+
+/*
+ * These constants are from the TrackPoint System
+ * Engineering documentation Version 4 from IBM Watson
+ * research:
+ * 	http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
+ */
+
+#define TP_COMMAND	(0xE2)	/* Commands start with this */
+
+#define TP_READ_ID	(0xE1)	/* Sent for device identification */
+#define TP_MAGIC_IDENT	(0x01)	/* Sent after a TP_READ_ID followed */
+				/* by the firmware ID */
+
+
+/*
+ * Commands
+ */
+#define TP_RECALIB	(0x51)	/* Recalibrate */
+#define TP_POWER_DOWN	(0x44)	/* Can only be undone through HW reset */
+#define TP_EXT_DEV	(0x21)	/* Determines if external device is connected (RO) */
+#define TP_EXT_BTN	(0x4B)	/* Read extended button status */
+#define TP_POR		(0x7F)	/* Execute Power on Reset */
+#define TP_POR_RESULTS	(0x25)	/* Read Power on Self test results */
+#define TP_DISABLE_EXT	(0x40)	/* Disable external pointing device */
+#define TP_ENABLE_EXT	(0x41)	/* Enable external pointing device */
+
+/*
+ * Mode manipulation
+ */
+#define TP_SET_SOFT_TRANS (0x4E) /* Set mode */
+#define TP_CANCEL_SOFT_TRANS (0xB9) /* Cancel mode */
+#define TP_SET_HARD_TRANS (0x45) /* Mode can only be set */
+
+
+/*
+ * Register oriented commands/properties
+ */
+#define TP_WRITE_MEM	(0x81)
+#define TP_READ_MEM	(0x80)	/* Not used in this implementation */
+
+/*
+* RAM Locations for properties
+ */
+#define TP_SENS		(0x4A)	/* Sensitivity */
+#define TP_MB 		(0x4C)	/* Read Middle Button Status (RO) */
+#define TP_INERTIA	(0x4D)	/* Negative Inertia */
+#define TP_SPEED	(0x60)	/* Speed of TP Cursor */
+#define TP_REACH	(0x57)	/* Backup for Z-axis press */
+#define TP_DRAGHYS	(0x58)	/* Drag Hysteresis */
+				/* (how hard it is to drag */
+				/* with Z-axis pressed) */
+
+#define TP_MINDRAG	(0x59)	/* Minimum amount of force needed */
+				/* to trigger dragging */
+
+#define TP_THRESH	(0x5C)	/* Minimum value for a Z-axis press */
+#define TP_UP_THRESH	(0x5A)	/* Used to generate a 'click' on Z-axis */
+#define TP_Z_TIME	(0x5E)	/* How sharp of a press */
+#define TP_JENKS_CURV	(0x5D)	/* Minimum curvature for double click */
+
+/*
+ * Toggling Flag bits
+ */
+#define TP_TOGGLE (0x47) /* Toggle command */
+
+#define TP_TOGGLE_MB		(0x23)	/* Disable/Enable Middle Button */
+#define TP_TOGGLE_DRIFT		(0x23)	/* Drift Correction */
+#define TP_TOGGLE_BURST		(0x28)	/* Burst Mode */
+#define TP_TOGGLE_PTSON		(0x2C)	/* Press to Select */
+#define TP_TOGGLE_HARD_TRANS	(0x2C)	/* Alternate method to set Hard
Transparency */
+#define TP_TOGGLE_TWOHAND	(0x2D)	/* Two handed */
+#define TP_TOGGLE_STICKY_TWO	(0x2D)	/* Sticky two handed */
+#define TP_TOGGLE_SKIPBACK	(0x2D)	/* Suppress movement */
+					/* after drag release */
+#define TP_TOGGLE_EXT_DEV	(0x23)  /* Toggle external device */
+#define TP_TOGGLE_SOURCE_TAG	(0x20)  /* Bit 3 of the first packet
will be set to
+					   to the origin of the packet (external or TP) */
+
+/*
+ * Various makses for registers 
+ * XOR'd to current contents for new value
+ */
+#define TP_MASK_PTSON		(0x01)
+#define TP_MASK_SKIPBACK	(0x08)
+#define TP_MASK_TWOHAND		(0x01)
+#define TP_MASK_STICKY_TWO	(0x04)
+#define TP_MASK_HARD_TRANS	(0x80)
+#define TP_MASK_BURST		(0x80)
+#define TP_MASK_MB		(0x01)
+#define TP_MASK_DRIFT		(0x80)
+#define TP_MASK_EXT_DEV		(0x02)
+#define TP_MASK_SOURCE_TAG	(0x80)
+
+/* Power on Self Test Results */
+#define TP_POR_SUCCESS		(0x3B)
+
+/*
+ * Default power on values
+ */
+#define TP_DEF_SENS	(0x80)
+#define TP_DEF_INERTIA	(0x06)
+#define TP_DEF_SPEED	(0x61)
+#define TP_DEF_REACH	(0x0A)
+
+#define TP_DEF_DRAGHYS   (0xFF)
+#define TP_DEF_MINDRAG	 (0x14)
+
+#define TP_DEF_THRESH     (0x08)
+#define TP_DEF_UP_THRESH  (0xFF)
+#define TP_DEF_Z_TIME     (0x26)
+#define TP_DEF_JENKS_CURV (0x87)
+
+/* Toggles */
+#define TP_DEF_MB	 (0x00)
+#define TP_DEF_PTSON	 (0x00)
+#define TP_DEF_SKIPBACK  (0x00)
+#define TP_DEF_EXT_DEV   (0x01)
+
+#define MAKE_PS2_CMD(params, results, cmd) ((params<<12) |
(results<<8) | (cmd))
+
+
+
+struct trackpoint_data
+{
+	unsigned char firmware_id;
+
+	unsigned char sensitivity, speed, inertia, reach;
+	unsigned char draghys, mindrag;
+	unsigned char thresh, upthresh;
+	unsigned char ztime, jenks;
+
+	unsigned char press_to_select;
+	unsigned char twohand, skipback;
+	unsigned char middle_btn_disable;
+
+	unsigned char ext_dev;
+	unsigned char transparent;
+	unsigned char source_tag;
+
+};
+
+extern int trackpoint_init (struct psmouse *psmouse);
+
+#endif /* _TRACKPOINT_H */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH 2.6.11-rc4]: IBM TrackPoint configuration support
  2005-02-16  4:13     ` Stephen Evanchik
@ 2005-02-16  5:20       ` Dmitry Torokhov
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry Torokhov @ 2005-02-16  5:20 UTC (permalink / raw)
  To: Stephen Evanchik; +Cc: Vojtech Pavlik, linux-kernel

Hi,

sorry, couple of more things (and I promise I will shut up ;))

>  /*
> + * Try to initialize the IBM TrackPoint
> + */
> +	if (max_proto > PSMOUSE_PS2 && trackpoint_init(psmouse) == 0) {
> +		psmouse->vendor = "IBM";
> +		psmouse->name = "TrackPoint";
> + 
> +		return PSMOUSE_PS2;
> +	}

I would like you to change the code so that psmouse structure only
changed when set_properties is set. Probably moving these into 
trackpoint_init is a good idea since _init should not override 
psmouse->private unless told to do so. It is important when the device
was not identified as a trackpoint but later (let's say after resume)
it is - in this case generic reconnect will cause psmouse_extensions
with set_properties = 0 to verify protocol and we dont' want to change
anything in psmouse to give the original disconnect handler change to
clean up properly.

Thinking about it some more I am pretty sure that you need a special
protocol number for the trackpoint, because protocol number is used
by psmouse_reconnect to check whether reconnect can be done or rescan
is needed. You can reuse the standard protocol handler, but you need
the new number. This way if trackpad was not identified as such first
time around, but is identified on reconnect psmouse-base would notice
that it is a new type of device and schedule reconnect and will proper
cleanup/initialization.

Does this make sense?

> +
> +#define MAKE_ATTR_WRITE(_item, command) \
> +        static ssize_t psmouse_attr_set_##_item(struct psmouse
> *psmouse, const char *buf, size_t count) \

It looks like the patch got mangled on it's way, please check your mail
client.

> +        { \
> +		char *rest; \
> +                unsigned long value; \
> +                struct trackpoint_data *tp = psmouse->private; \
> +                value = simple_strtoul(buf, &rest, 10); \

Whitespace damage (tabs vs. spaces). Also there are some trailing
whitespace. If you are using vi I find the following helpful to 
highlight the problem spots:

set listchars=tab:\|-
highlight WhitespaceEOL ctermbg=red guibg=red
match WhitespaceEOL /\s\+$/

-- 
Dmitry

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-02-16  5:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-14  0:32 PATCH 2.6.11-rc4]: IBM TrackPoint configuration support Stephen Evanchik
2005-02-14  1:31 ` Dmitry Torokhov
2005-02-15 14:16   ` Vojtech Pavlik
2005-02-16  4:13     ` Stephen Evanchik
2005-02-16  5:20       ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).