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 = ¶m; 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 = ¶m; 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 = ¶m; 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