All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support
@ 2011-03-24 22:02 Andy Ross
  2011-03-24 22:02 ` [PATCH 1/4] asus-laptop: Platform detection for Pegatron Lucid Andy Ross
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Andy Ross @ 2011-03-24 22:02 UTC (permalink / raw)
  To: Corentin Chary; +Cc: acpi4asus-user, platform-driver-x86

Accelerometer and ambient light sensor drivers for the Pegatron Lucid
(sold as WeTab and ExoPC) tablet PC.

This was submitted a while back, but got dropped before merge as we
were distracted by other projects.  The last change requested was to
fold the accelerometer driver into asus-laptop, which has been done
here.

Unfortunately there is one new wart: doing so causes initialization to
occur earlier, and we were seeing common panics underneath ACPI
initialization.  So I moved the accelerometer initialization out of
the ACPI startup call tree and into a separate platform driver (as it
was earlier when it was a separate module), which helped some.  But
occasional panics persisted, which I eventually tracked down to the
very first accelerometer reads.

Faking this initial report (which I *think* is being requested out of
the input polldev layer, not userspace) resulted in stable behavior.
This code has been running on a bunch of development systems for
several months now, so I feel as comfortable with the voodoo as I
think I can.

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

* [PATCH 1/4] asus-laptop: Platform detection for Pegatron Lucid
  2011-03-24 22:02 [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support Andy Ross
@ 2011-03-24 22:02 ` Andy Ross
  2011-03-24 22:02 ` [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor Andy Ross
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Andy Ross @ 2011-03-24 22:02 UTC (permalink / raw)
  To: Corentin Chary; +Cc: acpi4asus-user, platform-driver-x86

Recognize the Pegatron Lucid tablets by their method signatures.

Signed-off-by: Andy Ross <andy.ross@windriver.com>
---
 drivers/platform/x86/Kconfig       |   13 ++++++++-----
 drivers/platform/x86/asus-laptop.c |   23 ++++++++++++++++++++---
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index faec777..b6f983e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -62,12 +62,15 @@ config ASUS_LAPTOP
 	depends on INPUT
 	depends on RFKILL || RFKILL = n
 	select INPUT_SPARSEKMAP
+	select INPUT_POLLDEV
 	---help---
-	  This is the new Linux driver for Asus laptops. It may also support some
-	  MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
-	  standard ACPI events and input events. It also adds
-	  support for video output switching, LCD backlight control, Bluetooth and
-	  Wlan control, and most importantly, allows you to blink those fancy LEDs.
+	  This is a driver for Asus laptops and the Pegatron Lucid
+	  tablet. It may also support some MEDION, JVC or VICTOR
+	  laptops. It makes all the extra buttons generate standard
+	  ACPI events and input events. It also adds support for video
+	  output switching, LCD backlight control, Bluetooth and Wlan
+	  control, and most importantly, allows you to blink those
+	  fancy LEDs.
 
 	  For more information and a userspace daemon for handling the extra
 	  buttons see <http://acpi4asus.sf.net>.
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index d235f44..ec46d71 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
  *  Copyright (C) 2006-2007 Corentin Chary
+ *  Copyright (C) 2011 Wind River Systems
  *
  *  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
@@ -48,6 +49,7 @@
 #include <linux/uaccess.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
+#include <linux/input-polldev.h>
 #include <linux/rfkill.h>
 #include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
@@ -210,6 +212,12 @@ static char *display_get_paths[] = {
 #define METHOD_KBD_LIGHT_SET	"SLKB"
 #define METHOD_KBD_LIGHT_GET	"GLKB"
 
+/* For Pegatron Lucid tablet */
+#define DEVICE_NAME_PEGA	"Lucid"
+#define METHOD_PEGA_ENABLE	"ENPR"
+#define METHOD_PEGA_DISABLE	"DAPR"
+#define METHOD_PEGA_READ	"RDLN"
+
 /*
  * Define a specific led structure to keep the main structure clean
  */
@@ -246,6 +254,7 @@ struct asus_laptop {
 
 	int wireless_status;
 	bool have_rsts;
+	bool have_pega_lucid;
 	int lcd_state;
 
 	struct rfkill *gps_rfkill;
@@ -361,6 +370,14 @@ static int acpi_check_handle(acpi_handle handle, const char *method,
 	return 0;
 }
 
+static bool asus_check_pega_lucid(struct asus_laptop *asus)
+{
+	return !strcmp(asus->name, DEVICE_NAME_PEGA) &&
+	   !acpi_check_handle(asus->handle, METHOD_PEGA_ENABLE, NULL) &&
+	   !acpi_check_handle(asus->handle, METHOD_PEGA_DISABLE, NULL) &&
+	   !acpi_check_handle(asus->handle, METHOD_PEGA_READ, NULL);
+}
+
 /* Generic LED function */
 static int asus_led_set(struct asus_laptop *asus, const char *method,
 			 int value)
@@ -1334,7 +1351,6 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
 		   attr == &dev_attr_ls_level.attr) {
 		supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) &&
 			    !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL);
-
 	} else if (attr == &dev_attr_gps.attr) {
 		supported = !acpi_check_handle(handle, METHOD_GPS_ON, NULL) &&
 			    !acpi_check_handle(handle, METHOD_GPS_OFF, NULL) &&
@@ -1579,9 +1595,10 @@ static int __devinit asus_acpi_add(struct acpi_device *device)
 		goto fail_platform;
 
 	/*
-	 * Register the platform device first.  It is used as a parent for the
-	 * sub-devices below.
+	 * Need platform type detection first, then the platform
+	 * device.  It is used as a parent for the sub-devices below.
 	 */
+	asus->have_pega_lucid = asus_check_pega_lucid(asus);
 	result = asus_platform_init(asus);
 	if (result)
 		goto fail_platform;
-- 
1.7.1

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

* [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor
  2011-03-24 22:02 [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support Andy Ross
  2011-03-24 22:02 ` [PATCH 1/4] asus-laptop: Platform detection for Pegatron Lucid Andy Ross
@ 2011-03-24 22:02 ` Andy Ross
  2011-03-25  7:48   ` Corentin Chary
  2011-03-24 22:02 ` [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer Andy Ross
  2011-03-24 22:02 ` [PATCH 4/4] asus-laptop: allow boot time control of Pegatron ALS sensor Andy Ross
  3 siblings, 1 reply; 14+ messages in thread
From: Andy Ross @ 2011-03-24 22:02 UTC (permalink / raw)
  To: Corentin Chary; +Cc: acpi4asus-user, platform-driver-x86

Ambient light sensor for Pegatron Lucid.  Supports pre-existing
ls_switch sysfs interface to en/disable automatic control, and exports
the brightness from the device as "ls_value".

