linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] Add support for Classmate V3 accelerometer to classmate-laptop
@ 2012-06-29 12:46 Miguel Gómez
  2012-06-29 12:46 ` [PATCH] classmate-laptop: Add support for Classmate V3 accelerometer Miguel Gómez
  2012-06-29 13:39 ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
  0 siblings, 2 replies; 15+ messages in thread
From: Miguel Gómez @ 2012-06-29 12:46 UTC (permalink / raw)
  To: cascardo, don, mjg; +Cc: platform-driver-x86, linux-kernel, Miguel Gómez

Classmate V3 has a different accelerometer than the previous versions. Main
differences between the new  (ACCE0001) and the old one (ACCE0000) are:

* ACPI method calls need to receive 4 parameters instead of 2
* Values returned by the accelerometer are 2 bytes signed integers, instead
of one unsigned byte
* New accelerometer has a new attribute (g_select) besides the sensitivity one.
This attribute's possible values are 0 (meaning 1.5g) and 1 (meaning 6g).

I haven't been able to find the datasheet of the accelerometer, so I got most
of the behaviour of the device by looking at the previous model driver and by
experimenting with the hardware. Due to this, the range of the axis values
(currently defined as -255-255) may not be exact, and also the fuzz value (16)
may not be the best. But, with this configuration, the programs handling the
screen rotation developed for previous versions of Classmate are working
properly.

Initially I thought of modifying the ACCE0000 driver to be able to handle both
devices, but the patch was quite big and messy, and it might add problems to the
previous hardware, so I decided to implement it as a new driver, following the
structure of the ACCE0000 driver. This way the new code won't break the old one.

In order to differenciate the new driver code from the old one, all the
function names that belong to the new driver end with "v3".

Hope everything is ok :)

Regards!

Miguel Gómez (1):
  classmate-laptop: Add support for accelerometer in classmate V3.

 drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
 1 file changed, 398 insertions(+), 2 deletions(-)

-- 
1.7.9.5


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

* [PATCH] classmate-laptop: Add support for Classmate V3 accelerometer.
  2012-06-29 12:46 [PATCH 0/1] Add support for Classmate V3 accelerometer to classmate-laptop Miguel Gómez
@ 2012-06-29 12:46 ` Miguel Gómez
  2012-06-29 13:39 ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
  1 sibling, 0 replies; 15+ messages in thread
From: Miguel Gómez @ 2012-06-29 12:46 UTC (permalink / raw)
  To: cascardo, don, mjg; +Cc: platform-driver-x86, linux-kernel, Miguel Gómez

Classmate V3 laptop includes a new accelerometer that can't be handled by
previous driver. This patch adds a new driver to handle it.

Signed-off-by: Miguel Gómez <magomez@igalia.com>
---
 drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
 1 file changed, 398 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index 94f93b6..f8cd3ad 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -31,12 +31,18 @@ MODULE_LICENSE("GPL");
 
 struct cmpc_accel {
 	int sensitivity;
+	int g_select;
+	int inputdev_state;
 };
 
-#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
+#define CMPC_ACCEL_DEV_STATE_CLOSED	0
+#define CMPC_ACCEL_DEV_STATE_OPEN	1
 
+#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
+#define CMPC_ACCEL_G_SELECT_DEFAULT		0
 
 #define CMPC_ACCEL_HID		"ACCE0000"
+#define CMPC_ACCEL_HID_V3	"ACCE0001"
 #define CMPC_TABLET_HID		"TBLT0000"
 #define CMPC_IPML_HID	"IPML200"
 #define CMPC_KEYS_HID		"FnBT0000"
