Re: [Hdaps-devel] [PATCH 2.6.23-rc2] hwmon: HP Mobile Data Protection System 3D ACPI driver (resend)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/29/07, Henrique de Moraes Holschuh <[email protected]> wrote:
> On Wed, 29 Aug 2007, Yan Burman wrote:

> HDAPS with input device support is quite new.  hdapsd was patched to talk to
> it, too.  I suppose we should port the input device support to the driver
> in-tree just so that we get it in tree as well.  Sounds like an useful
> reason to bother with in-tree hdaps.  Not that it will save much power with
> the in-tree driver, but at least it will be widely available from there.

In case they'll be of help for such porting, the relevant hdaps
patches from my tp_smapi patch series are attached.


> > I agree that the sys interface is probably not the best choice, but the
> > accelerometer data should provide not only position, but also generate
> > an event when it detects
> > that it's falling. From what I understood hdaps does not have that info,
>
> You can generate events on input devices, but I am not sure that's the best
> way to go about it for this.  Things that block on read until an interrupt
> happens might work better.

You can do the latter via another (4th) input device.


> I'd suggest an accelerometer sysfs interface, that we implement in hdaps
> (in and out-of-tree), ams and hpmdp.  One input device for joystick
> emulation (optional), one input device with accelerometer data in mg or ug,

Is any of the accelerometer drivers currently capable of computing the
physical acceleration? Also, is there an issue of linear vs. angular
acceleration?


> and an optional one with the raw accelerometer data.

Before or after axis inversion/swapping? The tp_smapi hdaps driver
(losslessly) inverts the raw data too, to avoid duplication of
model-specific orientation logic.


> unless someone wants to implement their own free-fall algorithms instead of
> using whatever is in the firmware).

The term "free-fall" is dangerously misleading, for the reasons
explained in the IBM APS whitepaper.

  Shem
hdaps: Add ID fields to the hdaps joystick-emulation input device

Minor ABI break: the input dev name changes from "hdaps" to a more
meaningful "ThinkPad HDAPS joystick emulation", following
Documentation/input/input-programming.txt. The
bus/vendor/product/version have been coordinated with the maintainer
of thinkpad_acpi (the other user of this bus/vendor namespace).

Signed-off-by: Shem Multinymous <[email protected]>
---
 drivers/hwmon/hdaps.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index ad92c0a..423f348 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -35,6 +35,7 @@
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
 #include <linux/thinkpad_ec.h>
+#include <linux/pci_ids.h>
 
 /* Embedded controller accelerometer read command and its result: */
 static const struct thinkpad_ec_row ec_accel_args =
@@ -62,9 +63,14 @@ static const struct thinkpad_ec_row ec_accel_args =
 #define HDAPS_INPUT_FLAT	4
 #define KMACT_REMEMBER_PERIOD   (HZ/10) /* keyboard/mouse persistance */
 
+/* Input IDs */
+#define HDAPS_INPUT_VENDOR	PCI_VENDOR_ID_IBM
+#define HDAPS_INPUT_PRODUCT	0x5054 /* "TP", shared with thinkpad_acpi */
+#define HDAPS_INPUT_JS_VERSION	0x6801 /* Joystick emulation input device */
+
 static struct timer_list hdaps_timer;
 static struct platform_device *pdev;
-static struct input_dev *hdaps_idev;
+static struct input_dev *hdaps_idev;     /* joystick-like device with fuzz */
 static unsigned int hdaps_invert;
 static int needs_calibration;
 
@@ -744,8 +750,13 @@ static int __init hdaps_init(void)
 	/* calibration for the input device (deferred to avoid delay) */
 	needs_calibration = 1;
 