Signed-off-by: Andy Ross <andy.ross@windriver.com>
---
 drivers/platform/x86/asus-laptop.c |   70 +++++++++++++++++++++++++++++++++---
 1 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index ec46d71..6651d8c 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -214,9 +214,15 @@ static char *display_get_paths[] = {
 
 /* For Pegatron Lucid tablet */
 #define DEVICE_NAME_PEGA	"Lucid"
+
 #define METHOD_PEGA_ENABLE	"ENPR"
 #define METHOD_PEGA_DISABLE	"DAPR"
+#define PEGA_ALS	0x04
+#define PEGA_ALS_POWER	0x05
+
 #define METHOD_PEGA_READ	"RDLN"
+#define PEGA_READ_ALS_H	0x02
+#define PEGA_READ_ALS_L	0x03
 
 /*
  * Define a specific led structure to keep the main structure clean
@@ -378,6 +384,12 @@ static bool asus_check_pega_lucid(struct asus_laptop *asus)
 	   !acpi_check_handle(asus->handle, METHOD_PEGA_READ, NULL);
 }
 
+static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
+{
+	char *method = enable ? METHOD_PEGA_ENABLE : METHOD_PEGA_DISABLE;
+	return write_acpi_int(asus->handle, method, unit);
+}
+
 /* Generic LED function */
 static int asus_led_set(struct asus_laptop *asus, const char *method,
 			 int value)
@@ -1046,7 +1058,15 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
  */
 static void asus_als_switch(struct asus_laptop *asus, int value)
 {
-	if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value))
+	int ret;
+	if (asus->have_pega_lucid) {
+		ret = asus_pega_lucid_set(asus, PEGA_ALS, value);
+		if (!ret)
+			ret = asus_pega_lucid_set(asus, PEGA_ALS_POWER, value);
+	} else {
+		ret = write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value);
+	}
+	if (ret)
 		pr_warning("Error setting light sensor switch\n");
 	asus->light_switch = value;
 }
@@ -1103,6 +1123,35 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
 	return rv;
 }
 
+static int pega_int_read(struct asus_laptop *asus, int arg, int *result)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	int err = write_acpi_int_ret(asus->handle, METHOD_PEGA_READ, arg,
+				     &buffer);
+	if (!err) {
+		union acpi_object *obj = buffer.pointer;
+		if (obj && obj->type == ACPI_TYPE_INTEGER)
+			*result = obj->integer.value;
+		else
+			err = -EIO;
+	}
+	return err;
+}
+
+static ssize_t show_lsvalue(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+	int err, hi, lo;
+
+	err = pega_int_read(asus, PEGA_READ_ALS_H, &hi);
+	if (!err)
+		err = pega_int_read(asus, PEGA_READ_ALS_L, &lo);
+	if (!err)
+		return sprintf(buf, "%d\n", 10 * hi + lo);
+	return err;
+}
+
 /*
  * GPS
  */
@@ -1300,6 +1349,7 @@ static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
 static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
 static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
 static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
+static DEVICE_ATTR(ls_value, S_IRUGO, show_lsvalue, NULL);
 static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
 static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
 static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps);
@@ -1312,6 +1362,7 @@ static struct attribute *asus_attributes[] = {
 	&dev_attr_wwan.attr,
 	&dev_attr_display.attr,
 	&dev_attr_ledd.attr,
+	&dev_attr_ls_value.attr,
 	&dev_attr_ls_level.attr,
 	&dev_attr_ls_switch.attr,
 	&dev_attr_gps.attr,
@@ -1349,8 +1400,15 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
 
 	} else if (attr == &dev_attr_ls_switch.attr ||
 		   attr == &dev_attr_ls_level.attr) {
-		supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) &&
-			    !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL);
+		if (asus->have_pega_lucid) {
+			/* no ls_level interface on the Lucid */
+			supported = attr == &dev_attr_ls_switch.attr;
+		} else {
+			supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) &&
+				    !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL);
+		}
+	} else if (attr == &dev_attr_ls_value.attr) {
+		supported = asus->have_pega_lucid;
 	} else if (attr == &dev_attr_gps.attr) {
 		supported = !acpi_check_handle(handle, METHOD_GPS_ON, NULL) &&
 			    !acpi_check_handle(handle, METHOD_GPS_OFF, NULL) &&
@@ -1562,8 +1620,10 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
 	asus->light_switch = 0;	/* Default to light sensor disabled */
 	asus->light_level = 5;	/* level 5 for sensor sensitivity */
 
-	if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
-	    !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
+	if (asus->have_pega_lucid) {
+		asus_als_switch(asus, asus->light_switch);
+	} else if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
+		   !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
 		asus_als_switch(asus, asus->light_switch);
 		asus_als_level(asus, asus->light_level);
 	}
-- 
1.7.1

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