@@ -76,7 +82,388 @@ static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
 }
 
 /*
- * Accelerometer code.
+ * Accelerometer code for Classmate V3
+ */
+static acpi_status cmpc_start_accel_v3(acpi_handle handle)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x3;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_stop_accel_v3(acpi_handle handle)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x4;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_accel_set_sensitivity_v3(acpi_handle handle, int val)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x02;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = val;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
+}
+
+static acpi_status cmpc_accel_set_g_select_v3(acpi_handle handle, int val)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x05;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = val;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
+}
+
+static acpi_status cmpc_get_accel_v3(acpi_handle handle,
+				     int16_t *x,
+				     int16_t *y,
+				     int16_t *z)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	int16_t *locs;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x01;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
+	if (ACPI_SUCCESS(status)) {
+		union acpi_object *obj;
+		obj = output.pointer;
+		locs = (int16_t *) obj->buffer.pointer;
+		*x = locs[0];
+		*y = locs[1];
+		*z = locs[2];
+		kfree(output.pointer);
+	}
+	return status;
+}
+
+static void cmpc_accel_handler_v3(struct acpi_device *dev, u32 event)
+{
+	if (event == 0x81) {
+		int16_t x, y, z;
+		acpi_status status;
+
+		status = cmpc_get_accel_v3(dev->handle, &x, &y, &z);
+		if (ACPI_SUCCESS(status)) {
+			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+
+			input_report_abs(inputdev, ABS_X, x);
+			input_report_abs(inputdev, ABS_Y, y);
+			input_report_abs(inputdev, ABS_Z, z);
+			input_sync(inputdev);
+		}
+	}
+}
+
+static ssize_t cmpc_accel_sensitivity_show_v3(struct device *dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	return sprintf(buf, "%d\n", accel->sensitivity);
+}
+
+static ssize_t cmpc_accel_sensitivity_store_v3(struct device *dev,
+					       struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+	unsigned long sensitivity;
+	int r;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	r = kstrtoul(buf, 0, &sensitivity);
+	if (r)
+		return r;
+
+	/* sensitivity must be between 1 and 127 */
+	if (sensitivity < 1 || sensitivity > 127)
+		return -EINVAL;
+
+	accel->sensitivity = sensitivity;
+	cmpc_accel_set_sensitivity_v3(acpi->handle, sensitivity);
+
+	return strnlen(buf, count);
+}
+
+static struct device_attribute cmpc_accel_sensitivity_attr_v3 = {
+	.attr = { .name = "sensitivity", .mode = 0660 },
+	.show = cmpc_accel_sensitivity_show_v3,
+	.store = cmpc_accel_sensitivity_store_v3
+};
+
+static ssize_t cmpc_accel_g_select_show_v3(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	return sprintf(buf, "%d\n", accel->g_select);
+}
+
+static ssize_t cmpc_accel_g_select_store_v3(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+	unsigned long g_select;
+	int r;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	r = kstrtoul(buf, 0, &g_select);
+	if (r)
+		return r;
+
+	/* 0 means 1.5g, 1 means 6g, everything else is wrong */
+	if (g_select != 0 && g_select != 1)
+		return -EINVAL;
+
+	accel->g_select = g_select;
+	cmpc_accel_set_g_select_v3(acpi->handle, g_select);
+
+	return strnlen(buf, count);
+}
+
+static struct device_attribute cmpc_accel_g_select_attr_v3 = {
+	.attr = { .name = "g_select", .mode = 0660 },
+	.show = cmpc_accel_g_select_show_v3,
+	.store = cmpc_accel_g_select_store_v3
+};
+
+static int cmpc_accel_open_v3(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(input->dev.parent);
+	accel = dev_get_drvdata(&input->dev);
+
+	cmpc_accel_set_sensitivity_v3(acpi->handle, accel->sensitivity);
+	cmpc_accel_set_g_select_v3(acpi->handle, accel->g_select);
+
+	if (ACPI_SUCCESS(cmpc_start_accel_v3(acpi->handle))) {
+		accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
+		return 0;
+	}
+	return -EIO;
+}
+
+static void cmpc_accel_close_v3(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(input->dev.parent);
+	accel = dev_get_drvdata(&input->dev);
+
+	cmpc_stop_accel_v3(acpi->handle);
+	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
+}
+
+static void cmpc_accel_idev_init_v3(struct input_dev *inputdev)
+{
+	set_bit(EV_ABS, inputdev->evbit);
+	input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
+	input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
+	input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
+	inputdev->open = cmpc_accel_open_v3;
+	inputdev->close = cmpc_accel_close_v3;
+}
+
+static int cmpc_accel_suspend_v3(struct acpi_device *acpi, pm_message_t state)
+{
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
+		return cmpc_stop_accel_v3(acpi->handle);
+
+	return 0;
+}
+
+static int cmpc_accel_resume_v3(struct acpi_device *acpi)
+{
+
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
+		cmpc_accel_set_sensitivity_v3(acpi->handle, accel->sensitivity);
+		cmpc_accel_set_g_select_v3(acpi->handle, accel->g_select);
+
+		if (ACPI_FAILURE(cmpc_start_accel_v3(acpi->handle)))
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int cmpc_accel_add_v3(struct acpi_device *acpi)
+{
+	int error;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
+	if (!accel)
+		return -ENOMEM;
+
+	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
+
+	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
+	cmpc_accel_set_sensitivity_v3(acpi->handle, accel->sensitivity);
+
+	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v3);
+	if (error)
+		goto failed_sensitivity;
+
+	accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
+	cmpc_accel_set_g_select_v3(acpi->handle, accel->g_select);
+
+	error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v3);
+	if (error)
+		goto failed_g_select;
+
+	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v3",
+					    cmpc_accel_idev_init_v3);
+	if (error)
+		goto failed_input;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	dev_set_drvdata(&inputdev->dev, accel);
+
+	return 0;
+
+failed_input:
+	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v3);
+failed_g_select:
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v3);
+failed_sensitivity:
+	kfree(accel);
+	return error;
+}
+
+static int cmpc_accel_remove_v3(struct acpi_device *acpi, int type)
+{
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v3);
+	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v3);
+	return cmpc_remove_acpi_notify_device(acpi);
+}
+
+static const struct acpi_device_id cmpc_accel_device_ids_v3[] = {
+	{CMPC_ACCEL_HID_V3, 0},
+	{"", 0}
+};
+
+static struct acpi_driver cmpc_accel_acpi_driver_v3 = {
+	.owner = THIS_MODULE,
+	.name = "cmpc_accel_v3",
+	.class = "cmpc_accel_v3",
+	.ids = cmpc_accel_device_ids_v3,
+	.ops = {
+		.add = cmpc_accel_add_v3,
+		.remove = cmpc_accel_remove_v3,
+		.notify = cmpc_accel_handler_v3,
+		.suspend = cmpc_accel_suspend_v3,
+		.resume = cmpc_accel_resume_v3,
+	}
+};
+
+
+/*
+ * Accelerometer code for classmate V1 and V2
  */
 static acpi_status cmpc_start_accel(acpi_handle handle)
 {
@@ -723,8 +1110,15 @@ static int cmpc_init(void)
 	if (r)
 		goto failed_accel;
 
+	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v3);
+	if (r)
+		goto failed_accel_v3;
+
 	return r;
 
+failed_accel_v3:
+	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
+
 failed_accel:
 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
 
@@ -740,6 +1134,7 @@ failed_keys:
 
 static void cmpc_exit(void)
 {
+	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v3);
 	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
 	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
