[go: nahoru, domu]

1529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
2529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  Copyright (C) 2009  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *
4529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  This program is free software; you can redistribute it and/or modify
5529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  it under the terms of the GNU General Public License as published by
6529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  the Free Software Foundation; either version 2 of the License, or
7529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  (at your option) any later version.
8529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *
9529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  This program is distributed in the hope that it will be useful,
10529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  GNU General Public License for more details.
13529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *
14529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  You should have received a copy of the GNU General Public License along
15529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  with this program; if not, write to the Free Software Foundation, Inc.,
16529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
18529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
19529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
20529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo#include <linux/init.h>
21529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo#include <linux/module.h>
225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
23529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo#include <linux/workqueue.h>
248b48463f89429af408ff695244dc627e1acff4f7Lv Zheng#include <linux/acpi.h>
25529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo#include <linux/backlight.h>
26529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo#include <linux/input.h>
27d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo#include <linux/rfkill.h>
28529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
29529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza CascardoMODULE_LICENSE("GPL");
30529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
31529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostruct cmpc_accel {
32529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int sensitivity;
337125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int g_select;
347125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int inputdev_state;
35529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
36529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
377125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez#define CMPC_ACCEL_DEV_STATE_CLOSED	0
387125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez#define CMPC_ACCEL_DEV_STATE_OPEN	1
39529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
407125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
417125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez#define CMPC_ACCEL_G_SELECT_DEFAULT		0
42529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
4302e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo#define CMPC_ACCEL_HID		"ACCE0000"
447125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez#define CMPC_ACCEL_HID_V4	"ACCE0001"
4502e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo#define CMPC_TABLET_HID		"TBLT0000"
46d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo#define CMPC_IPML_HID	"IPML200"
470ece8d515c264078a144bc597d0ffc40645ce378Miguel Gómez#define CMPC_KEYS_HID		"FNBT0000"
4802e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo
49529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
50529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo * Generic input device code.
51529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
52529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
53529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardotypedef void (*input_device_init)(struct input_dev *dev);
54529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
55529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
56529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				       input_device_init idev_init)
57529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
58529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
59529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int error;
60529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
61529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev = input_allocate_device();
62529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (!inputdev)
63529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return -ENOMEM;
64529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev->name = name;
65529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev->dev.parent = &acpi->dev;
66529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	idev_init(inputdev);
67529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	error = input_register_device(inputdev);
68529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (error) {
69529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		input_free_device(inputdev);
70529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return error;
71529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
72529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	dev_set_drvdata(&acpi->dev, inputdev);
73529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
74529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
75529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
76529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
77529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
78529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
79529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input_unregister_device(inputdev);
80529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
81529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
82529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
83529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
847125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez * Accelerometer code for Classmate V4
857125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez */
867125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic acpi_status cmpc_start_accel_v4(acpi_handle handle)
877125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
887125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	union acpi_object param[4];
897125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_object_list input;
907125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi_status status;
917125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
927125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].type = ACPI_TYPE_INTEGER;
937125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].integer.value = 0x3;
947125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].type = ACPI_TYPE_INTEGER;
957125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].integer.value = 0;
967125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].type = ACPI_TYPE_INTEGER;
977125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].integer.value = 0;
987125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].type = ACPI_TYPE_INTEGER;
997125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].integer.value = 0;
1007125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.count = 4;
1017125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.pointer = param;
1027125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
1037125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return status;
1047125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
1057125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1067125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic acpi_status cmpc_stop_accel_v4(acpi_handle handle)
1077125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
1087125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	union acpi_object param[4];
1097125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_object_list input;
1107125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi_status status;
1117125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1127125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].type = ACPI_TYPE_INTEGER;
1137125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].integer.value = 0x4;
1147125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].type = ACPI_TYPE_INTEGER;
1157125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].integer.value = 0;
1167125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].type = ACPI_TYPE_INTEGER;
1177125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].integer.value = 0;
1187125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].type = ACPI_TYPE_INTEGER;
1197125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].integer.value = 0;
1207125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.count = 4;
1217125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.pointer = param;
1227125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
1237125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return status;
1247125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
1257125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1267125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val)
1277125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
1287125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	union acpi_object param[4];
1297125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_object_list input;
1307125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1317125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].type = ACPI_TYPE_INTEGER;
1327125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].integer.value = 0x02;
1337125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].type = ACPI_TYPE_INTEGER;
1347125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].integer.value = val;
1357125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].type = ACPI_TYPE_INTEGER;
1367125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].integer.value = 0;
1377125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].type = ACPI_TYPE_INTEGER;
1387125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].integer.value = 0;
1397125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.count = 4;
1407125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.pointer = param;
1417125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
1427125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
1437125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1447125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val)
1457125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
1467125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	union acpi_object param[4];
1477125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_object_list input;
1487125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1497125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].type = ACPI_TYPE_INTEGER;
1507125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].integer.value = 0x05;
1517125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].type = ACPI_TYPE_INTEGER;
1527125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].integer.value = val;
1537125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].type = ACPI_TYPE_INTEGER;
1547125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].integer.value = 0;
1557125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].type = ACPI_TYPE_INTEGER;
1567125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].integer.value = 0;
1577125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.count = 4;
1587125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.pointer = param;
1597125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
1607125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
1617125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1627125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic acpi_status cmpc_get_accel_v4(acpi_handle handle,
1637125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez				     int16_t *x,
1647125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez				     int16_t *y,
1657125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez				     int16_t *z)
1667125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
1677125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	union acpi_object param[4];
1687125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_object_list input;
1697125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1707125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int16_t *locs;
1717125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi_status status;
1727125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1737125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].type = ACPI_TYPE_INTEGER;
1747125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[0].integer.value = 0x01;
1757125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].type = ACPI_TYPE_INTEGER;
1767125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[1].integer.value = 0;
1777125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].type = ACPI_TYPE_INTEGER;
1787125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[2].integer.value = 0;
1797125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].type = ACPI_TYPE_INTEGER;
1807125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	param[3].integer.value = 0;
1817125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.count = 4;
1827125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input.pointer = param;
1837125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
1847125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (ACPI_SUCCESS(status)) {
1857125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		union acpi_object *obj;
1867125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		obj = output.pointer;
1877125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		locs = (int16_t *) obj->buffer.pointer;
1887125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		*x = locs[0];
1897125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		*y = locs[1];
1907125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		*z = locs[2];
1917125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		kfree(output.pointer);
1927125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	}
1937125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return status;
1947125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
1957125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1967125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
1977125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
1987125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (event == 0x81) {
1997125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		int16_t x, y, z;
2007125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		acpi_status status;
2017125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2027125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
2037125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		if (ACPI_SUCCESS(status)) {
2047125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
2057125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2067125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			input_report_abs(inputdev, ABS_X, x);
2077125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			input_report_abs(inputdev, ABS_Y, y);
2087125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			input_report_abs(inputdev, ABS_Z, z);
2097125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			input_sync(inputdev);
2107125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		}
2117125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	}
2127125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
2137125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2147125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,
2157125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					      struct device_attribute *attr,
2167125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					      char *buf)
2177125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
2187125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
2197125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
2207125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
2217125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2227125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(dev);
2237125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
2247125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
2257125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2267125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return sprintf(buf, "%d\n", accel->sensitivity);
2277125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
2287125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2297125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,
2307125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					       struct device_attribute *attr,
2317125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					       const char *buf, size_t count)
2327125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
2337125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
2347125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
2357125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
2367125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	unsigned long sensitivity;
2377125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int r;
2387125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2397125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(dev);
2407125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
2417125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
2427125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2437125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	r = kstrtoul(buf, 0, &sensitivity);
2447125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (r)
2457125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return r;
2467125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2477125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	/* sensitivity must be between 1 and 127 */
2487125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (sensitivity < 1 || sensitivity > 127)
2497125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return -EINVAL;
2507125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2517125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->sensitivity = sensitivity;
2527125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity);
2537125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2547125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return strnlen(buf, count);
2557125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
2567125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2577125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic struct device_attribute cmpc_accel_sensitivity_attr_v4 = {
2587125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.attr = { .name = "sensitivity", .mode = 0660 },
2597125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.show = cmpc_accel_sensitivity_show_v4,
2607125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.store = cmpc_accel_sensitivity_store_v4
2617125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez};
2627125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2637125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic ssize_t cmpc_accel_g_select_show_v4(struct device *dev,
2647125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					   struct device_attribute *attr,
2657125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					   char *buf)
2667125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
2677125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
2687125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
2697125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
2707125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2717125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(dev);
2727125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
2737125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
2747125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2757125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return sprintf(buf, "%d\n", accel->g_select);
2767125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
2777125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2787125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic ssize_t cmpc_accel_g_select_store_v4(struct device *dev,
2797125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					    struct device_attribute *attr,
2807125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					    const char *buf, size_t count)
2817125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
2827125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
2837125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
2847125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
2857125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	unsigned long g_select;
2867125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int r;
2877125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2887125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(dev);
2897125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
2907125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
2917125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2927125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	r = kstrtoul(buf, 0, &g_select);
2937125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (r)
2947125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return r;
2957125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
2967125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	/* 0 means 1.5g, 1 means 6g, everything else is wrong */
2977125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (g_select != 0 && g_select != 1)
2987125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return -EINVAL;
2997125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3007125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->g_select = g_select;
3017125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_g_select_v4(acpi->handle, g_select);
3027125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3037125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return strnlen(buf, count);
3047125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3057125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3067125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic struct device_attribute cmpc_accel_g_select_attr_v4 = {
3077125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.attr = { .name = "g_select", .mode = 0660 },
3087125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.show = cmpc_accel_g_select_show_v4,
3097125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.store = cmpc_accel_g_select_store_v4
3107125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez};
3117125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3127125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic int cmpc_accel_open_v4(struct input_dev *input)
3137125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3147125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
3157125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
3167125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3177125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(input->dev.parent);
3187125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&input->dev);
3197125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3207125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
3217125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
3227125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3237125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
3247125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
3257125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return 0;
3267125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	}
3277125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return -EIO;
3287125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3297125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3307125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic void cmpc_accel_close_v4(struct input_dev *input)
3317125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3327125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct acpi_device *acpi;
3337125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
3347125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3357125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi = to_acpi_device(input->dev.parent);
3367125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&input->dev);
3377125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3387125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_stop_accel_v4(acpi->handle);
3397125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
3407125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3417125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3427125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
3437125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3447125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	set_bit(EV_ABS, inputdev->evbit);
3457125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
3467125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
3477125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
3487125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev->open = cmpc_accel_open_v4;
3497125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev->close = cmpc_accel_close_v4;
3507125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3517125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3523567a4e2c52ce2f6fe74fc85690335ec7c96608eRafael J. Wysocki#ifdef CONFIG_PM_SLEEP
3537125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic int cmpc_accel_suspend_v4(struct device *dev)
3547125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3557125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
3567125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
3577125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3587125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(dev);
3597125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
3607125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3617125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
3627125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return cmpc_stop_accel_v4(to_acpi_device(dev)->handle);
3637125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3647125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return 0;
3657125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3667125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3677125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic int cmpc_accel_resume_v4(struct device *dev)
3687125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3697125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
3707125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
3717125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3727125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(dev);
3737125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
3747125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3757125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
3767125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		cmpc_accel_set_sensitivity_v4(to_acpi_device(dev)->handle,
3777125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					      accel->sensitivity);
3787125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		cmpc_accel_set_g_select_v4(to_acpi_device(dev)->handle,
3797125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					   accel->g_select);
3807125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3817125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		if (ACPI_FAILURE(cmpc_start_accel_v4(to_acpi_device(dev)->handle)))
3827125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			return -EIO;
3837125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	}
3847125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3857125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return 0;
3867125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
3873567a4e2c52ce2f6fe74fc85690335ec7c96608eRafael J. Wysocki#endif
3887125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3897125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic int cmpc_accel_add_v4(struct acpi_device *acpi)
3907125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
3917125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	int error;
3927125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
3937125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
3947125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3957125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
3967125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (!accel)
3977125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		return -ENOMEM;
3987125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
3997125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
4007125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4017125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
4027125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
4037125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4047125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
4057125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (error)
4067125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		goto failed_sensitivity;
4077125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4087125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
4097125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
4107125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4117125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
4127125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (error)
4137125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		goto failed_g_select;
4147125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4157125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
4167125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez					    cmpc_accel_idev_init_v4);
4177125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (error)
4187125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		goto failed_input;
4197125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4207125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
4217125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	dev_set_drvdata(&inputdev->dev, accel);
4227125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4237125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return 0;
4247125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4257125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezfailed_input:
4267125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
4277125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezfailed_g_select:
4287125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
4297125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezfailed_sensitivity:
4307125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	kfree(accel);
4317125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return error;
4327125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
4337125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
43451fac8388a0325a43f0ae67453ece2c373e2ec28Rafael J. Wysockistatic int cmpc_accel_remove_v4(struct acpi_device *acpi)
4357125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez{
4367125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct input_dev *inputdev;
4377125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	struct cmpc_accel *accel;
4387125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4397125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	inputdev = dev_get_drvdata(&acpi->dev);
4407125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	accel = dev_get_drvdata(&inputdev->dev);
4417125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4427125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
4437125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
4447125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	return cmpc_remove_acpi_notify_device(acpi);
4457125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez}
4467125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4477125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4,
4487125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez			 cmpc_accel_resume_v4);
4497125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4507125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
4517125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	{CMPC_ACCEL_HID_V4, 0},
4527125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	{"", 0}
4537125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez};
4547125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4557125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezstatic struct acpi_driver cmpc_accel_acpi_driver_v4 = {
4567125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.owner = THIS_MODULE,
4577125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.name = "cmpc_accel_v4",
4587125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.class = "cmpc_accel_v4",
4597125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.ids = cmpc_accel_device_ids_v4,
4607125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.ops = {
4617125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		.add = cmpc_accel_add_v4,
4627125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		.remove = cmpc_accel_remove_v4,
4637125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		.notify = cmpc_accel_handler_v4,
4647125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	},
4657125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	.drv.pm = &cmpc_accel_pm,
4667125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez};
4677125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4687125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
4697125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez/*
4707125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez * Accelerometer code for Classmate versions prior to V4
471529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
472529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_start_accel(acpi_handle handle)
473529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
474529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param[2];
475529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
476529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
477529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
478529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
479529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].integer.value = 0x3;
480529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
481529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 2;
482529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = param;
483529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
484529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
485529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
486529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
487529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_stop_accel(acpi_handle handle)
488529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
489529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param[2];
490529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
491529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
492529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
493529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
494529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].integer.value = 0x4;
495529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
496529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 2;
497529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = param;
498529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
499529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
500529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
501529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
502529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val)
503529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
504529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param[2];
505529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
506529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
507529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
508529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].integer.value = 0x02;
509529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
510529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].integer.value = val;
511529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 2;
512529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = param;
513529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
514529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
515529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
516529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_get_accel(acpi_handle handle,
517529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				  unsigned char *x,
518529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				  unsigned char *y,
519529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				  unsigned char *z)
520529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
521529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param[2];
522529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
523529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 };
524529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned char *locs;
525529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
526529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
527529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
528529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].integer.value = 0x01;
529529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
530529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 2;
531529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = param;
532529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
533529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status)) {
534529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		union acpi_object *obj;
535529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		obj = output.pointer;
536529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		locs = obj->buffer.pointer;
537529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		*x = locs[0];
538529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		*y = locs[1];
539529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		*z = locs[2];
540529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		kfree(output.pointer);
541529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
542529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
543529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
544529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
545529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_accel_handler(struct acpi_device *dev, u32 event)
546529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
547529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (event == 0x81) {
548529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		unsigned char x, y, z;
549529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		acpi_status status;
550529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
551529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		status = cmpc_get_accel(dev->handle, &x, &y, &z);
552529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		if (ACPI_SUCCESS(status)) {
553529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
554529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
555529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			input_report_abs(inputdev, ABS_X, x);
556529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			input_report_abs(inputdev, ABS_Y, y);
557529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			input_report_abs(inputdev, ABS_Z, z);
558529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			input_sync(inputdev);
559529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		}
560529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
561529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
562529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
563529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic ssize_t cmpc_accel_sensitivity_show(struct device *dev,
564529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					   struct device_attribute *attr,
565529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					   char *buf)
566529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
567529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_device *acpi;
568529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
569529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct cmpc_accel *accel;
570529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
571529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi = to_acpi_device(dev);
572529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev = dev_get_drvdata(&acpi->dev);
573529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel = dev_get_drvdata(&inputdev->dev);
574529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
575529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return sprintf(buf, "%d\n", accel->sensitivity);
576529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
577529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
578529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic ssize_t cmpc_accel_sensitivity_store(struct device *dev,
579529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					    struct device_attribute *attr,
580529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					    const char *buf, size_t count)
581529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
582529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_device *acpi;
583529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
584529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct cmpc_accel *accel;
585529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long sensitivity;
586529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int r;
587529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
588529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi = to_acpi_device(dev);
589529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev = dev_get_drvdata(&acpi->dev);
590529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel = dev_get_drvdata(&inputdev->dev);
591529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
5920db7fd969e567dc0e4d2a7138896d6860f9614d5Jingoo Han	r = kstrtoul(buf, 0, &sensitivity);
593529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (r)
594529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return r;
595529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
596529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel->sensitivity = sensitivity;
597529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	cmpc_accel_set_sensitivity(acpi->handle, sensitivity);
598529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
599529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return strnlen(buf, count);
600529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
601529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
602df92754dddc77003c6be9540ff91bf89fcfce890Axel Linstatic struct device_attribute cmpc_accel_sensitivity_attr = {
603529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.attr = { .name = "sensitivity", .mode = 0660 },
604529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.show = cmpc_accel_sensitivity_show,
605529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.store = cmpc_accel_sensitivity_store
606529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
607529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
608529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_accel_open(struct input_dev *input)
609529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
610529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_device *acpi;
611529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
612529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi = to_acpi_device(input->dev.parent);
613529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle)))
614529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return 0;
615529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return -EIO;
616529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
617529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
618529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_accel_close(struct input_dev *input)
619529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
620529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_device *acpi;
621529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
622529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi = to_acpi_device(input->dev.parent);
623529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	cmpc_stop_accel(acpi->handle);
624529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
625529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
626529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_accel_idev_init(struct input_dev *inputdev)
627529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
628529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	set_bit(EV_ABS, inputdev->evbit);
629529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0);
630529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0);
631529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0);
632529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev->open = cmpc_accel_open;
633529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev->close = cmpc_accel_close;
634529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
635529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
636529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_accel_add(struct acpi_device *acpi)
637529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
638529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int error;
639529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
640529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct cmpc_accel *accel;
641529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
642529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
643529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (!accel)
644529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return -ENOMEM;
645529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
646529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
647529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity);
648529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
649529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
650529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (error)
651529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_file;
652529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
653529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel",
654529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					    cmpc_accel_idev_init);
655529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (error)
656529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_input;
657529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
658529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev = dev_get_drvdata(&acpi->dev);
659529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	dev_set_drvdata(&inputdev->dev, accel);
660529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
661529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
662529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
663529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_input:
664529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
665529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_file:
666529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	kfree(accel);
667529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return error;
668529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
669529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
67051fac8388a0325a43f0ae67453ece2c373e2ec28Rafael J. Wysockistatic int cmpc_accel_remove(struct acpi_device *acpi)
671529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
672529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
673529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct cmpc_accel *accel;
674529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
675529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	inputdev = dev_get_drvdata(&acpi->dev);
676529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	accel = dev_get_drvdata(&inputdev->dev);
677529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
678529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
679529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return cmpc_remove_acpi_notify_device(acpi);
680529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
681529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
682529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic const struct acpi_device_id cmpc_accel_device_ids[] = {
68302e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_ACCEL_HID, 0},
684529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	{"", 0}
685529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
686529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
687529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic struct acpi_driver cmpc_accel_acpi_driver = {
688529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.owner = THIS_MODULE,
689529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.name = "cmpc_accel",
690529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.class = "cmpc_accel",
691529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ids = cmpc_accel_device_ids,
692529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ops = {
693529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.add = cmpc_accel_add,
694529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.remove = cmpc_accel_remove,
695529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.notify = cmpc_accel_handler,
696529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
697529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
698529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
699529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
700529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
701529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo * Tablet mode code.
702529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
703529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_get_tablet(acpi_handle handle,
704529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				   unsigned long long *value)
705529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
706529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param;
707529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
708529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long output;
709529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
710529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
711529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param.type = ACPI_TYPE_INTEGER;
712529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param.integer.value = 0x01;
713529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 1;
714529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = &param;
715529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_integer(handle, "TCMD", &input, &output);
716529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status))
717529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		*value = output;
718529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
719529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
720529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
721529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
722529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
723529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long val = 0;
724529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
725529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
726529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (event == 0x81) {
727ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez		if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) {
728529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo			input_report_switch(inputdev, SW_TABLET_MODE, !val);
729ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez			input_sync(inputdev);
730ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez		}
731529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
732529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
733529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
734529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_tablet_idev_init(struct input_dev *inputdev)
735529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
736529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long val = 0;
737529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_device *acpi;
738529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
739529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	set_bit(EV_SW, inputdev->evbit);
740529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	set_bit(SW_TABLET_MODE, inputdev->swbit);
741529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
742529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi = to_acpi_device(inputdev->dev.parent);
743ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez	if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) {
744529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		input_report_switch(inputdev, SW_TABLET_MODE, !val);
745ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez		input_sync(inputdev);
746ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez	}
747529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
748529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
749529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_tablet_add(struct acpi_device *acpi)
750529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
751529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet",
752529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					   cmpc_tablet_idev_init);
753529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
754529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
75551fac8388a0325a43f0ae67453ece2c373e2ec28Rafael J. Wysockistatic int cmpc_tablet_remove(struct acpi_device *acpi)
756529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
757529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return cmpc_remove_acpi_notify_device(acpi);
758529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
759529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
7603567a4e2c52ce2f6fe74fc85690335ec7c96608eRafael J. Wysocki#ifdef CONFIG_PM_SLEEP
76181bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysockistatic int cmpc_tablet_resume(struct device *dev)
762529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
76381bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysocki	struct input_dev *inputdev = dev_get_drvdata(dev);
76481bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysocki
765529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long val = 0;
766ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez	if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) {
767529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		input_report_switch(inputdev, SW_TABLET_MODE, !val);
768ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez		input_sync(inputdev);
769ad20c73b05ea40cfdb42758506fb6b6befa3c9e5Carlos Alberto Lopez Perez	}
770529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
771529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
7723567a4e2c52ce2f6fe74fc85690335ec7c96608eRafael J. Wysocki#endif
773529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
77481bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysockistatic SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume);
77581bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysocki
776529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic const struct acpi_device_id cmpc_tablet_device_ids[] = {
77702e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_TABLET_HID, 0},
778529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	{"", 0}
779529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
780529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
781529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic struct acpi_driver cmpc_tablet_acpi_driver = {
782529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.owner = THIS_MODULE,
783529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.name = "cmpc_tablet",
784529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.class = "cmpc_tablet",
785529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ids = cmpc_tablet_device_ids,
786529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ops = {
787529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.add = cmpc_tablet_add,
788529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.remove = cmpc_tablet_remove,
789529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.notify = cmpc_tablet_handler,
79081bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysocki	},
79181bc495401955bf7a62d04f8c794718476a2b093Rafael J. Wysocki	.drv.pm = &cmpc_tablet_pm,
792529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
793529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
794529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
795529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
796529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo * Backlight code.
797529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
798529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
799529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_get_brightness(acpi_handle handle,
800529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				       unsigned long long *value)
801529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
802529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param;
803529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
804529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long output;
805529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
806529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
807529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param.type = ACPI_TYPE_INTEGER;
808529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param.integer.value = 0xC0;
809529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 1;
810529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = &param;
811529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
812529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status))
813529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		*value = output;
814529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
815529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
816529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
817529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic acpi_status cmpc_set_brightness(acpi_handle handle,
818529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo				       unsigned long long value)
819529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
820529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	union acpi_object param[2];
821529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct acpi_object_list input;
822529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
823529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long output;
824529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
825529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
826529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[0].integer.value = 0xC0;
827529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
828529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	param[1].integer.value = value;
829529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.count = 2;
830529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input.pointer = param;
831529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
832529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return status;
833529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
834529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
835529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_bl_get_brightness(struct backlight_device *bd)
836529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
837529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
838529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_handle handle;
839529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	unsigned long long brightness;
840529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
841529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	handle = bl_get_data(bd);
842529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = cmpc_get_brightness(handle, &brightness);
843529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status))
844529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return brightness;
845529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	else
846529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return -1;
847529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
848529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
849529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_bl_update_status(struct backlight_device *bd)
850529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
851529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_status status;
852529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_handle handle;
853529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
854529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	handle = bl_get_data(bd);
855529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	status = cmpc_set_brightness(handle, bd->props.brightness);
856529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status))
857529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return 0;
858529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	else
859529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		return -1;
860529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
861529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
862f0af78991363d704694a3618b638662c97d8a110Bruno Prémontstatic const struct backlight_ops cmpc_bl_ops = {
863529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.get_brightness = cmpc_bl_get_brightness,
864529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.update_status = cmpc_bl_update_status
865529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
866529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
867d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo/*
868d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo * RFKILL code.
869d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo */
870d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
871d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic acpi_status cmpc_get_rfkill_wlan(acpi_handle handle,
872d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo					unsigned long long *value)
873529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
874d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	union acpi_object param;
875d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct acpi_object_list input;
876d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	unsigned long long output;
877d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_status status;
878d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
879d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param.type = ACPI_TYPE_INTEGER;
880d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param.integer.value = 0xC1;
881d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	input.count = 1;
882d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	input.pointer = &param;
883d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
884d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status))
885d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		*value = output;
886d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	return status;
887d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo}
888d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
889d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic acpi_status cmpc_set_rfkill_wlan(acpi_handle handle,
890d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo					unsigned long long value)
891d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo{
892d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	union acpi_object param[2];
893d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct acpi_object_list input;
894d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_status status;
895d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	unsigned long long output;
896d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
897d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param[0].type = ACPI_TYPE_INTEGER;
898d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param[0].integer.value = 0xC1;
899d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param[1].type = ACPI_TYPE_INTEGER;
900d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	param[1].integer.value = value;
901d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	input.count = 2;
902d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	input.pointer = param;
903d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
904d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	return status;
905d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo}
906d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
907d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic void cmpc_rfkill_query(struct rfkill *rfkill, void *data)
908d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo{
909d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_status status;
910d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_handle handle;
911d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	unsigned long long state;
912d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	bool blocked;
913d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
914d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	handle = data;
915d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	status = cmpc_get_rfkill_wlan(handle, &state);
916d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (ACPI_SUCCESS(status)) {
917d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		blocked = state & 1 ? false : true;
918d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		rfkill_set_sw_state(rfkill, blocked);
919d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	}
920d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo}
921d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
922d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic int cmpc_rfkill_block(void *data, bool blocked)
923d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo{
924d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_status status;
925d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_handle handle;
926d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	unsigned long long state;
927698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski	bool is_blocked;
928d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
929d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	handle = data;
930d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	status = cmpc_get_rfkill_wlan(handle, &state);
931d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (ACPI_FAILURE(status))
932d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		return -ENODEV;
933698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski	/* Check if we really need to call cmpc_set_rfkill_wlan */
934698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski	is_blocked = state & 1 ? false : true;
935698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski	if (is_blocked != blocked) {
936698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski		state = blocked ? 0 : 1;
937698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski		status = cmpc_set_rfkill_wlan(handle, state);
938698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski		if (ACPI_FAILURE(status))
939698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski			return -ENODEV;
940698e1641a37f833dd26ee2fde5eed426cd97880bHerton Ronaldo Krzesinski	}
941d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	return 0;
942d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo}
943d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
944d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic const struct rfkill_ops cmpc_rfkill_ops = {
945d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	.query = cmpc_rfkill_query,
946d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	.set_block = cmpc_rfkill_block,
947d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo};
948d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
949d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo/*
950d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo * Common backlight and rfkill code.
951d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo */
952d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
953d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostruct ipml200_dev {
954529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct backlight_device *bd;
955d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct rfkill *rf;
956d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo};
957d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
958d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic int cmpc_ipml_add(struct acpi_device *acpi)
959d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo{
960d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	int retval;
961d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct ipml200_dev *ipml;
962d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct backlight_properties props;
963d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
964d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	ipml = kmalloc(sizeof(*ipml), GFP_KERNEL);
965d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (ipml == NULL)
966d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		return -ENOMEM;
967529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
968a19a6ee6cad2b20292a774c2f56ba8039b0fac9cMatthew Garrett	memset(&props, 0, sizeof(struct backlight_properties));
969bb7ca747f8d6243b3943c5b133048652020f4a50Matthew Garrett	props.type = BACKLIGHT_PLATFORM;
970a19a6ee6cad2b20292a774c2f56ba8039b0fac9cMatthew Garrett	props.max_brightness = 7;
971d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev,
972d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo					     acpi->handle, &cmpc_bl_ops,
973d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo					     &props);
974d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (IS_ERR(ipml->bd)) {
975d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		retval = PTR_ERR(ipml->bd);
976d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		goto out_bd;
977d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	}
978d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
979d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN,
980d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo				&cmpc_rfkill_ops, acpi->handle);
981b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	/*
982b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	 * If RFKILL is disabled, rfkill_alloc will return ERR_PTR(-ENODEV).
983b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	 * This is OK, however, since all other uses of the device will not
984b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	 * derefence it.
985b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	 */
986b95d13eaf3d4ea093aba95c7f615f3b10708a2c4Thadeu Lima de Souza Cascardo	if (ipml->rf) {
987d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		retval = rfkill_register(ipml->rf);
988d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		if (retval) {
989d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo			rfkill_destroy(ipml->rf);
990d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo			ipml->rf = NULL;
991d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		}
992d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	}
993d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
994d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	dev_set_drvdata(&acpi->dev, ipml);
995529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
996d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
997d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardoout_bd:
998d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	kfree(ipml);
999d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	return retval;
1000529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1001529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
100251fac8388a0325a43f0ae67453ece2c373e2ec28Rafael J. Wysockistatic int cmpc_ipml_remove(struct acpi_device *acpi)
1003529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1004d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	struct ipml200_dev *ipml;
1005d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
1006d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	ipml = dev_get_drvdata(&acpi->dev);
1007d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
1008d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	backlight_device_unregister(ipml->bd);
1009d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
1010d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	if (ipml->rf) {
1011d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		rfkill_unregister(ipml->rf);
1012d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		rfkill_destroy(ipml->rf);
1013d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	}
1014d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo
1015d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	kfree(ipml);
1016529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1017529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return 0;
1018529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1019529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1020d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic const struct acpi_device_id cmpc_ipml_device_ids[] = {
1021d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	{CMPC_IPML_HID, 0},
1022529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	{"", 0}
1023529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
1024529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1025d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardostatic struct acpi_driver cmpc_ipml_acpi_driver = {
1026529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.owner = THIS_MODULE,
1027529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.name = "cmpc",
1028529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.class = "cmpc",
1029d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	.ids = cmpc_ipml_device_ids,
1030529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ops = {
1031d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		.add = cmpc_ipml_add,
1032d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo		.remove = cmpc_ipml_remove
1033529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
1034529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
1035529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1036529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1037529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
1038529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo * Extra keys code.
1039529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
1040529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_keys_codes[] = {
1041529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_UNKNOWN,
1042529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_WLAN,
1043529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_SWITCHVIDEOMODE,
1044529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_BRIGHTNESSDOWN,
1045529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_BRIGHTNESSUP,
1046529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_VENDOR,
1047881a6c25a8453388e3190de94a5e105439a9f806Thadeu Lima de Souza Cascardo	KEY_UNKNOWN,
1048881a6c25a8453388e3190de94a5e105439a9f806Thadeu Lima de Souza Cascardo	KEY_CAMERA,
1049881a6c25a8453388e3190de94a5e105439a9f806Thadeu Lima de Souza Cascardo	KEY_BACK,
1050881a6c25a8453388e3190de94a5e105439a9f806Thadeu Lima de Souza Cascardo	KEY_FORWARD,
1051529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	KEY_MAX
1052529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
1053529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1054529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_keys_handler(struct acpi_device *dev, u32 event)
1055529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1056529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	struct input_dev *inputdev;
1057529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int code = KEY_MAX;
1058529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1059529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes))
1060529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		code = cmpc_keys_codes[event & 0x0F];
10613098064d3b4a9bf9d2855b2a89599ad77695e324Joe Perches	inputdev = dev_get_drvdata(&dev->dev);
1062529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	input_report_key(inputdev, code, !(event & 0x10));
106372135d21b587debcbcc57e0dbcc8bcfa4dacb661Herton Ronaldo Krzesinski	input_sync(inputdev);
1064529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1065529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1066529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_keys_idev_init(struct input_dev *inputdev)
1067529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1068529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int i;
1069529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1070529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	set_bit(EV_KEY, inputdev->evbit);
1071529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++)
1072529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		set_bit(cmpc_keys_codes[i], inputdev->keybit);
1073529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1074529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1075529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_keys_add(struct acpi_device *acpi)
1076529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1077529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return cmpc_add_acpi_notify_device(acpi, "cmpc_keys",
1078529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo					   cmpc_keys_idev_init);
1079529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1080529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
108151fac8388a0325a43f0ae67453ece2c373e2ec28Rafael J. Wysockistatic int cmpc_keys_remove(struct acpi_device *acpi)
1082529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1083529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return cmpc_remove_acpi_notify_device(acpi);
1084529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1085529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1086529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic const struct acpi_device_id cmpc_keys_device_ids[] = {
108702e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_KEYS_HID, 0},
1088529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	{"", 0}
1089529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
1090529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1091529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic struct acpi_driver cmpc_keys_acpi_driver = {
1092529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.owner = THIS_MODULE,
1093529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.name = "cmpc_keys",
1094529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.class = "cmpc_keys",
1095529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ids = cmpc_keys_device_ids,
1096529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	.ops = {
1097529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.add = cmpc_keys_add,
1098529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.remove = cmpc_keys_remove,
1099529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		.notify = cmpc_keys_handler,
1100529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	}
1101529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo};
1102529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1103529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1104529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo/*
1105529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo * General init/exit code.
1106529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo */
1107529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1108529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic int cmpc_init(void)
1109529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
1110529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	int r;
1111529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1112529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	r = acpi_bus_register_driver(&cmpc_keys_acpi_driver);
1113529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (r)
1114529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_keys;
1115529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1116d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver);
1117529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (r)
1118529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_bl;
1119529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1120529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver);
1121529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (r)
1122529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_tablet;
1123529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1124529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver);
1125529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	if (r)
1126529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo		goto failed_accel;
1127529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
11287125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
11297125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	if (r)
11307125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez		goto failed_accel_v4;
11317125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1132529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return r;
1133529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
11347125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómezfailed_accel_v4:
11357125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
11367125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez
1137529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_accel:
1138529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
1139529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1140529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_tablet:
1141d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
1142529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1143529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_bl:
1144529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
1145529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1146529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardofailed_keys:
1147529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	return r;
1148529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1149529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1150529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardostatic void cmpc_exit(void)
1151529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo{
11527125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
1153529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
1154529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
1155d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
1156529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
1157529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo}
1158529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardo
1159529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardomodule_init(cmpc_init);
1160529aa8cb0a59367d08883f818e8c47028e819d0dThadeu Lima de Souza Cascardomodule_exit(cmpc_exit);
116102e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo
116202e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardostatic const struct acpi_device_id cmpc_device_ids[] = {
116302e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_ACCEL_HID, 0},
11647125587df4e87224dbd3b90ddf6f23e83044ae30Miguel Gómez	{CMPC_ACCEL_HID_V4, 0},
116502e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_TABLET_HID, 0},
1166d5c051f1080e0eec55f3fc42c37d941681941628Thadeu Lima de Souza Cascardo	{CMPC_IPML_HID, 0},
116702e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{CMPC_KEYS_HID, 0},
116802e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo	{"", 0}
116902e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo};
117002e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza Cascardo
117102e77a55f7b7e36888e39c62439fedb90ae4e808Thadeu Lima de Souza CascardoMODULE_DEVICE_TABLE(acpi, cmpc_device_ids);
1172