* [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-24 22:02 [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support Andy Ross
  2011-03-24 22:02 ` [PATCH 1/4] asus-laptop: Platform detection for Pegatron Lucid Andy Ross
  2011-03-24 22:02 ` [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor Andy Ross
@ 2011-03-24 22:02 ` Andy Ross
  2011-03-25 11:21   ` Corentin Chary
  2011-03-24 22:02 ` [PATCH 4/4] asus-laptop: allow boot time control of Pegatron ALS sensor Andy Ross
  3 siblings, 1 reply; 14+ messages in thread
From: Andy Ross @ 2011-03-24 22:02 UTC (permalink / raw)
  To: Corentin Chary; +Cc: acpi4asus-user, platform-driver-x86

Support the built-in accelerometer on the Lucid tablets as a standard
3-axis input device.

Signed-off-by: Andy Ross <andy.ross@windriver.com>
---
 drivers/platform/x86/Kconfig       |    9 ++-
 drivers/platform/x86/asus-laptop.c |  137 +++++++++++++++++++++++++++++++++++-
 2 files changed, 141 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b6f983e..43906f5 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -67,10 +67,11 @@ config ASUS_LAPTOP
 	  This is a driver for Asus laptops and the Pegatron Lucid
 	  tablet. It may also support some MEDION, JVC or VICTOR
 	  laptops. It makes all the extra buttons generate standard
-	  ACPI events and input events. It also adds support for video
-	  output switching, LCD backlight control, Bluetooth and Wlan
-	  control, and most importantly, allows you to blink those
-	  fancy LEDs.
+	  ACPI events and input events, and on the Lucid the built-in
+	  accelerometer appears as an input device.  It also adds
+	  support for video output switching, LCD backlight control,
+	  Bluetooth and Wlan control, and most importantly, allows you
+	  to blink those fancy LEDs.
 
 	  For more information and a userspace daemon for handling the extra
 	  buttons see <http://acpi4asus.sf.net>.
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 6651d8c..9b07368 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -224,6 +224,14 @@ static char *display_get_paths[] = {
 #define PEGA_READ_ALS_H	0x02
 #define PEGA_READ_ALS_L	0x03
 
+#define PEGA_ACCEL_NAME "pega_accel"
+#define PEGA_ACCEL_DESC "Pegatron Lucid Tablet Accelerometer"
+#define METHOD_XLRX "XLRX"
+#define METHOD_XLRY "XLRY"
+#define METHOD_XLRZ "XLRZ"
+#define PEGA_ACC_CLAMP 512 /* 1G accel is reported as ~256, so clamp to 2G */
+#define PEGA_ACC_RETRIES 3
+
 /*
  * Define a specific led structure to keep the main structure clean
  */
@@ -249,6 +257,7 @@ struct asus_laptop {
 
 	struct input_dev *inputdev;
 	struct key_entry *keymap;
+	struct input_polled_dev *pega_accel_poll;
 
 	struct asus_led mled;
 	struct asus_led tled;
@@ -262,6 +271,10 @@ struct asus_laptop {
 	bool have_rsts;
 	bool have_pega_lucid;
 	int lcd_state;
+	bool pega_acc_live;
+	int pega_acc_x;
+	int pega_acc_y;
+	int pega_acc_z;
 
 	struct rfkill *gps_rfkill;
 
@@ -390,6 +403,99 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
 	return write_acpi_int(asus->handle, method, unit);
 }
 
+static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
+{
+	int i, delta;
+	unsigned long long val;
+	for (i = 0; i < PEGA_ACC_RETRIES; i++) {
+		acpi_evaluate_integer(asus->handle, method, NULL, &val);
+
+		/* The output is noisy.  From reading the ASL
+		 * dissassembly, timeout errors are returned with 1's
+		 * in the high word, and the lack of locking around
+		 * thei hi/lo byte reads means that a transition
+		 * between (for example) -1 and 0 could be read as
+		 * 0xff00 or 0x00ff. */
+		delta = abs(curr - (short)val);
+		if (delta < 128 && !(val & ~0xffff))
+			break;
+	}
+	return clamp_val((short)val, -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP);
+}
+
+static void pega_accel_poll(struct input_polled_dev *ipd)
+{
+	struct device *parent = ipd->input->dev.parent;
+	struct asus_laptop *asus = dev_get_drvdata(parent);
+
+	/* In some cases, the very first call to poll causes a
+	 * recursive fault under the polldev worker.  This is
+	 * apparently related to very early userspace access to the
+	 * device, and perhaps a firmware bug.  See related comments
+	 * in asus_platform_probe regarding the fragility of these
+	 * methods early in the boot.  Fake the first report. */
+	if (!asus->pega_acc_live) {
+		asus->pega_acc_live = true;
+		input_report_abs(ipd->input, ABS_X, 0);
+		input_report_abs(ipd->input, ABS_Y, 0);
+		input_report_abs(ipd->input, ABS_Z, 0);
+		input_sync(ipd->input);
+		return;
+	}
+
+	asus->pega_acc_x = pega_acc_axis(asus, asus->pega_acc_x, METHOD_XLRX);
+	asus->pega_acc_y = pega_acc_axis(asus, asus->pega_acc_y, METHOD_XLRY);
+	asus->pega_acc_z = pega_acc_axis(asus, asus->pega_acc_z, METHOD_XLRZ);
+
+	/* Note transform, convert to "right/up/out" in the native
+	 * landscape orientation (i.e. the vector is the direction of
+	 * "real up" in the device's cartiesian coordinates). */
+	input_report_abs(ipd->input, ABS_X, -asus->pega_acc_x);
+	input_report_abs(ipd->input, ABS_Y, -asus->pega_acc_y);
+	input_report_abs(ipd->input, ABS_Z,  asus->pega_acc_z);
+	input_sync(ipd->input);
+}
+
+static void pega_accel_probe(struct asus_laptop *asus)
+{
+	int err;
+	struct input_polled_dev *ipd;
+
+	if (!asus->have_pega_lucid ||
+	    acpi_check_handle(asus->handle, METHOD_XLRX, NULL) ||
+	    acpi_check_handle(asus->handle, METHOD_XLRY, NULL) ||
+	    acpi_check_handle(asus->handle, METHOD_XLRZ, NULL))
+		return;
+
+	ipd = input_allocate_polled_device();
+	if (!ipd)
+		return;
+
+	ipd->poll = pega_accel_poll;
+	ipd->poll_interval = 125;
+	ipd->poll_interval_min = 50;
+	ipd->poll_interval_max = 2000;
+
+	ipd->input->name = PEGA_ACCEL_DESC;
+	ipd->input->phys = PEGA_ACCEL_NAME "/input0";
+	ipd->input->dev.parent = &asus->platform_device->dev;
+	ipd->input->id.bustype = BUS_HOST;
+
+	set_bit(EV_ABS, ipd->input->evbit);
+	input_set_abs_params(ipd->input, ABS_X,
+			     -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
+	input_set_abs_params(ipd->input, ABS_Y,
+			     -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
+	input_set_abs_params(ipd->input, ABS_Z,
+			     -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
+
+	err = input_register_polled_device(ipd);
+	if (err)
+		input_free_polled_device(ipd);
+	else
+		asus->pega_accel_poll = ipd;
+}
+
 /* Generic LED function */
 static int asus_led_set(struct asus_laptop *asus, const char *method,
 			 int value)
@@ -1459,11 +1565,40 @@ static void asus_platform_exit(struct asus_laptop *asus)
 	platform_device_unregister(asus->platform_device);
 }
 
+static int asus_platform_probe(struct platform_device *pd)
+{
+	struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
+
+	/* This is instantiated during platform driver initialization
+	 * becuase if it's done from underneath asus_acpi_add(), the
+	 * resulting input device can be grabbed by an early userspace
+	 * reader before ACPI initialization is finished and something
+	 * oopses underneath the acpi_evaluate_integer() call out of
+	 * pega_accel_poll().  Firmware bug? */
+	pega_accel_probe(asus);
+
+	return 0;
+}
+
+static int __devexit asus_platform_remove(struct platform_device *pd)
+{
+	struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
+	if (asus->pega_accel_poll) {
+		input_unregister_polled_device(asus->pega_accel_poll);
+		input_free_polled_device(asus->pega_accel_poll);
+	}
+	asus->pega_accel_poll = NULL;
+	return 0;
+}
+
+
 static struct platform_driver platform_driver = {
 	.driver = {
 		.name = ASUS_LAPTOP_FILE,
 		.owner = THIS_MODULE,
-	}
+	},
+	.probe  = asus_platform_probe,
+	.remove = asus_platform_remove,
 };
 
 static int asus_handle_init(char *name, acpi_handle * handle,
-- 
1.7.1

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

* [PATCH 4/4] asus-laptop: allow boot time control of Pegatron ALS sensor
  2011-03-24 22:02 [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support Andy Ross
                   ` (2 preceding siblings ...)
  2011-03-24 22:02 ` [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer Andy Ross
@ 2011-03-24 22:02 ` Andy Ross
  3 siblings, 0 replies; 14+ messages in thread
From: Andy Ross @ 2011-03-24 22:02 UTC (permalink / raw)
  To: Corentin Chary; +Cc: acpi4asus-user, platform-driver-x86

Signed-off-by: Andy Ross <andy.ross@windriver.com>
---
 drivers/platform/x86/asus-laptop.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 9b07368..1d32457 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -85,6 +85,7 @@ static int wlan_status = 1;
 static int bluetooth_status = 1;
 static int wimax_status = -1;
 static int wwan_status = -1;
+static int als_status = -1;
 
 module_param(wlan_status, int, 0444);
 MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
@@ -106,6 +107,11 @@ MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
 		 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
 		 "default is 1");
 
+module_param(als_status, int, 0444);
+MODULE_PARM_DESC(als_status, "Set the ALS status on boot "
+		 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+		 "default is 0");
+
 /*
  * Some events we use, same for all Asus
  */
@@ -1752,7 +1758,7 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
 	asus->ledd_status = 0xFFF;
 
 	/* Set initial values of light sensor and level */
-	asus->light_switch = 0;	/* Default to light sensor disabled */
+	asus->light_switch = als_status >= 0 ? !!als_status : 0;
 	asus->light_level = 5;	/* level 5 for sensor sensitivity */
 
 	if (asus->have_pega_lucid) {
-- 
1.7.1

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

* Re: [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor
  2011-03-24 22:02 ` [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor Andy Ross
@ 2011-03-25  7:48   ` Corentin Chary
  0 siblings, 0 replies; 14+ messages in thread
From: Corentin Chary @ 2011-03-25  7:48 UTC (permalink / raw)
  To: Andy Ross; +Cc: acpi4asus-user, platform-driver-x86

On Thu, Mar 24, 2011 at 11:02 PM, Andy Ross <andy.ross@windriver.com> wrote:
> Ambient light sensor for Pegatron Lucid.  Supports pre-existing
> ls_switch sysfs interface to en/disable automatic control, and exports
> the brightness from the device as "ls_value".
>
> Signed-off-by: Andy Ross <andy.ross@windriver.com>
> ---
>  drivers/platform/x86/asus-laptop.c |   70 +++++++++++++++++++++++++++++++++---
>  1 files changed, 65 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
> index ec46d71..6651d8c 100644
> --- a/drivers/platform/x86/asus-laptop.c
> +++ b/drivers/platform/x86/asus-laptop.c
> @@ -214,9 +214,15 @@ static char *display_get_paths[] = {
>
>  /* For Pegatron Lucid tablet */
>  #define DEVICE_NAME_PEGA       "Lucid"
> +
>  #define METHOD_PEGA_ENABLE     "ENPR"
>  #define METHOD_PEGA_DISABLE    "DAPR"
> +#define PEGA_ALS       0x04
> +#define PEGA_ALS_POWER 0x05
> +
>  #define METHOD_PEGA_READ       "RDLN"
> +#define PEGA_READ_ALS_H        0x02
> +#define PEGA_READ_ALS_L        0x03
>
>  /*
>  * Define a specific led structure to keep the main structure clean
> @@ -378,6 +384,12 @@ static bool asus_check_pega_lucid(struct asus_laptop *asus)
>           !acpi_check_handle(asus->handle, METHOD_PEGA_READ, NULL);
>  }
>
> +static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
> +{
> +       char *method = enable ? METHOD_PEGA_ENABLE : METHOD_PEGA_DISABLE;
> +       return write_acpi_int(asus->handle, method, unit);
> +}
> +
>  /* Generic LED function */
>  static int asus_led_set(struct asus_laptop *asus, const char *method,
>                         int value)
> @@ -1046,7 +1058,15 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
>  */
>  static void asus_als_switch(struct asus_laptop *asus, int value)
>  {
> -       if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value))
> +       int ret;
> +       if (asus->have_pega_lucid) {
> +               ret = asus_pega_lucid_set(asus, PEGA_ALS, value);
> +               if (!ret)
> +                       ret = asus_pega_lucid_set(asus, PEGA_ALS_POWER, value);
> +       } else {
> +               ret = write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value);
> +       }
> +       if (ret)
>                pr_warning("Error setting light sensor switch\n");
>        asus->light_switch = value;
>  }
> @@ -1103,6 +1123,35 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
>        return rv;
>  }
>
> +static int pega_int_read(struct asus_laptop *asus, int arg, int *result)
> +{
> +       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> +       int err = write_acpi_int_ret(asus->handle, METHOD_PEGA_READ, arg,
> +                                    &buffer);
> +       if (!err) {
> +               union acpi_object *obj = buffer.pointer;

I think a kfree(buffer.pointer); is missing here.

> +               if (obj && obj->type == ACPI_TYPE_INTEGER)
> +                       *result = obj->integer.value;
> +               else
> +                       err = -EIO;
> +       }
> +       return err;
> +}
> +
> +static ssize_t show_lsvalue(struct device *dev,
> +                           struct device_attribute *attr, char *buf)
> +{
> +       struct asus_laptop *asus = dev_get_drvdata(dev);
> +       int err, hi, lo;
> +
> +       err = pega_int_read(asus, PEGA_READ_ALS_H, &hi);
> +       if (!err)
> +               err = pega_int_read(asus, PEGA_READ_ALS_L, &lo);
> +       if (!err)
> +               return sprintf(buf, "%d\n", 10 * hi + lo);
> +       return err;
> +}
> +
>  /*
>  * GPS
>  */
> @@ -1300,6 +1349,7 @@ static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
>  static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
>  static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
>  static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
> +static DEVICE_ATTR(ls_value, S_IRUGO, show_lsvalue, NULL);

Could you document that new file in
Documentation/ABI/testing/sysfs-platform-asus-laptop ?

>  static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
>  static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
>  static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps);
> @@ -1312,6 +1362,7 @@ static struct attribute *asus_attributes[] = {
>        &dev_attr_wwan.attr,
>        &dev_attr_display.attr,
>        &dev_attr_ledd.attr,
> +       &dev_attr_ls_value.attr,
>        &dev_attr_ls_level.attr,
>        &dev_attr_ls_switch.attr,
>        &dev_attr_gps.attr,
> @@ -1349,8 +1400,15 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
>
>        } else if (attr == &dev_attr_ls_switch.attr ||
>                   attr == &dev_attr_ls_level.attr) {
> -               supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) &&
> -                           !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL);
> +               if (asus->have_pega_lucid) {
> +                       /* no ls_level interface on the Lucid */
> +                       supported = attr == &dev_attr_ls_switch.attr;
> +               } else {
> +                       supported = !acpi_check_handle(handle, METHOD_ALS_CONTROL, NULL) &&
> +                                   !acpi_check_handle(handle, METHOD_ALS_LEVEL, NULL);
> +               }
> +       } else if (attr == &dev_attr_ls_value.attr) {
> +               supported = asus->have_pega_lucid;
>        } else if (attr == &dev_attr_gps.attr) {
>                supported = !acpi_check_handle(handle, METHOD_GPS_ON, NULL) &&
>                            !acpi_check_handle(handle, METHOD_GPS_OFF, NULL) &&
> @@ -1562,8 +1620,10 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
>        asus->light_switch = 0; /* Default to light sensor disabled */
>        asus->light_level = 5;  /* level 5 for sensor sensitivity */
>
> -       if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
> -           !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
> +       if (asus->have_pega_lucid) {
> +               asus_als_switch(asus, asus->light_switch);
> +       } else if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
> +                  !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
>                asus_als_switch(asus, asus->light_switch);
>                asus_als_level(asus, asus->light_level);
>        }
> --
> 1.7.1
>
>