@@ -751,6 +1146,7 @@ module_exit(cmpc_exit);
 
 static const struct acpi_device_id cmpc_device_ids[] = {
 	{CMPC_ACCEL_HID, 0},
+	{CMPC_ACCEL_HID_V3, 0},
 	{CMPC_TABLET_HID, 0},
 	{CMPC_IPML_HID, 0},
 	{CMPC_KEYS_HID, 0},
-- 
1.7.9.5


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

* [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop
  2012-06-29 12:46 [PATCH 0/1] Add support for Classmate V3 accelerometer to classmate-laptop Miguel Gómez
  2012-06-29 12:46 ` [PATCH] classmate-laptop: Add support for Classmate V3 accelerometer Miguel Gómez
@ 2012-06-29 13:39 ` Miguel Gómez
  2012-06-29 13:39   ` [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer Miguel Gómez
  2012-07-17 14:34   ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
  1 sibling, 2 replies; 15+ messages in thread
From: Miguel Gómez @ 2012-06-29 13:39 UTC (permalink / raw)
  To: cascardo, don, mjg; +Cc: platform-driver-x86, linux-kernel, Miguel Gómez

************************************************************************

Sorry, I made a mistake with the version. The patch is for Classmate V4
and not for V3, so I adjusted it accordingly.

************************************************************************

Classmate V4 has a different accelerometer than the previous versions. Main
differences between the new  (ACCE0001) and the old one (ACCE0000) are:

* ACPI method calls need to receive 4 parameters instead of 2
* Values returned by the accelerometer are 2 bytes signed integers, instead
of one unsigned byte
* New accelerometer has a new attribute (g_select) besides the sensitivity one.
This attribute's possible values are 0 (meaning 1.5g) and 1 (meaning 6g).

I haven't been able to find the datasheet of the accelerometer, so I got most
of the behaviour of the device by looking at the previous model driver and by
experimenting with the hardware. Due to this, the range of the axis values
(currently defined as -255-255) may not be exact, and also the fuzz value (16)
may not be the best. But, with this configuration, the programs handling the
screen rotation developed for previous versions of Classmate are working
properly.

Initially I thought of modifying the ACCE0000 driver to be able to handle both
devices, but the patch was quite big and messy, and it might add problems to the
previous hardware, so I decided to implement it as a new driver, following the
structure of the ACCE0000 driver. This way the new code won't break the old one.

In order to differenciate the new driver code from the old one, all the
function names that belong to the new driver end with "v4".

Hope everything is ok :)

Regards!

Miguel Gómez (1):
  classmate-laptop: Add support for Classmate V4 accelerometer.

 drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
 1 file changed, 398 insertions(+), 2 deletions(-)

-- 
1.7.9.5


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

* [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-06-29 13:39 ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
@ 2012-06-29 13:39   ` Miguel Gómez
  2012-07-17 22:47     ` Thadeu Lima de Souza Cascardo
  2012-07-17 14:34   ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
  1 sibling, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-06-29 13:39 UTC (permalink / raw)
  To: cascardo, don, mjg; +Cc: platform-driver-x86, linux-kernel, Miguel Gómez

Classmate V4 laptop includes a new accelerometer that can't be handled by
previous driver. This patch adds a new driver to handle it.

Signed-off-by: Miguel Gómez <magomez@igalia.com>
---
 drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
 1 file changed, 398 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index 94f93b6..5de01bc 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -31,12 +31,18 @@ MODULE_LICENSE("GPL");
 
 struct cmpc_accel {
 	int sensitivity;
+	int g_select;
+	int inputdev_state;
 };
 
-#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
+#define CMPC_ACCEL_DEV_STATE_CLOSED	0
+#define CMPC_ACCEL_DEV_STATE_OPEN	1
 
+#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
+#define CMPC_ACCEL_G_SELECT_DEFAULT		0
 
 #define CMPC_ACCEL_HID		"ACCE0000"
+#define CMPC_ACCEL_HID_V4	"ACCE0001"
 #define CMPC_TABLET_HID		"TBLT0000"
 #define CMPC_IPML_HID	"IPML200"
 #define CMPC_KEYS_HID		"FnBT0000"
@@ -76,7 +82,388 @@ static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
 }
 
 /*
- * Accelerometer code.
+ * Accelerometer code for Classmate V4
+ */
+static acpi_status cmpc_start_accel_v4(acpi_handle handle)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x3;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_stop_accel_v4(acpi_handle handle)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x4;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x02;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = val;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
+}
+
+static acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x05;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = val;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
+}
+
+static acpi_status cmpc_get_accel_v4(acpi_handle handle,
+				     int16_t *x,
+				     int16_t *y,
+				     int16_t *z)
+{
+	union acpi_object param[4];
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	int16_t *locs;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x01;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = 0;
+	param[2].type = ACPI_TYPE_INTEGER;
+	param[2].integer.value = 0;
+	param[3].type = ACPI_TYPE_INTEGER;
+	param[3].integer.value = 0;
+	input.count = 4;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
+	if (ACPI_SUCCESS(status)) {
+		union acpi_object *obj;
+		obj = output.pointer;
+		locs = (int16_t *) obj->buffer.pointer;
+		*x = locs[0];
+		*y = locs[1];
+		*z = locs[2];
+		kfree(output.pointer);
+	}
+	return status;
+}
+
+static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
+{
+	if (event == 0x81) {
+		int16_t x, y, z;
+		acpi_status status;
+
+		status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
+		if (ACPI_SUCCESS(status)) {
+			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+
+			input_report_abs(inputdev, ABS_X, x);
+			input_report_abs(inputdev, ABS_Y, y);
+			input_report_abs(inputdev, ABS_Z, z);
+			input_sync(inputdev);
+		}
+	}
+}
+
+static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	return sprintf(buf, "%d\n", accel->sensitivity);
+}
+
+static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,
+					       struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+	unsigned long sensitivity;
+	int r;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	r = kstrtoul(buf, 0, &sensitivity);
+	if (r)
+		return r;
+
+	/* sensitivity must be between 1 and 127 */
+	if (sensitivity < 1 || sensitivity > 127)
+		return -EINVAL;
+
+	accel->sensitivity = sensitivity;
+	cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity);
+
+	return strnlen(buf, count);
+}
+
+static struct device_attribute cmpc_accel_sensitivity_attr_v4 = {
+	.attr = { .name = "sensitivity", .mode = 0660 },
+	.show = cmpc_accel_sensitivity_show_v4,
+	.store = cmpc_accel_sensitivity_store_v4
+};
+
+static ssize_t cmpc_accel_g_select_show_v4(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	return sprintf(buf, "%d\n", accel->g_select);
+}
+
+static ssize_t cmpc_accel_g_select_store_v4(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+	unsigned long g_select;
+	int r;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	r = kstrtoul(buf, 0, &g_select);
+	if (r)
+		return r;
+
+	/* 0 means 1.5g, 1 means 6g, everything else is wrong */
+	if (g_select != 0 && g_select != 1)
+		return -EINVAL;
+
+	accel->g_select = g_select;
+	cmpc_accel_set_g_select_v4(acpi->handle, g_select);
+
+	return strnlen(buf, count);
+}
+
+static struct device_attribute cmpc_accel_g_select_attr_v4 = {
+	.attr = { .name = "g_select", .mode = 0660 },
+	.show = cmpc_accel_g_select_show_v4,
+	.store = cmpc_accel_g_select_store_v4
+};
+
+static int cmpc_accel_open_v4(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(input->dev.parent);
+	accel = dev_get_drvdata(&input->dev);
+
+	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
+	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
+
+	if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
+		accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
+		return 0;
+	}
+	return -EIO;
+}
+
+static void cmpc_accel_close_v4(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(input->dev.parent);
+	accel = dev_get_drvdata(&input->dev);
+
+	cmpc_stop_accel_v4(acpi->handle);
+	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
+}
+
+static void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
+{
+	set_bit(EV_ABS, inputdev->evbit);
+	input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
+	input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
+	input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
+	inputdev->open = cmpc_accel_open_v4;
+	inputdev->close = cmpc_accel_close_v4;
+}
+
+static int cmpc_accel_suspend_v4(struct acpi_device *acpi, pm_message_t state)
+{
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
+		return cmpc_stop_accel_v4(acpi->handle);
+
+	return 0;
+}
+
+static int cmpc_accel_resume_v4(struct acpi_device *acpi)
+{
+
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
+		cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
+		cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
+
+		if (ACPI_FAILURE(cmpc_start_accel_v4(acpi->handle)))
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int cmpc_accel_add_v4(struct acpi_device *acpi)
+{
+	int error;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
+	if (!accel)
+		return -ENOMEM;
+
+	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
+
+	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
+	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
+
+	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
+	if (error)
+		goto failed_sensitivity;
+
+	accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
+	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
+
+	error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
+	if (error)
+		goto failed_g_select;
+
+	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
+					    cmpc_accel_idev_init_v4);
+	if (error)
+		goto failed_input;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	dev_set_drvdata(&inputdev->dev, accel);
+
+	return 0;
+
+failed_input:
+	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
+failed_g_select:
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
+failed_sensitivity:
+	kfree(accel);
+	return error;
+}
+
+static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type)
+{
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
+	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
+	return cmpc_remove_acpi_notify_device(acpi);
+}
+
+static const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
+	{CMPC_ACCEL_HID_V4, 0},
+	{"", 0}
+};
+
+static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
+	.owner = THIS_MODULE,
+	.name = "cmpc_accel_v4",
+	.class = "cmpc_accel_v4",
+	.ids = cmpc_accel_device_ids_v4,
+	.ops = {
+		.add = cmpc_accel_add_v4,
+		.remove = cmpc_accel_remove_v4,
+		.notify = cmpc_accel_handler_v4,
+		.suspend = cmpc_accel_suspend_v4,
+		.resume = cmpc_accel_resume_v4,
+	}
+};
+
+
+/*
+ * Accelerometer code for Classmate versions prior to V4
  */
 static acpi_status cmpc_start_accel(acpi_handle handle)
 {
@@ -723,8 +1110,15 @@ static int cmpc_init(void)
 	if (r)
 		goto failed_accel;
 
+	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
+	if (r)
+		goto failed_accel_v4;
+
 	return r;
 
+failed_accel_v4:
+	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
+
 failed_accel:
 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
 
@@ -740,6 +1134,7 @@ failed_keys:
 
 static void cmpc_exit(void)
 {
+	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
 	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
 	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
@@ -751,6 +1146,7 @@ module_exit(cmpc_exit);
 
 static const struct acpi_device_id cmpc_device_ids[] = {
 	{CMPC_ACCEL_HID, 0},
+	{CMPC_ACCEL_HID_V4, 0},
 	{CMPC_TABLET_HID, 0},
 	{CMPC_IPML_HID, 0},
 	{CMPC_KEYS_HID, 0},
-- 
1.7.9.5


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

* Re: [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop
  2012-06-29 13:39 ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
  2012-06-29 13:39   ` [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer Miguel Gómez
@ 2012-07-17 14:34   ` Miguel Gómez
  1 sibling, 0 replies; 15+ messages in thread
From: Miguel Gómez @ 2012-07-17 14:34 UTC (permalink / raw)
  To: Miguel Gómez; +Cc: cascardo, don, mjg, platform-driver-x86, linux-kernel

Hi!

> Miguel Gómez (1):
>    classmate-laptop: Add support for Classmate V4 accelerometer.
>
>   drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
>   1 file changed, 398 insertions(+), 2 deletions(-)

Anyone had a moment to give a look to this code? I'm eager to get some 
feedback and fix whatever is needed to put it in shape... and start 
playing Tux Racer with the Classmate 4 accelerometer :)

Regards!!

-- 
Miguel Gómez
Igalia - http://www.igalia.com



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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-06-29 13:39   ` [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer Miguel Gómez
@ 2012-07-17 22:47     ` Thadeu Lima de Souza Cascardo
  2012-07-18 13:53       ` Miguel Gómez
  0 siblings, 1 reply; 15+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2012-07-17 22:47 UTC (permalink / raw)
  To: Miguel Gómez; +Cc: don, mjg, platform-driver-x86, linux-kernel

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

On Fri, Jun 29, 2012 at 03:39:48PM +0200, Miguel Gómez wrote:
> Classmate V4 laptop includes a new accelerometer that can't be handled by
> previous driver. This patch adds a new driver to handle it.
> 
> Signed-off-by: Miguel Gómez <magomez@igalia.com>

Hi, Miguel.

This seems OK to me. Thanks for this work. Do you have the other
functionality of the driver working? I am interested to know if you have
the function buttons working.

Regards.
Cascardo.

Acked-by: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>

> ---
>  drivers/platform/x86/classmate-laptop.c |  400 ++++++++++++++++++++++++++++++-
>  1 file changed, 398 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
> index 94f93b6..5de01bc 100644
> --- a/drivers/platform/x86/classmate-laptop.c
> +++ b/drivers/platform/x86/classmate-laptop.c
> @@ -31,12 +31,18 @@ MODULE_LICENSE("GPL");
>  
>  struct cmpc_accel {
>  	int sensitivity;
> +	int g_select;
> +	int inputdev_state;
>  };
>  
> -#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
> +#define CMPC_ACCEL_DEV_STATE_CLOSED	0
> +#define CMPC_ACCEL_DEV_STATE_OPEN	1
>  
> +#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
> +#define CMPC_ACCEL_G_SELECT_DEFAULT		0
>  
>  #define CMPC_ACCEL_HID		"ACCE0000"
> +#define CMPC_ACCEL_HID_V4	"ACCE0001"
>  #define CMPC_TABLET_HID		"TBLT0000"
>  #define CMPC_IPML_HID	"IPML200"
>  #define CMPC_KEYS_HID		"FnBT0000"
> @@ -76,7 +82,388 @@ static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
>  }
>  
>  /*
> - * Accelerometer code.
> + * Accelerometer code for Classmate V4
> + */
> +static acpi_status cmpc_start_accel_v4(acpi_handle handle)
> +{
> +	union acpi_object param[4];
> +	struct acpi_object_list input;
> +	acpi_status status;
> +
> +	param[0].type = ACPI_TYPE_INTEGER;
> +	param[0].integer.value = 0x3;
> +	param[1].type = ACPI_TYPE_INTEGER;
> +	param[1].integer.value = 0;
> +	param[2].type = ACPI_TYPE_INTEGER;
> +	param[2].integer.value = 0;
> +	param[3].type = ACPI_TYPE_INTEGER;
> +	param[3].integer.value = 0;
> +	input.count = 4;
> +	input.pointer = param;
> +	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
> +	return status;
> +}
> +
> +static acpi_status cmpc_stop_accel_v4(acpi_handle handle)
> +{
> +	union acpi_object param[4];
> +	struct acpi_object_list input;
> +	acpi_status status;
> +
> +	param[0].type = ACPI_TYPE_INTEGER;
> +	param[0].integer.value = 0x4;
> +	param[1].type = ACPI_TYPE_INTEGER;
> +	param[1].integer.value = 0;
> +	param[2].type = ACPI_TYPE_INTEGER;
> +	param[2].integer.value = 0;
> +	param[3].type = ACPI_TYPE_INTEGER;
> +	param[3].integer.value = 0;
> +	input.count = 4;
> +	input.pointer = param;
> +	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
> +	return status;
> +}
> +
> +static acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val)
> +{
> +	union acpi_object param[4];
> +	struct acpi_object_list input;
> +
> +	param[0].type = ACPI_TYPE_INTEGER;
> +	param[0].integer.value = 0x02;
> +	param[1].type = ACPI_TYPE_INTEGER;
> +	param[1].integer.value = val;
> +	param[2].type = ACPI_TYPE_INTEGER;
> +	param[2].integer.value = 0;
> +	param[3].type = ACPI_TYPE_INTEGER;
> +	param[3].integer.value = 0;
> +	input.count = 4;
> +	input.pointer = param;
> +	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
> +}
> +
> +static acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val)
> +{
> +	union acpi_object param[4];
> +	struct acpi_object_list input;
> +
> +	param[0].type = ACPI_TYPE_INTEGER;
> +	param[0].integer.value = 0x05;
> +	param[1].type = ACPI_TYPE_INTEGER;
> +	param[1].integer.value = val;
> +	param[2].type = ACPI_TYPE_INTEGER;
> +	param[2].integer.value = 0;
> +	param[3].type = ACPI_TYPE_INTEGER;
> +	param[3].integer.value = 0;
> +	input.count = 4;
> +	input.pointer = param;
> +	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
> +}
> +
> +static acpi_status cmpc_get_accel_v4(acpi_handle handle,
> +				     int16_t *x,
> +				     int16_t *y,
> +				     int16_t *z)
> +{
> +	union acpi_object param[4];
> +	struct acpi_object_list input;
> +	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
> +	int16_t *locs;
> +	acpi_status status;
> +
> +	param[0].type = ACPI_TYPE_INTEGER;
> +	param[0].integer.value = 0x01;
> +	param[1].type = ACPI_TYPE_INTEGER;
> +	param[1].integer.value = 0;
> +	param[2].type = ACPI_TYPE_INTEGER;
> +	param[2].integer.value = 0;
> +	param[3].type = ACPI_TYPE_INTEGER;
> +	param[3].integer.value = 0;
> +	input.count = 4;
> +	input.pointer = param;
> +	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
> +	if (ACPI_SUCCESS(status)) {
> +		union acpi_object *obj;
> +		obj = output.pointer;
> +		locs = (int16_t *) obj->buffer.pointer;
> +		*x = locs[0];
> +		*y = locs[1];
> +		*z = locs[2];
> +		kfree(output.pointer);
> +	}
> +	return status;
> +}
> +
> +static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
> +{
> +	if (event == 0x81) {
> +		int16_t x, y, z;
> +		acpi_status status;
> +
> +		status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
> +		if (ACPI_SUCCESS(status)) {
> +			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
> +
> +			input_report_abs(inputdev, ABS_X, x);
> +			input_report_abs(inputdev, ABS_Y, y);
> +			input_report_abs(inputdev, ABS_Z, z);
> +			input_sync(inputdev);
> +		}
> +	}
> +}
> +
> +static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,
> +					      struct device_attribute *attr,
> +					      char *buf)
> +{
> +	struct acpi_device *acpi;
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	acpi = to_acpi_device(dev);
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	return sprintf(buf, "%d\n", accel->sensitivity);
> +}
> +
> +static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,
> +					       struct device_attribute *attr,
> +					       const char *buf, size_t count)
> +{
> +	struct acpi_device *acpi;
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +	unsigned long sensitivity;
> +	int r;
> +
> +	acpi = to_acpi_device(dev);
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	r = kstrtoul(buf, 0, &sensitivity);
> +	if (r)
> +		return r;
> +
> +	/* sensitivity must be between 1 and 127 */
> +	if (sensitivity < 1 || sensitivity > 127)
> +		return -EINVAL;
> +
> +	accel->sensitivity = sensitivity;
> +	cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity);
> +
> +	return strnlen(buf, count);
> +}
> +
> +static struct device_attribute cmpc_accel_sensitivity_attr_v4 = {
> +	.attr = { .name = "sensitivity", .mode = 0660 },
> +	.show = cmpc_accel_sensitivity_show_v4,
> +	.store = cmpc_accel_sensitivity_store_v4
> +};
> +
> +static ssize_t cmpc_accel_g_select_show_v4(struct device *dev,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	struct acpi_device *acpi;
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	acpi = to_acpi_device(dev);
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	return sprintf(buf, "%d\n", accel->g_select);
> +}
> +
> +static ssize_t cmpc_accel_g_select_store_v4(struct device *dev,
> +					    struct device_attribute *attr,
> +					    const char *buf, size_t count)
> +{
> +	struct acpi_device *acpi;
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +	unsigned long g_select;
> +	int r;
> +
> +	acpi = to_acpi_device(dev);
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	r = kstrtoul(buf, 0, &g_select);
> +	if (r)
> +		return r;
> +
> +	/* 0 means 1.5g, 1 means 6g, everything else is wrong */
> +	if (g_select != 0 && g_select != 1)
> +		return -EINVAL;
> +
> +	accel->g_select = g_select;
> +	cmpc_accel_set_g_select_v4(acpi->handle, g_select);
> +
> +	return strnlen(buf, count);
> +}
> +
> +static struct device_attribute cmpc_accel_g_select_attr_v4 = {
> +	.attr = { .name = "g_select", .mode = 0660 },
> +	.show = cmpc_accel_g_select_show_v4,
> +	.store = cmpc_accel_g_select_store_v4
> +};
> +
> +static int cmpc_accel_open_v4(struct input_dev *input)
> +{
> +	struct acpi_device *acpi;
> +	struct cmpc_accel *accel;
> +
> +	acpi = to_acpi_device(input->dev.parent);
> +	accel = dev_get_drvdata(&input->dev);
> +
> +	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
> +	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
> +
> +	if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
> +		accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
> +		return 0;
> +	}
> +	return -EIO;
> +}
> +
> +static void cmpc_accel_close_v4(struct input_dev *input)
> +{
> +	struct acpi_device *acpi;
> +	struct cmpc_accel *accel;
> +
> +	acpi = to_acpi_device(input->dev.parent);
> +	accel = dev_get_drvdata(&input->dev);
> +
> +	cmpc_stop_accel_v4(acpi->handle);
> +	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
> +}
> +
> +static void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
> +{
> +	set_bit(EV_ABS, inputdev->evbit);
> +	input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
> +	input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
> +	input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
> +	inputdev->open = cmpc_accel_open_v4;
> +	inputdev->close = cmpc_accel_close_v4;
> +}
> +
> +static int cmpc_accel_suspend_v4(struct acpi_device *acpi, pm_message_t state)
> +{
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
> +		return cmpc_stop_accel_v4(acpi->handle);
> +
> +	return 0;
> +}
> +
> +static int cmpc_accel_resume_v4(struct acpi_device *acpi)
> +{
> +
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
> +		cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
> +		cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
> +
> +		if (ACPI_FAILURE(cmpc_start_accel_v4(acpi->handle)))
> +			return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cmpc_accel_add_v4(struct acpi_device *acpi)
> +{
> +	int error;
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
> +	if (!accel)
> +		return -ENOMEM;
> +
> +	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
> +
> +	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
> +	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
> +
> +	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
> +	if (error)
> +		goto failed_sensitivity;
> +
> +	accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
> +	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
> +
> +	error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
> +	if (error)
> +		goto failed_g_select;
> +
> +	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
> +					    cmpc_accel_idev_init_v4);
> +	if (error)
> +		goto failed_input;
> +
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	dev_set_drvdata(&inputdev->dev, accel);
> +
> +	return 0;
> +
> +failed_input:
> +	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
> +failed_g_select:
> +	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
> +failed_sensitivity:
> +	kfree(accel);
> +	return error;
> +}
> +
> +static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type)
> +{
> +	struct input_dev *inputdev;
> +	struct cmpc_accel *accel;
> +
> +	inputdev = dev_get_drvdata(&acpi->dev);
> +	accel = dev_get_drvdata(&inputdev->dev);
> +
> +	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
> +	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
> +	return cmpc_remove_acpi_notify_device(acpi);
> +}
> +
> +static const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
> +	{CMPC_ACCEL_HID_V4, 0},
> +	{"", 0}
> +};
> +
> +static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
> +	.owner = THIS_MODULE,
> +	.name = "cmpc_accel_v4",
> +	.class = "cmpc_accel_v4",
> +	.ids = cmpc_accel_device_ids_v4,
> +	.ops = {
> +		.add = cmpc_accel_add_v4,
> +		.remove = cmpc_accel_remove_v4,
> +		.notify = cmpc_accel_handler_v4,
> +		.suspend = cmpc_accel_suspend_v4,
> +		.resume = cmpc_accel_resume_v4,
> +	}
> +};
> +
> +
> +/*
> + * Accelerometer code for Classmate versions prior to V4
>   */
>  static acpi_status cmpc_start_accel(acpi_handle handle)
>  {
> @@ -723,8 +1110,15 @@ static int cmpc_init(void)
>  	if (r)
>  		goto failed_accel;
>  
> +	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
> +	if (r)
> +		goto failed_accel_v4;
> +
>  	return r;
>  
> +failed_accel_v4:
> +	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
> +
>  failed_accel:
>  	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
>  
> @@ -740,6 +1134,7 @@ failed_keys:
>  
>  static void cmpc_exit(void)
>  {
> +	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
>  	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
>  	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
>  	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
> @@ -751,6 +1146,7 @@ module_exit(cmpc_exit);
>  
>  static const struct acpi_device_id cmpc_device_ids[] = {
>  	{CMPC_ACCEL_HID, 0},
> +	{CMPC_ACCEL_HID_V4, 0},
>  	{CMPC_TABLET_HID, 0},
>  	{CMPC_IPML_HID, 0},
>  	{CMPC_KEYS_HID, 0},
> -- 
> 1.7.9.5
> 

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-17 22:47     ` Thadeu Lima de Souza Cascardo
@ 2012-07-18 13:53       ` Miguel Gómez
  2012-07-23 13:28         ` Matthew Garrett
  0 siblings, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-07-18 13:53 UTC (permalink / raw)
  To: Thadeu Lima de Souza Cascardo; +Cc: don, mjg, platform-driver-x86, linux-kernel

> On Fri, Jun 29, 2012 at 03:39:48PM +0200, Miguel Gómez wrote:
>> Classmate V4 laptop includes a new accelerometer that can't be handled by
>> previous driver. This patch adds a new driver to handle it.
>>
>> Signed-off-by: Miguel Gómez <magomez@igalia.com>
>
> Hi, Miguel.
>
> This seems OK to me. Thanks for this work. Do you have the other
> functionality of the driver working? I am interested to know if you have
> the function buttons working.

Hi Thadeu

I've been giving a look to the buttons code. Currently they are not 
working because the hardware id reported by the device (FNBT0000) is not 
the same as the one defined by the driver (FnBT0000), as you an one of 
my colleagues commented in this thread:

https://lkml.org/lkml/2011/6/21/341

I've replaced the id in the driver to FNBT0000 and it made the buttons 
work like a charm (enabling control of the backlight and LAN as well). 
To ensure compatibility with older versions of the kernel, a new id can 
be added (FNBT0000) besides the existent one (FnBT0000), and that works 
as well (as proposed in the thread).

It seems that this problem got a bit forgotten in the lists. Quoting 
yourself from the last email in the thread:

> I am copying the acpi list and Len Brown to see if they can tell us
> which one should be the right solution:
>
> 1) reverting the patch in acpica that puts all names in uppercase
> 2) using a case-insensitive match in acpi bus driver
> 3) using uppercase name in classmate-laptop driver

I think the easiest and less risky way to fix this is by adding a new 
hardware id (as proposed in the thread's patch), as it doesn't add any 
side effects (that the other solutions might add), and it doesn't break 
the behaviour of the old code.

What do you think?

Regards!

-- 
Miguel Gómez
Igalia - http://www.igalia.com



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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-18 13:53       ` Miguel Gómez
@ 2012-07-23 13:28         ` Matthew Garrett
  2012-07-23 13:33           ` Miguel Gómez
  0 siblings, 1 reply; 15+ messages in thread
From: Matthew Garrett @ 2012-07-23 13:28 UTC (permalink / raw)
  To: Miguel Gómez
  Cc: Thadeu Lima de Souza Cascardo, don, platform-driver-x86, linux-kernel

On Wed, Jul 18, 2012 at 03:53:48PM +0200, Miguel Gómez wrote:

> >1) reverting the patch in acpica that puts all names in uppercase
> >2) using a case-insensitive match in acpi bus driver
> >3) using uppercase name in classmate-laptop driver
> 
> I think the easiest and less risky way to fix this is by adding a
> new hardware id (as proposed in the thread's patch), as it doesn't
> add any side effects (that the other solutions might add), and it
> doesn't break the behaviour of the old code.

I've lost track of the implementation state here - if all names are 
upper-cased in acpica, why is this not already matching?

-- 
Matthew Garrett | mjg59@srcf.ucam.org

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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-23 13:28         ` Matthew Garrett
@ 2012-07-23 13:33           ` Miguel Gómez
  2012-07-23 13:36             ` Matthew Garrett
  0 siblings, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-07-23 13:33 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Thadeu Lima de Souza Cascardo, don, platform-driver-x86, linux-kernel

El 23/07/12 15:28, Matthew Garrett escribió:
> On Wed, Jul 18, 2012 at 03:53:48PM +0200, Miguel Gómez wrote:
>
>>> 1) reverting the patch in acpica that puts all names in uppercase
>>> 2) using a case-insensitive match in acpi bus driver
>>> 3) using uppercase name in classmate-laptop driver
>>
>> I think the easiest and less risky way to fix this is by adding a
>> new hardware id (as proposed in the thread's patch), as it doesn't
>> add any side effects (that the other solutions might add), and it
>> doesn't break the behaviour of the old code.
>
> I've lost track of the implementation state here - if all names are
> upper-cased in acpica, why is this not already matching?

Names are upper-cased in acpica, so the device is reported as FNBT0000. 
But in the driver it's named FnBT0000, and that's why it doesn't match.

-- 
Miguel Gómez
Igalia - http://www.igalia.com

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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-23 13:33           ` Miguel Gómez
@ 2012-07-23 13:36             ` Matthew Garrett
  2012-07-23 13:44               ` Miguel Gómez
  0 siblings, 1 reply; 15+ messages in thread
From: Matthew Garrett @ 2012-07-23 13:36 UTC (permalink / raw)
  To: Miguel Gómez
  Cc: Thadeu Lima de Souza Cascardo, don, platform-driver-x86, linux-kernel

On Mon, Jul 23, 2012 at 03:33:27PM +0200, Miguel Gómez wrote:

> Names are upper-cased in acpica, so the device is reported as
> FNBT0000. But in the driver it's named FnBT0000, and that's why it
> doesn't match.

So just change the existing entry in the driver to FNBT0000?

-- 
Matthew Garrett | mjg59@srcf.ucam.org

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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-23 13:36             ` Matthew Garrett
@ 2012-07-23 13:44               ` Miguel Gómez
  2012-07-24  3:09                 ` Thadeu Lima de Souza Cascardo
  0 siblings, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-07-23 13:44 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Thadeu Lima de Souza Cascardo, don, platform-driver-x86, linux-kernel

El 23/07/12 15:36, Matthew Garrett escribió:
> On Mon, Jul 23, 2012 at 03:33:27PM +0200, Miguel Gómez wrote:
>
>> Names are upper-cased in acpica, so the device is reported as
>> FNBT0000. But in the driver it's named FnBT0000, and that's why it
>> doesn't match.
>
> So just change the existing entry in the driver to FNBT0000?

I'd go for it. I can send a patch if you want. But not sure about 
Thadeu's opinion. In the old thread it seems that he wanted to explore 
other options besides that.

Do you agree with that change Thadeu?


-- 
Miguel Gómez
Igalia - http://www.igalia.com

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

* Re: [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer.
  2012-07-23 13:44               ` Miguel Gómez
@ 2012-07-24  3:09                 ` Thadeu Lima de Souza Cascardo
  2012-07-24 13:05                   ` [PATCH] classmate-laptop: Fix extra keys hardware id Miguel Gómez
  0 siblings, 1 reply; 15+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2012-07-24  3:09 UTC (permalink / raw)
  To: Miguel Gómez; +Cc: Matthew Garrett, don, platform-driver-x86, linux-kernel

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

On Mon, Jul 23, 2012 at 03:44:41PM +0200, Miguel Gómez wrote:
> El 23/07/12 15:36, Matthew Garrett escribió:
> >On Mon, Jul 23, 2012 at 03:33:27PM +0200, Miguel Gómez wrote:
> >
> >>Names are upper-cased in acpica, so the device is reported as
> >>FNBT0000. But in the driver it's named FnBT0000, and that's why it
> >>doesn't match.
> >
> >So just change the existing entry in the driver to FNBT0000?
> 
> I'd go for it. I can send a patch if you want. But not sure about
> Thadeu's opinion. In the old thread it seems that he wanted to
> explore other options besides that.
> 
> Do you agree with that change Thadeu?
> 

I'd say the other options were met with silence. So, go forward with the
patch and I'll ack it.

Thanks.
Cascardo.

> 
> -- 
> Miguel Gómez
> Igalia - http://www.igalia.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH] classmate-laptop: Fix extra keys hardware id.
  2012-07-24  3:09                 ` Thadeu Lima de Souza Cascardo
@ 2012-07-24 13:05                   ` Miguel Gómez
  2012-07-24 13:17                     ` Miguel Gómez
  0 siblings, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-07-24 13:05 UTC (permalink / raw)
  To: cascardo, don, mjg; +Cc: platform-driver-x86, linux-kernel, Miguel Gómez

Since ACPI devices ids were changed to use always upper-case letters, the ACPI
id of the extra keys (FNBT0000) was not maching the one defined in the driver
(FnBT0000), causing the extra keys not to work.

The patch replaces the driver id with the one reported by ACPI, fixing the
problem.

Signed-off-by: Miguel Gómez <magomez@igalia.com>
---
 drivers/platform/x86/classmate-laptop.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index e2230a2..43e6e54 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -39,7 +39,7 @@ struct cmpc_accel {
 #define CMPC_ACCEL_HID		"ACCE0000"
 #define CMPC_TABLET_HID		"TBLT0000"
 #define CMPC_IPML_HID	"IPML200"
-#define CMPC_KEYS_HID		"FnBT0000"
+#define CMPC_KEYS_HID		"FNBT0000"
 
 /*
  * Generic input device code.
-- 
1.7.9.5


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

* Re: [PATCH] classmate-laptop: Fix extra keys hardware id.
  2012-07-24 13:05                   ` [PATCH] classmate-laptop: Fix extra keys hardware id Miguel Gómez
@ 2012-07-24 13:17                     ` Miguel Gómez
  2012-07-24 13:21                       ` Matthew Garrett
  0 siblings, 1 reply; 15+ messages in thread
From: Miguel Gómez @ 2012-07-24 13:17 UTC (permalink / raw)
  To: Miguel Gómez; +Cc: cascardo, don, mjg, platform-driver-x86, linux-kernel

> Since ACPI devices ids were changed to use always upper-case letters, the ACPI
> id of the extra keys (FNBT0000) was not maching the one defined in the driver
> (FnBT0000), causing the extra keys not to work.
>
> The patch replaces the driver id with the one reported by ACPI, fixing the
> problem.
>
> Signed-off-by: Miguel Gómez <magomez@igalia.com>

I've created this patch on top of linux-next, but it won't apply over 
the patch I've just sent for the accelerometer (neither the later over 
the former).

