[patch] updated hdaps driver.

2005-09-08 Thread Robert Love

Andrew,

Attached patch updates the hdaps driver in 2.6.13-mm2.  It is a drop-in
replacement for the current patch.

Changes: bug fixes and an absolute input device.

Thanks,

Robert Love


driver for hdaps

 MAINTAINERS|7 
 drivers/hwmon/Kconfig  |   17 +
 drivers/hwmon/Makefile |1 
 drivers/hwmon/hdaps.c  |  696 +
 4 files changed, 721 insertions(+)

diff -urN linux-2.6.13/drivers/hwmon/hdaps.c linux/drivers/hwmon/hdaps.c
--- linux-2.6.13/drivers/hwmon/hdaps.c  1969-12-31 19:00:00.0 -0500
+++ linux/drivers/hwmon/hdaps.c 2005-09-08 12:21:21.0 -0400
@@ -0,0 +1,696 @@
+/*
+ * drivers/hwmon/hdaps.c - driver for IBM's Hard Drive Active Protection System
+ *
+ * Copyright (C) 2005 Robert Love <[EMAIL PROTECTED]> 
+ * Copyright (C) 2005 Jesper Juhl <[EMAIL PROTECTED]> 
+ *
+ * The HardDisk Active Protection System (hdaps) is present in the IBM ThinkPad
+ * T41, T42, T43, R50, R50p, R51, and X40, at least.  It provides a basic
+ * two-axis accelerometer and other data, such as the device's temperature.
+ *
+ * This driver is based on the document by Mark A. Smith available at
+ * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial
+ * and error.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HDAPS_LOW_PORT 0x1600  /* first port used by hdaps */
+#define HDAPS_NR_PORTS 0x30/* number of ports: 0x1600 - 0x162f */
+
+#define HDAPS_PORT_STATE   0x1611  /* device state */
+#define HDAPS_PORT_YPOS0x1612  /* y-axis position */
+#defineHDAPS_PORT_XPOS 0x1614  /* x-axis position */
+#define HDAPS_PORT_TEMP1   0x1616  /* device temperature, in celcius */
+#define HDAPS_PORT_YVAR0x1617  /* y-axis variance (what is 
this?) */
+#define HDAPS_PORT_XVAR0x1619  /* x-axis variance (what is 
this?) */
+#define HDAPS_PORT_TEMP2   0x161b  /* device temperature (again?) */
+#define HDAPS_PORT_UNKNOWN 0x161c  /* what is this? */
+#define HDAPS_PORT_KMACT   0x161d  /* keyboard or mouse activity */
+
+#define STATE_FRESH0x50/* accelerometer data is fresh */
+
+#define KEYBD_MASK 0x20/* set if keyboard activity */
+#define MOUSE_MASK 0x40/* set if mouse activity */
+#define KEYBD_ISSET(n) (!! (n & KEYBD_MASK))   /* keyboard used? */
+#define MOUSE_ISSET(n) (!! (n & MOUSE_MASK))   /* mouse used? */
+
+#define INIT_TIMEOUT_MSECS 4000/* wait up to 4s for device init ... */
+#define INIT_WAIT_MSECS200 /* ... in 200ms increments */
+
+#define HDAPS_POLL_PERIOD  (HZ/20) /* poll for input every 1/20s */
+#define HDAPS_INPUT_FUZZ   4   /* input event threshold */
+
+static struct timer_list hdaps_timer;
+static unsigned int hdaps_mousedev;
+static unsigned int hdaps_invert;
+static u8 km_activity;
+static int rest_x;
+static int rest_y;
+
+static DECLARE_MUTEX(hdaps_sem);
+
+/*
+ * __get_latch - Get the value from a given port.  Callers must hold hdaps_sem.
+ */
+static inline u8 __get_latch(u16 port)
+{
+   return inb(port) & 0xff;
+}
+
+/*
+ * __check_latch - Check a port latch for a given value.  Returns zero if the
+ * port contains the given value.  Callers must hold hdaps_sem.
+ */
+static inline int __check_latch(u16 port, u8 val)
+{
+   if (__get_latch(port) == val)
+   return 0;
+   return -EINVAL;
+}
+
+/*
+ * __wait_latch - Wait up to 100us for a port latch to get a certain value,
+ * returning zero if the value is obtained.  Callers must hold hdaps_sem.
+ */
+static int __wait_latch(u16 port, u8 val)
+{
+   unsigned int i;
+
+   for (i = 0; i < 20; i++) {
+   if (!__check_latch(port, val))
+   return 0;
+   udelay(5);
+   }
+
+   return -EIO;
+}
+
+/*
+ * __device_refresh - request a refresh from the accelerometer.  Does not wait
+ * for refresh to complete.  Callers must hold hdaps_sem.
+ */
+static void __device_refresh(void)
+{
+   udelay(200);
+   if (inb(0x1604) != STATE_FRESH) {
+   outb(0x11, 0x1610);
+   outb(0x01, 0x161f);
+   }
+}
+
+/*
+ * __device_refresh_sync - request a synch

[patch] updated hdaps driver.

2005-08-31 Thread Robert Love
Below find an updated hdaps driver.

Various bug fixes, clean ups, additions to the DMI whitelist, and a new
automatic inversion detector (some ThinkPads have the axises negated).

Andrew, since a new 2.6-mm has yet to come out, feel free to replace the
original patch with this one.

Thanks,

Robert Love


Driver for the IBM Hard Drive Active Protection System (HDAPS), an
accelerometer found in most modern ThinkPads.

Signed-off-by: Robert Love <[EMAIL PROTECTED]>

diff -urN linux-2.6.13/drivers/hwmon/hdaps.c linux/drivers/hwmon/hdaps.c
--- linux-2.6.13/drivers/hwmon/hdaps.c  1969-12-31 19:00:00.0 -0500
+++ linux/drivers/hwmon/hdaps.c 2005-08-31 23:50:36.0 -0400
@@ -0,0 +1,739 @@
+/*
+ * drivers/hwmon/hdaps.c - driver for IBM's Hard Drive Active Protection System
+ *
+ * Copyright (C) 2005 Robert Love <[EMAIL PROTECTED]> 
+ * Copyright (C) 2005 Jesper Juhl <[EMAIL PROTECTED]> 
+ *
+ * The HardDisk Active Protection System (hdaps) is present in the IBM ThinkPad
+ * T41, T42, T43, R51, and X40, at least.  It provides a basic two-axis
+ * accelerometer and other data, such as the device's temperature.
+ *
+ * Based on the document by Mark A. Smith available at
+ * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial
+ * and error.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HDAPS_LOW_PORT 0x1600  /* first port used by hdaps */
+#define HDAPS_NR_PORTS 0x30/* 0x1600 - 0x162f */
+
+#define STATE_FRESH0x50/* accelerometer data is fresh */
+
+#define REFRESH_ASYNC  0x00/* do asynchronous refresh */
+#define REFRESH_SYNC   0x01/* do synchronous refresh */
+
+#define HDAPS_PORT_STATE   0x1611  /* device state */
+#define HDAPS_PORT_YPOS0x1612  /* y-axis position */
+#defineHDAPS_PORT_XPOS 0x1614  /* x-axis position */
+#define HDAPS_PORT_TEMP1   0x1616  /* device temperature, in celcius */
+#define HDAPS_PORT_YVAR0x1617  /* y-axis variance (what is 
this?) */
+#define HDAPS_PORT_XVAR0x1619  /* x-axis variance (what is 
this?) */
+#define HDAPS_PORT_TEMP2   0x161b  /* device temperature (again?) */
+#define HDAPS_PORT_UNKNOWN 0x161c  /* what is this? */
+#define HDAPS_PORT_KMACT   0x161d  /* keyboard or mouse activity */
+
+#define HDAPS_READ_MASK0xff/* some reads have the low 8 
bits set */
+
+#define KEYBD_MASK 0x20/* set if keyboard activity */
+#define MOUSE_MASK 0x40/* set if mouse activity */
+#define KEYBD_ISSET(n) (!! (n & KEYBD_MASK))   /* keyboard used? */
+#define MOUSE_ISSET(n) (!! (n & MOUSE_MASK))   /* mouse used? */
+
+#define INIT_TIMEOUT_MSECS 4000/* wait up to 4s for device init ... */
+#define INIT_WAIT_MSECS200 /* ... in 200ms increments */
+
+static struct platform_device *pdev;
+static struct input_dev hdaps_idev;
+static struct timer_list hdaps_timer;
+static unsigned int hdaps_mousedev_threshold = 4;
+static unsigned long hdaps_poll_ms = 50;
+static unsigned int hdaps_mousedev;
+static unsigned int hdaps_invert;
+static u8 km_activity;
+static int rest_x;
+static int rest_y;
+
+static DECLARE_MUTEX(hdaps_sem);
+
+/*
+ * __get_latch - Get the value from a given port.  Callers must hold hdaps_sem.
+ */
+static inline u8 __get_latch(u16 port)
+{
+   return inb(port) & HDAPS_READ_MASK;
+}
+
+/*
+ * __check_latch - Check a port latch for a given value.  Callers must hold
+ * hdaps_sem.  Returns zero if the port contains the given value.
+ */
+static inline unsigned int __check_latch(u16 port, u8 val)
+{
+   if (__get_latch(port) == val)
+   return 0;
+   return -EINVAL;
+}
+
+/*
+ * __wait_latch - Wait up to 100us for a port latch to get a certain value,
+ * returning zero if the value is obtained.  Callers must hold hdaps_sem.
+ */
+static unsigned int __wait_latch(u16 port, u8 val)
+{
+   unsigned int i;
+
+   for (i = 0; i < 20; i++) {
+   if (!__check_latch(port, val))
+   return 0;
+   udelay(5);
+   }
+
+   return -EINVAL;
+}
+
+/*
+ * __device_refresh - Request a refresh from the accelerometer.
+ *
+ * If sync is REF