-- 
Corentin Chary
http://xf.iksaif.net

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-24 22:02 ` [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer Andy Ross
@ 2011-03-25 11:21   ` Corentin Chary
  2011-03-28  5:43     ` Dmitry Torokhov
  2011-03-28  6:41     ` Corentin Chary
  0 siblings, 2 replies; 14+ messages in thread
From: Corentin Chary @ 2011-03-25 11:21 UTC (permalink / raw)
  To: Andy Ross
  Cc: acpi4asus-user, platform-driver-x86, Dmitry Torokhov,
	Matthew Garrett

Ccing Dmitry and Matthew, they may want to comment that one.

On Thu, Mar 24, 2011 at 11:02 PM, Andy Ross <andy.ross@windriver.com> wrote:
> Support the built-in accelerometer on the Lucid tablets as a standard
> 3-axis input device.
>
> Signed-off-by: Andy Ross <andy.ross@windriver.com>
> ---
>  drivers/platform/x86/Kconfig       |    9 ++-
>  drivers/platform/x86/asus-laptop.c |  137 +++++++++++++++++++++++++++++++++++-
>  2 files changed, 141 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index b6f983e..43906f5 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -67,10 +67,11 @@ config ASUS_LAPTOP
>          This is a driver for Asus laptops and the Pegatron Lucid
>          tablet. It may also support some MEDION, JVC or VICTOR
>          laptops. It makes all the extra buttons generate standard
> -         ACPI events and input events. It also adds support for video
> -         output switching, LCD backlight control, Bluetooth and Wlan
> -         control, and most importantly, allows you to blink those
> -         fancy LEDs.
> +         ACPI events and input events, and on the Lucid the built-in
> +         accelerometer appears as an input device.  It also adds
> +         support for video output switching, LCD backlight control,
> +         Bluetooth and Wlan control, and most importantly, allows you
> +         to blink those fancy LEDs.
>
>          For more information and a userspace daemon for handling the extra
>          buttons see <http://acpi4asus.sf.net>.
> diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
> index 6651d8c..9b07368 100644
> --- a/drivers/platform/x86/asus-laptop.c
> +++ b/drivers/platform/x86/asus-laptop.c
> @@ -224,6 +224,14 @@ static char *display_get_paths[] = {
>  #define PEGA_READ_ALS_H        0x02
>  #define PEGA_READ_ALS_L        0x03
>
> +#define PEGA_ACCEL_NAME "pega_accel"
> +#define PEGA_ACCEL_DESC "Pegatron Lucid Tablet Accelerometer"
> +#define METHOD_XLRX "XLRX"
> +#define METHOD_XLRY "XLRY"
> +#define METHOD_XLRZ "XLRZ"
> +#define PEGA_ACC_CLAMP 512 /* 1G accel is reported as ~256, so clamp to 2G */
> +#define PEGA_ACC_RETRIES 3
> +
>  /*
>  * Define a specific led structure to keep the main structure clean
>  */
> @@ -249,6 +257,7 @@ struct asus_laptop {
>
>        struct input_dev *inputdev;
>        struct key_entry *keymap;
> +       struct input_polled_dev *pega_accel_poll;
>
>        struct asus_led mled;
>        struct asus_led tled;
> @@ -262,6 +271,10 @@ struct asus_laptop {
>        bool have_rsts;
>        bool have_pega_lucid;
>        int lcd_state;
> +       bool pega_acc_live;
> +       int pega_acc_x;
> +       int pega_acc_y;
> +       int pega_acc_z;
>
>        struct rfkill *gps_rfkill;
>
> @@ -390,6 +403,99 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
>        return write_acpi_int(asus->handle, method, unit);
>  }
>
> +static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
> +{
> +       int i, delta;
> +       unsigned long long val;
> +       for (i = 0; i < PEGA_ACC_RETRIES; i++) {
> +               acpi_evaluate_integer(asus->handle, method, NULL, &val);
> +
> +               /* The output is noisy.  From reading the ASL
> +                * dissassembly, timeout errors are returned with 1's
> +                * in the high word, and the lack of locking around
> +                * thei hi/lo byte reads means that a transition
> +                * between (for example) -1 and 0 could be read as
> +                * 0xff00 or 0x00ff. */
> +               delta = abs(curr - (short)val);
> +               if (delta < 128 && !(val & ~0xffff))
> +                       break;
> +       }
> +       return clamp_val((short)val, -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP);
> +}

Wow :/ How long is an acpi_evaluate_integer call here ?

> +static int asus_platform_probe(struct platform_device *pd)
> +{
> +       struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
> +
> +       /* This is instantiated during platform driver initialization
> +        * becuase if it's done from underneath asus_acpi_add(), the
> +        * resulting input device can be grabbed by an early userspace
> +        * reader before ACPI initialization is finished and something
> +        * oopses underneath the acpi_evaluate_integer() call out of
> +        * pega_accel_poll().  Firmware bug? */
> +       pega_accel_probe(asus);
> +
> +       return 0;
> +}

When is asus_platform_probe called exactly ? Because I'd say it's
called during asus_platform_probe(), and that doesn't fix your issue
right ?

-- 
Corentin Chary
http://xf.iksaif.net

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-25 11:21   ` Corentin Chary
@ 2011-03-28  5:43     ` Dmitry Torokhov
  2011-03-28 15:36       ` Andy Ross
  2011-03-28  6:41     ` Corentin Chary
  1 sibling, 1 reply; 14+ messages in thread
From: Dmitry Torokhov @ 2011-03-28  5:43 UTC (permalink / raw)
  To: Corentin Chary
  Cc: Andy Ross, acpi4asus-user, platform-driver-x86, Matthew Garrett

On Fri, Mar 25, 2011 at 12:21:20PM +0100, Corentin Chary wrote:
> Ccing Dmitry and Matthew, they may want to comment that one.
> 
> On Thu, Mar 24, 2011 at 11:02 PM, Andy Ross <andy.ross@windriver.com> wrote:
> > +static int asus_platform_probe(struct platform_device *pd)
> > +{
> > +       struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
> > +
> > +       /* This is instantiated during platform driver initialization
> > +        * becuase if it's done from underneath asus_acpi_add(), the
> > +        * resulting input device can be grabbed by an early userspace
> > +        * reader before ACPI initialization is finished and something
> > +        * oopses underneath the acpi_evaluate_integer() call out of
> > +        * pega_accel_poll().  Firmware bug? */
> > +       pega_accel_probe(asus);
> > +
> > +       return 0;
> > +}
> 
> When is asus_platform_probe called exactly ? Because I'd say it's
> called during asus_platform_probe(), and that doesn't fix your issue
> right ?

This I do not quite understand... Do we bind acpi drivers to devices
before ACPI initialization is done? Then this should be fixed in ACPI
layer, but I doubt even early userspace is active at the time ACPI core
is being initialized. Also, input polling is done in a separate thread
so you not moving the poll out of ACPI binding thread but delay poll
execution by a few microseconds...

-- 
Dmitry

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-25 11:21   ` Corentin Chary
  2011-03-28  5:43     ` Dmitry Torokhov
@ 2011-03-28  6:41     ` Corentin Chary
  1 sibling, 0 replies; 14+ messages in thread
From: Corentin Chary @ 2011-03-28  6:41 UTC (permalink / raw)
  To: Andy Ross
  Cc: acpi4asus-user, platform-driver-x86, Dmitry Torokhov,
	Matthew Garrett

On Fri, Mar 25, 2011 at 12:21 PM, Corentin Chary
<corentin.chary@gmail.com> wrote:
> Ccing Dmitry and Matthew, they may want to comment that one.
>
> On Thu, Mar 24, 2011 at 11:02 PM, Andy Ross <andy.ross@windriver.com> wrote:
>> Support the built-in accelerometer on the Lucid tablets as a standard
>> 3-axis input device.
>>
>> Signed-off-by: Andy Ross <andy.ross@windriver.com>
>> ---
>>  drivers/platform/x86/Kconfig       |    9 ++-
>>  drivers/platform/x86/asus-laptop.c |  137 +++++++++++++++++++++++++++++++++++-
>>  2 files changed, 141 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index b6f983e..43906f5 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -67,10 +67,11 @@ config ASUS_LAPTOP
>>          This is a driver for Asus laptops and the Pegatron Lucid
>>          tablet. It may also support some MEDION, JVC or VICTOR
>>          laptops. It makes all the extra buttons generate standard
>> -         ACPI events and input events. It also adds support for video
>> -         output switching, LCD backlight control, Bluetooth and Wlan
>> -         control, and most importantly, allows you to blink those
>> -         fancy LEDs.
>> +         ACPI events and input events, and on the Lucid the built-in
>> +         accelerometer appears as an input device.  It also adds
>> +         support for video output switching, LCD backlight control,
>> +         Bluetooth and Wlan control, and most importantly, allows you
>> +         to blink those fancy LEDs.
>>
>>          For more information and a userspace daemon for handling the extra
>>          buttons see <http://acpi4asus.sf.net>.
>> diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
>> index 6651d8c..9b07368 100644
>> --- a/drivers/platform/x86/asus-laptop.c
>> +++ b/drivers/platform/x86/asus-laptop.c
>> @@ -224,6 +224,14 @@ static char *display_get_paths[] = {
>>  #define PEGA_READ_ALS_H        0x02
>>  #define PEGA_READ_ALS_L        0x03
>>
>> +#define PEGA_ACCEL_NAME "pega_accel"
>> +#define PEGA_ACCEL_DESC "Pegatron Lucid Tablet Accelerometer"
>> +#define METHOD_XLRX "XLRX"
>> +#define METHOD_XLRY "XLRY"
>> +#define METHOD_XLRZ "XLRZ"
>> +#define PEGA_ACC_CLAMP 512 /* 1G accel is reported as ~256, so clamp to 2G */
>> +#define PEGA_ACC_RETRIES 3
>> +
>>  /*
>>  * Define a specific led structure to keep the main structure clean
>>  */
>> @@ -249,6 +257,7 @@ struct asus_laptop {
>>
>>        struct input_dev *inputdev;
>>        struct key_entry *keymap;
>> +       struct input_polled_dev *pega_accel_poll;
>>
>>        struct asus_led mled;
>>        struct asus_led tled;
>> @@ -262,6 +271,10 @@ struct asus_laptop {
>>        bool have_rsts;
>>        bool have_pega_lucid;
>>        int lcd_state;
>> +       bool pega_acc_live;
>> +       int pega_acc_x;
>> +       int pega_acc_y;
>> +       int pega_acc_z;
>>
>>        struct rfkill *gps_rfkill;
>>
>> @@ -390,6 +403,99 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
>>        return write_acpi_int(asus->handle, method, unit);
>>  }
>>
>> +static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
>> +{
>> +       int i, delta;
>> +       unsigned long long val;
>> +       for (i = 0; i < PEGA_ACC_RETRIES; i++) {
>> +               acpi_evaluate_integer(asus->handle, method, NULL, &val);
>> +
>> +               /* The output is noisy.  From reading the ASL
>> +                * dissassembly, timeout errors are returned with 1's
>> +                * in the high word, and the lack of locking around
>> +                * thei hi/lo byte reads means that a transition
>> +                * between (for example) -1 and 0 could be read as
>> +                * 0xff00 or 0x00ff. */
>> +               delta = abs(curr - (short)val);
>> +               if (delta < 128 && !(val & ~0xffff))
>> +                       break;
>> +       }
>> +       return clamp_val((short)val, -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP);
>> +}
>
> Wow :/ How long is an acpi_evaluate_integer call here ?
>
>> +static int asus_platform_probe(struct platform_device *pd)
>> +{
>> +       struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
>> +
>> +       /* This is instantiated during platform driver initialization
>> +        * becuase if it's done from underneath asus_acpi_add(), the
>> +        * resulting input device can be grabbed by an early userspace
>> +        * reader before ACPI initialization is finished and something
>> +        * oopses underneath the acpi_evaluate_integer() call out of
>> +        * pega_accel_poll().  Firmware bug? */
>> +       pega_accel_probe(asus);
>> +
>> +       return 0;
>> +}
>
> When is asus_platform_probe called exactly ? Because I'd say it's
> called during asus_platform_probe(), and that doesn't fix your issue
> right ?



On Mon, Mar 28, 2011 at 7:43 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Fri, Mar 25, 2011 at 12:21:20PM +0100, Corentin Chary wrote:
>> Ccing Dmitry and Matthew, they may want to comment that one.
>>
>> On Thu, Mar 24, 2011 at 11:02 PM, Andy Ross <andy.ross@windriver.com> wrote:
>> > +static int asus_platform_probe(struct platform_device *pd)
>> > +{
>> > +       struct asus_laptop *asus = dev_get_drvdata(&pd->dev);
>> > +
>> > +       /* This is instantiated during platform driver initialization
>> > +        * becuase if it's done from underneath asus_acpi_add(), the
>> > +        * resulting input device can be grabbed by an early userspace
>> > +        * reader before ACPI initialization is finished and something
>> > +        * oopses underneath the acpi_evaluate_integer() call out of
>> > +        * pega_accel_poll().  Firmware bug? */
>> > +       pega_accel_probe(asus);
>> > +
>> > +       return 0;
>> > +}
>>
>> When is asus_platform_probe called exactly ? Because I'd say it's
>> called during asus_platform_probe(), and that doesn't fix your issue
>> right ?

I meant during *asus_platform_init()* (which is called by
asus_acpi_add()), not *asus_platform_probe()*


-- 
Corentin Chary
http://xf.iksaif.net

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-28  5:43     ` Dmitry Torokhov
@ 2011-03-28 15:36       ` Andy Ross
  2011-03-31  7:23         ` Corentin Chary
  0 siblings, 1 reply; 14+ messages in thread
From: Andy Ross @ 2011-03-28 15:36 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Corentin Chary, acpi4asus-user, platform-driver-x86,
	Matthew Garrett

[combined responses for clarity]

Corentin Chary wrote:
> Wow :/ How long is an acpi_evaluate_integer call here ?

Early on I benchmarked the per-axis ACPI calls about about 50us, which
is shockingly high to me.  But honestly that note there is just
pedantry: the hi/lo race (and the fact that "errors" live in the same
space with valid data values) is a real condition that lets me justify
the "retry on large deltas" behavior, which most definitely improves
data quality.

> When is asus_platform_probe called exactly ? Because I'd say it's
> called during asus_platform_probe(), and that doesn't fix your issue
> right ?

Admittedly this is voodoo.  Moving the input_polldev device
initialization to asus_laptop (originally in asus_acpi_add(), which is
called out of the ACPI framwwork) caused reliable panics on boot.  I
moved it to asus_platform_probe() to restore the structure of the
original pega_accel module, which did it in a platform probe.

I don't know enough about the platform driver model to say exactly,
but I strongly suspect that platform probe calls are not done
synchronously underneath the platform_{device|driver}_register()
calls.

Dmitry Torokhov wrote:
> This I do not quite understand... Do we bind acpi drivers to devices
> before ACPI initialization is done? Then this should be fixed in
> ACPI layer, but I doubt even early userspace is active at the time
> ACPI core is being initialized. Also, input polling is done in a
> separate thread so you not moving the poll out of ACPI binding
> thread but delay poll execution by a few microseconds...

See comments above.  The current model in asus-laptop is to register
its keyboard input device underneat the .add callback in the acpi
driver.  That was crashing with the accelerometer.

And there's definitely a userspace interaction: disabling the sensor
daemon (the distro in question is a MeeGo tablet image) at startup
avoided the crash (and in fact worked fine when started up manually
later).

Andy

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-28 15:36       ` Andy Ross
@ 2011-03-31  7:23         ` Corentin Chary
  2011-04-04 17:16           ` Corentin Chary
  0 siblings, 1 reply; 14+ messages in thread
From: Corentin Chary @ 2011-03-31  7:23 UTC (permalink / raw)
  To: Andy Ross
  Cc: Dmitry Torokhov, acpi4asus-user, platform-driver-x86,
	Matthew Garrett

test platform printk

On Mon, Mar 28, 2011 at 3:36 PM, Andy Ross <andy.ross@windriver.com> wrote:
> [combined responses for clarity]
>
> Corentin Chary wrote:
>> Wow :/ How long is an acpi_evaluate_integer call here ?
>
> Early on I benchmarked the per-axis ACPI calls about about 50us, which
> is shockingly high to me.  But honestly that note there is just
> pedantry: the hi/lo race (and the fact that "errors" live in the same
> space with valid data values) is a real condition that lets me justify
> the "retry on large deltas" behavior, which most definitely improves
> data quality.

Ok,

>> When is asus_platform_probe called exactly ? Because I'd say it's
>> called during asus_platform_probe(), and that doesn't fix your issue
>> right ?
>
> Admittedly this is voodoo.  Moving the input_polldev device
> initialization to asus_laptop (originally in asus_acpi_add(), which is
> called out of the ACPI framwwork) caused reliable panics on boot.  I
> moved it to asus_platform_probe() to restore the structure of the
> original pega_accel module, which did it in a platform probe.
>
> I don't know enough about the platform driver model to say exactly,
> but I strongly suspect that platform probe calls are not done
> synchronously underneath the platform_{device|driver}_register()
> calls.

I'll check that this weekend.

> Dmitry Torokhov wrote:
>> This I do not quite understand... Do we bind acpi drivers to devices
>> before ACPI initialization is done? Then this should be fixed in
>> ACPI layer, but I doubt even early userspace is active at the time
>> ACPI core is being initialized. Also, input polling is done in a
>> separate thread so you not moving the poll out of ACPI binding
>> thread but delay poll execution by a few microseconds...
>
> See comments above.  The current model in asus-laptop is to register
> its keyboard input device underneat the .add callback in the acpi
> driver.  That was crashing with the accelerometer.
>
> And there's definitely a userspace interaction: disabling the sensor
> daemon (the distro in question is a MeeGo tablet image) at startup
> avoided the crash (and in fact worked fine when started up manually
> later).

Just to try to fix the crash in a more cleaner way, can you (re-)tell
us more about it ? It's a kernel crash, or the hardware just start
doing stupid things ? Any traces ? Does it also happens when you load
the model *after* boot (blacklist it, then modprobe) ? Could you also
re-send me the dsdt ? I think I lost it.

Thanks,

-- 
Corentin Chary
http://xf.iksaif.net

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-03-31  7:23         ` Corentin Chary
@ 2011-04-04 17:16           ` Corentin Chary
  2011-04-07 15:56             ` Anisse Astier
  0 siblings, 1 reply; 14+ messages in thread
From: Corentin Chary @ 2011-04-04 17:16 UTC (permalink / raw)
  To: Andy Ross
  Cc: Dmitry Torokhov, acpi4asus-user, platform-driver-x86,
	Matthew Garrett

On Thu, Mar 31, 2011 at 7:23 AM, Corentin Chary
<corentin.chary@gmail.com> wrote:
> test platform printk
>
> On Mon, Mar 28, 2011 at 3:36 PM, Andy Ross <andy.ross@windriver.com> wrote:
>> [combined responses for clarity]
>>
>> Corentin Chary wrote:
>>> Wow :/ How long is an acpi_evaluate_integer call here ?
>>
>> Early on I benchmarked the per-axis ACPI calls about about 50us, which
>> is shockingly high to me.  But honestly that note there is just
>> pedantry: the hi/lo race (and the fact that "errors" live in the same
>> space with valid data values) is a real condition that lets me justify
>> the "retry on large deltas" behavior, which most definitely improves
>> data quality.
>
> Ok,
>
>>> When is asus_platform_probe called exactly ? Because I'd say it's
>>> called during asus_platform_probe(), and that doesn't fix your issue
>>> right ?
>>
>> Admittedly this is voodoo.  Moving the input_polldev device
>> initialization to asus_laptop (originally in asus_acpi_add(), which is
>> called out of the ACPI framwwork) caused reliable panics on boot.  I
>> moved it to asus_platform_probe() to restore the structure of the
>> original pega_accel module, which did it in a platform probe.
>>
>> I don't know enough about the platform driver model to say exactly,
>> but I strongly suspect that platform probe calls are not done
>> synchronously underneath the platform_{device|driver}_register()
>> calls.
>
> I'll check that this weekend.

I didn't have any asus-laptop to test it, but here is a call trace for hp-wmi:

init
register
alloc
add
------------[ cut here ]------------
WARNING: at drivers/platform/x86/hp-wmi.c:901 hp_wmi_init+0x1db/0x234 [hp_wmi]()
Hardware name: HP Compaq 8710p
Modules linked in: hp_wmi(+) nvidia(P) hp_accel lis3lv02d
input_polldev ext2 sdhci_pci sdhci mmc_core thermal button ehci_hcd
btusb usbhid joydev sparse_keymap hid e1000e wmi bluetooth [last
unloaded: hp_wmi]
Pid: 25890, comm: insmod Tainted: P            2.6.39-rc1-00184-g78fca1b9 #4
Call Trace:
 [<ffffffff8103becb>] ? warn_slowpath_common+0x7b/0xc0
 [<ffffffffa00621db>] ? hp_wmi_init+0x1db/0x234 [hp_wmi]
 [<ffffffffa0062000>] ? 0xffffffffa0061fff
 [<ffffffff810002ba>] ? do_one_initcall+0x3a/0x170
 [<ffffffff81070e39>] ? sys_init_module+0xb9/0x200
 [<ffffffff815b733b>] ? system_call_fastpath+0x16/0x1b
---[ end trace 9b2a16f0f1ed60e4 ]---
bios setup begin
------------[ cut here ]------------
WARNING: at drivers/platform/x86/hp-wmi.c:783
hp_wmi_bios_setup+0x2a/0x2df [hp_wmi]()
Hardware name: HP Compaq 8710p
Modules linked in: hp_wmi(+) nvidia(P) hp_accel lis3lv02d
input_polldev ext2 sdhci_pci sdhci mmc_core thermal button ehci_hcd
btusb usbhid joydev sparse_keymap hid e1000e wmi bluetooth [last
unloaded: hp_wmi]
Pid: 25890, comm: insmod Tainted: P        W   2.6.39-rc1-00184-g78fca1b9 #4
Call Trace:
 [<ffffffff8103becb>] ? warn_slowpath_common+0x7b/0xc0
 [<ffffffffa003ad2d>] ? hp_wmi_bios_setup+0x2a/0x2df [hp_wmi]
 [<ffffffff81339efe>] ? pm_runtime_barrier+0x5e/0xc0
 [<ffffffff81331b46>] ? driver_probe_device+0x96/0x1b0
 [<ffffffff81331d00>] ? __driver_attach+0xa0/0xa0
 [<ffffffff8133087c>] ? bus_for_each_drv+0x5c/0x90
 [<ffffffff813319ef>] ? device_attach+0x8f/0xb0
 [<ffffffff8133121d>] ? bus_probe_device+0x2d/0x50
 [<ffffffff8132f546>] ? device_add+0x566/0x630
 [<ffffffff8132e18f>] ? dev_set_name+0x3f/0x50
 [<ffffffff813338b8>] ? platform_device_add+0xf8/0x1c0
 [<ffffffffa00621e7>] ? hp_wmi_init+0x1e7/0x234 [hp_wmi]
 [<ffffffffa0062000>] ? 0xffffffffa0061fff
 [<ffffffff810002ba>] ? do_one_initcall+0x3a/0x170
 [<ffffffff81070e39>] ? sys_init_module+0xb9/0x200
 [<ffffffff815b733b>] ? system_call_fastpath+0x16/0x1b
---[ end trace 9b2a16f0f1ed60e5 ]---
bios setup end
done

So, the call is clearly synchroneous.

Where did you put the call exactly to make it crash ?

>> Dmitry Torokhov wrote:
>>> This I do not quite understand... Do we bind acpi drivers to devices
>>> before ACPI initialization is done? Then this should be fixed in
>>> ACPI layer, but I doubt even early userspace is active at the time
>>> ACPI core is being initialized. Also, input polling is done in a
>>> separate thread so you not moving the poll out of ACPI binding
>>> thread but delay poll execution by a few microseconds...
>>
>> See comments above.  The current model in asus-laptop is to register
>> its keyboard input device underneat the .add callback in the acpi
>> driver.  That was crashing with the accelerometer.
>>
>> And there's definitely a userspace interaction: disabling the sensor
>> daemon (the distro in question is a MeeGo tablet image) at startup
>> avoided the crash (and in fact worked fine when started up manually
>> later).
>
> Just to try to fix the crash in a more cleaner way, can you (re-)tell
> us more about it ? It's a kernel crash, or the hardware just start
> doing stupid things ? Any traces ? Does it also happens when you load
> the model *after* boot (blacklist it, then modprobe) ? Could you also
> re-send me the dsdt ? I think I lost it.

ping ?

Thanks,
-- 
Corentin Chary
http://xf.iksaif.net

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-04-04 17:16           ` Corentin Chary
@ 2011-04-07 15:56             ` Anisse Astier
  2011-04-07 16:09               ` Corentin Chary
  0 siblings, 1 reply; 14+ messages in thread
From: Anisse Astier @ 2011-04-07 15:56 UTC (permalink / raw)
  To: Corentin Chary
  Cc: Andy Ross, Dmitry Torokhov, acpi4asus-user, platform-driver-x86,
	Matthew Garrett

[-- Attachment #1: Type: text/plain, Size: 604 bytes --]

On Mon, 4 Apr 2011 17:16:05 +0000, Corentin Chary <corentin.chary@gmail.com> wrote :

> On Thu, Mar 31, 2011 at 7:23 AM, Corentin Chary
> <corentin.chary@gmail.com> wrote:
<snip>
> > Just to try to fix the crash in a more cleaner way, can you (re-)tell
> > us more about it ? It's a kernel crash, or the hardware just start
> > doing stupid things ? Any traces ? Does it also happens when you load
> > the model *after* boot (blacklist it, then modprobe) ? Could you also
> > re-send me the dsdt ? I think I lost it.
> 
> ping ?

I have a Pegatron Lucid. Please find the DSDT attached.

Regards,

Anisse

[-- Attachment #2: DSDT-pegatron-lucid --]
[-- Type: application/octet-stream, Size: 35041 bytes --]

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

* Re: [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer
  2011-04-07 15:56             ` Anisse Astier
@ 2011-04-07 16:09               ` Corentin Chary
  0 siblings, 0 replies; 14+ messages in thread
From: Corentin Chary @ 2011-04-07 16:09 UTC (permalink / raw)
  To: Anisse Astier
  Cc: Andy Ross, Dmitry Torokhov, acpi4asus-user, platform-driver-x86,
	Matthew Garrett

On Thu, Apr 7, 2011 at 5:56 PM, Anisse Astier <anisse@astier.eu> wrote:
> On Mon, 4 Apr 2011 17:16:05 +0000, Corentin Chary <corentin.chary@gmail.com> wrote :
>
>> On Thu, Mar 31, 2011 at 7:23 AM, Corentin Chary
>> <corentin.chary@gmail.com> wrote:
> <snip>
>> > Just to try to fix the crash in a more cleaner way, can you (re-)tell
>> > us more about it ? It's a kernel crash, or the hardware just start
>> > doing stupid things ? Any traces ? Does it also happens when you load
>> > the model *after* boot (blacklist it, then modprobe) ? Could you also
>> > re-send me the dsdt ? I think I lost it.
>>
>> ping ?
>
> I have a Pegatron Lucid. Please find the DSDT attached.

Thanks for the DSDT. After a quick read I didn't find anything in it
that could produce the crash.
I'll wait for Andy's answers.


-- 
Corentin Chary
http://xf.iksaif.net

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

end of thread, other threads:[~2011-04-07 16:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-24 22:02 [PATCH 0/4] asus-laptop: Pegatron Lucid (WeTab/ExoPC) support Andy Ross
2011-03-24 22:02 ` [PATCH 1/4] asus-laptop: Platform detection for Pegatron Lucid Andy Ross
2011-03-24 22:02 ` [PATCH 2/4] asus-laptop: Pegatron Lucid ALS sensor Andy Ross
2011-03-25  7:48   ` Corentin Chary
2011-03-24 22:02 ` [PATCH 3/4] asus-laptop: Pegatron Lucid accelerometer Andy Ross
2011-03-25 11:21   ` Corentin Chary
2011-03-28  5:43     ` Dmitry Torokhov
2011-03-28 15:36       ` Andy Ross
2011-03-31  7:23         ` Corentin Chary
2011-04-04 17:16           ` Corentin Chary
2011-04-07 15:56             ` Anisse Astier
2011-04-07 16:09               ` Corentin Chary
2011-03-28  6:41     ` Corentin Chary
2011-03-24 22:02 ` [PATCH 4/4] asus-laptop: allow boot time control of Pegatron ALS sensor Andy Ross

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.