How do you want me to proceed? Should I sent this again over the 
accelerometer patch?

Regards!

-- 
Miguel Gómez
Igalia - http://www.igalia.com

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

* Re: [PATCH] classmate-laptop: Fix extra keys hardware id.
  2012-07-24 13:17                     ` Miguel Gómez
@ 2012-07-24 13:21                       ` Matthew Garrett
  0 siblings, 0 replies; 15+ messages in thread
From: Matthew Garrett @ 2012-07-24 13:21 UTC (permalink / raw)
  To: Miguel Gómez; +Cc: cascardo, don, platform-driver-x86, linux-kernel

On Tue, Jul 24, 2012 at 03:17:26PM +0200, Miguel Gómez wrote:
> I've created this patch on top of linux-next, but it won't apply
> over the patch I've just sent for the accelerometer (neither the
> later over the former).
> 
> How do you want me to proceed? Should I sent this again over the
> accelerometer patch?

I can merge them. Thanks for the patch!

-- 
Matthew Garrett | mjg59@srcf.ucam.org

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

end of thread, other threads:[~2012-07-24 13:21 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-29 12:46 [PATCH 0/1] Add support for Classmate V3 accelerometer to classmate-laptop Miguel Gómez
2012-06-29 12:46 ` [PATCH] classmate-laptop: Add support for Classmate V3 accelerometer Miguel Gómez
2012-06-29 13:39 ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez
2012-06-29 13:39   ` [PATCH 1/1 v2] classmate-laptop: Add support for Classmate V4 accelerometer Miguel Gómez
2012-07-17 22:47     ` Thadeu Lima de Souza Cascardo
2012-07-18 13:53       ` Miguel Gómez
2012-07-23 13:28         ` Matthew Garrett
2012-07-23 13:33           ` Miguel Gómez
2012-07-23 13:36             ` Matthew Garrett
2012-07-23 13:44               ` Miguel Gómez
2012-07-24  3:09                 ` Thadeu Lima de Souza Cascardo
2012-07-24 13:05                   ` [PATCH] classmate-laptop: Fix extra keys hardware id Miguel Gómez
2012-07-24 13:17                     ` Miguel Gómez
2012-07-24 13:21                       ` Matthew Garrett
2012-07-17 14:34   ` [PATCH 0/1 v2] Add support for Classmate V4 accelerometer to classmate-laptop Miguel Gómez

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