-	/* initialize the input class */
-	hdaps_idev->name = "hdaps";
+	/* initialize the joystick-like fuzzed input device */
+	hdaps_idev->name = "ThinkPad HDAPS joystick emulation";
+	hdaps_idev->phys = "hdaps/input0";
+	hdaps_idev->id.bustype = BUS_HOST;
+	hdaps_idev->id.vendor  = HDAPS_INPUT_VENDOR;
+	hdaps_idev->id.product = HDAPS_INPUT_PRODUCT;
+	hdaps_idev->id.version = HDAPS_INPUT_JS_VERSION;
 	hdaps_idev->dev.parent = &pdev->dev;
 	hdaps_idev->evbit[0] = BIT(EV_ABS);
 	input_set_abs_params(hdaps_idev, ABS_X,
-- 
1.5.2.4

hdaps: Add a 2nd input device for raw accelerometer data

The current interface used for reading the HDAPS accelerometer
requires userspace daemons to poll a sysfs attribute. This causes
interrupts on tickless kernels, and introduces a phase difference
between the userspace->kernel polling and kernel->hardware polling.

To solve this, this patch introduces an input dev interface to the
accelerometer data. It differs from the existing hdaps input dev in
that it produces raw measurements, without fuzzing or calibration (but
with axis reversal, this the model-specific knowledge is already
encoded in the driver).

Signed-off-by: Shem Multinymous <[email protected]>
---
 drivers/hwmon/Kconfig |    7 ++++---
 drivers/hwmon/hdaps.c |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0780255..ab993fc 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -608,10 +608,11 @@ config SENSORS_HDAPS
 	  This driver provides support for the IBM Hard Drive Active Protection
 	  System (hdaps), which provides an accelerometer and other misc. data.
 	  ThinkPads starting with the R50, T41, and X40 are supported.  The
-	  accelerometer data is readable via sysfs.
+	  accelerometer data is readable via sysfs and via an input device.
 
-	  This driver also provides an absolute input class device, allowing
-	  the laptop to act as a pinball machine-esque joystick.
+	  This driver also provides another absolute input class device with
+	  calibration and fuzzing, allowing the laptop to act as a pinball
+	  machine-esque joystick.
 
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of hdaps.
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 423f348..47ee3f1 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -67,10 +67,12 @@ static const struct thinkpad_ec_row ec_accel_args =
 #define HDAPS_INPUT_VENDOR	PCI_VENDOR_ID_IBM
 #define HDAPS_INPUT_PRODUCT	0x5054 /* "TP", shared with thinkpad_acpi */
 #define HDAPS_INPUT_JS_VERSION	0x6801 /* Joystick emulation input device */
+#define HDAPS_INPUT_RAW_VERSION	0x4801 /* Raw accelerometer input device */
 
 static struct timer_list hdaps_timer;
 static struct platform_device *pdev;
 static struct input_dev *hdaps_idev;     /* joystick-like device with fuzz */
+static struct input_dev *hdaps_idev_raw; /* raw hdaps sensor readouts */
 static unsigned int hdaps_invert;
 static int needs_calibration;
 
@@ -477,6 +479,9 @@ keep_active:
 	input_report_abs(hdaps_idev, ABS_X, pos_x - rest_x);
 	input_report_abs(hdaps_idev, ABS_Y, pos_y - rest_y);
 	input_sync(hdaps_idev);
+	input_report_abs(hdaps_idev_raw, ABS_X, pos_x);
+	input_report_abs(hdaps_idev_raw, ABS_Y, pos_y);
+	input_sync(hdaps_idev_raw);
 	mod_timer(&hdaps_timer, jiffies + HZ/sampling_rate);
 }
 
@@ -747,6 +752,12 @@ static int __init hdaps_init(void)
 		goto out_group;
 	}
 
+	hdaps_idev_raw = input_allocate_device();
+	if (!hdaps_idev_raw) {
+		ret = -ENOMEM;
+		goto out_idev_first;
+	}
+
 	/* calibration for the input device (deferred to avoid delay) */
 	needs_calibration = 1;
 
@@ -768,12 +779,32 @@ static int __init hdaps_init(void)
 	if (ret)
 		goto out_idev;
 
+	/* initialize the raw data input device */
+	hdaps_idev_raw->name = "ThinkPad HDAPS accelerometer data";
+	hdaps_idev_raw->phys = "hdaps/input1";
+	hdaps_idev_raw->id.bustype = BUS_HOST;
+	hdaps_idev_raw->id.vendor  = HDAPS_INPUT_VENDOR;
+	hdaps_idev_raw->id.product = HDAPS_INPUT_PRODUCT;
+	hdaps_idev_raw->id.version = HDAPS_INPUT_RAW_VERSION;
+	hdaps_idev_raw->dev.parent = &pdev->dev;
+	hdaps_idev_raw->evbit[0] = BIT(EV_ABS);
+	input_set_abs_params(hdaps_idev_raw, ABS_X, -32768, 32767, 0, 0);
+	input_set_abs_params(hdaps_idev_raw, ABS_Y, -32768, 32767, 0, 0);
+
+	ret = input_register_device(hdaps_idev_raw);
+	if (ret)
+		goto out_idev_reg_first;
+
 	mod_timer(&hdaps_timer, jiffies + HZ/sampling_rate);
 
 	printk(KERN_INFO "hdaps: driver successfully loaded.\n");
 	return 0;
 
+out_idev_reg_first:
+	input_unregister_device(hdaps_idev);
 out_idev:
+	input_free_device(hdaps_idev_raw);
+out_idev_first:
 	input_free_device(hdaps_idev);
 out_group:
 	sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
@@ -790,6 +821,7 @@ out:
 static void __exit hdaps_exit(void)
 {
 	del_timer_sync(&hdaps_timer);
+	input_unregister_device(hdaps_idev_raw);
 	input_unregister_device(hdaps_idev);
 	hdaps_device_shutdown(); /* ignore errors, effect is negligible */
 	sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
-- 
1.5.2.4


[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux