* [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* 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
* [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* 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-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
* 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
* [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