asus-laptop.c (d0930a2d42c5a28039d8cc2376a7dff4e59c5f7a) asus-laptop.c (66a71dd1f7c4eee636867d381995b7e6ae489dc3)
1/*
2 * asus-laptop.c - Asus Laptop Support
3 *
4 *
5 * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
6 * Copyright (C) 2006-2007 Corentin Chary
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 35 unchanged lines hidden (view full) ---

44#include <linux/backlight.h>
45#include <linux/fb.h>
46#include <linux/leds.h>
47#include <linux/platform_device.h>
48#include <acpi/acpi_drivers.h>
49#include <acpi/acpi_bus.h>
50#include <asm/uaccess.h>
51#include <linux/input.h>
1/*
2 * asus-laptop.c - Asus Laptop Support
3 *
4 *
5 * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
6 * Copyright (C) 2006-2007 Corentin Chary
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 35 unchanged lines hidden (view full) ---

44#include <linux/backlight.h>
45#include <linux/fb.h>
46#include <linux/leds.h>
47#include <linux/platform_device.h>
48#include <acpi/acpi_drivers.h>
49#include <acpi/acpi_bus.h>
50#include <asm/uaccess.h>
51#include <linux/input.h>
52#include <linux/input/sparse-keymap.h>
52
53#define ASUS_LAPTOP_VERSION "0.42"
54
55#define ASUS_LAPTOP_NAME "Asus Laptop Support"
56#define ASUS_LAPTOP_CLASS "hotkey"
57#define ASUS_LAPTOP_DEVICE_NAME "Hotkey"
58#define ASUS_LAPTOP_FILE KBUILD_MODNAME
59#define ASUS_LAPTOP_PREFIX "\\_SB.ATKD."

--- 178 unchanged lines hidden (view full) ---

238 acpi_handle handle; /* the handle of the hotk device */
239 u32 ledd_status; /* status of the LED display */
240 u8 light_level; /* light sensor level */
241 u8 light_switch; /* light sensor switch value */
242 u16 event_count[128]; /* count for each event TODO make this better */
243 u16 *keycode_map;
244};
245
53
54#define ASUS_LAPTOP_VERSION "0.42"
55
56#define ASUS_LAPTOP_NAME "Asus Laptop Support"
57#define ASUS_LAPTOP_CLASS "hotkey"
58#define ASUS_LAPTOP_DEVICE_NAME "Hotkey"
59#define ASUS_LAPTOP_FILE KBUILD_MODNAME
60#define ASUS_LAPTOP_PREFIX "\\_SB.ATKD."

--- 178 unchanged lines hidden (view full) ---

239 acpi_handle handle; /* the handle of the hotk device */
240 u32 ledd_status; /* status of the LED display */
241 u8 light_level; /* light sensor level */
242 u8 light_switch; /* light sensor switch value */
243 u16 event_count[128]; /* count for each event TODO make this better */
244 u16 *keycode_map;
245};
246
246struct key_entry {
247 char type;
248 u8 code;
249 u16 keycode;
250};
251
252enum { KE_KEY, KE_END };
253
254static const struct key_entry asus_keymap[] = {
247static const struct key_entry asus_keymap[] = {
255 {KE_KEY, 0x02, KEY_SCREENLOCK},
256 {KE_KEY, 0x05, KEY_WLAN},
257 {KE_KEY, 0x08, KEY_F13},
258 {KE_KEY, 0x17, KEY_ZOOM},
259 {KE_KEY, 0x1f, KEY_BATTERY},
260 {KE_KEY, 0x30, KEY_VOLUMEUP},
261 {KE_KEY, 0x31, KEY_VOLUMEDOWN},
262 {KE_KEY, 0x32, KEY_MUTE},
263 {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
264 {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
265 {KE_KEY, 0x40, KEY_PREVIOUSSONG},
266 {KE_KEY, 0x41, KEY_NEXTSONG},
267 {KE_KEY, 0x43, KEY_STOPCD},
268 {KE_KEY, 0x45, KEY_PLAYPAUSE},
269 {KE_KEY, 0x4c, KEY_MEDIA},
270 {KE_KEY, 0x50, KEY_EMAIL},
271 {KE_KEY, 0x51, KEY_WWW},
272 {KE_KEY, 0x55, KEY_CALC},
273 {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */
274 {KE_KEY, 0x5D, KEY_WLAN},
275 {KE_KEY, 0x5E, KEY_WLAN},
276 {KE_KEY, 0x5F, KEY_WLAN},
277 {KE_KEY, 0x60, KEY_SWITCHVIDEOMODE},
278 {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
279 {KE_KEY, 0x62, KEY_SWITCHVIDEOMODE},
280 {KE_KEY, 0x63, KEY_SWITCHVIDEOMODE},
281 {KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */
282 {KE_KEY, 0x82, KEY_CAMERA},
283 {KE_KEY, 0x88, KEY_WLAN },
284 {KE_KEY, 0x8A, KEY_PROG1},
285 {KE_KEY, 0x95, KEY_MEDIA},
286 {KE_KEY, 0x99, KEY_PHONE},
287 {KE_KEY, 0xc4, KEY_KBDILLUMUP},
288 {KE_KEY, 0xc5, KEY_KBDILLUMDOWN},
248 {KE_KEY, 0x02, { KEY_SCREENLOCK } },
249 {KE_KEY, 0x05, { KEY_WLAN } },
250 {KE_KEY, 0x08, { KEY_F13 } },
251 {KE_KEY, 0x17, { KEY_ZOOM } },
252 {KE_KEY, 0x1f, { KEY_BATTERY } },
253 {KE_KEY, 0x30, { KEY_VOLUMEUP } },
254 {KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
255 {KE_KEY, 0x32, { KEY_MUTE } },
256 {KE_KEY, 0x33, { KEY_SWITCHVIDEOMODE } },
257 {KE_KEY, 0x34, { KEY_SWITCHVIDEOMODE } },
258 {KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
259 {KE_KEY, 0x41, { KEY_NEXTSONG } },
260 {KE_KEY, 0x43, { KEY_STOPCD } },
261 {KE_KEY, 0x45, { KEY_PLAYPAUSE } },
262 {KE_KEY, 0x4c, { KEY_MEDIA } },
263 {KE_KEY, 0x50, { KEY_EMAIL } },
264 {KE_KEY, 0x51, { KEY_WWW } },
265 {KE_KEY, 0x55, { KEY_CALC } },
266 {KE_KEY, 0x5C, { KEY_SCREENLOCK } }, /* Screenlock */
267 {KE_KEY, 0x5D, { KEY_WLAN } },
268 {KE_KEY, 0x5E, { KEY_WLAN } },
269 {KE_KEY, 0x5F, { KEY_WLAN } },
270 {KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } },
271 {KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } },
272 {KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } },
273 {KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } },
274 {KE_KEY, 0x6B, { KEY_F13 } }, /* Lock Touchpad */
275 {KE_KEY, 0x82, { KEY_CAMERA } },
276 {KE_KEY, 0x88, { KEY_WLAN } },
277 {KE_KEY, 0x8A, { KEY_PROG1 } },
278 {KE_KEY, 0x95, { KEY_MEDIA } },
279 {KE_KEY, 0x99, { KEY_PHONE } },
280 {KE_KEY, 0xc4, { KEY_KBDILLUMUP } },
281 {KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } },
289 {KE_END, 0},
290};
291
282 {KE_END, 0},
283};
284
285
292/*
293 * This function evaluates an ACPI method, given an int as parameter, the
294 * method is searched within the scope of the handle, can be NULL. The output
295 * of the method is written is output, which can also be NULL
296 *
297 * returns 0 if write is successful, -1 else.
298 */
299static int write_acpi_int_ret(acpi_handle handle, const char *method, int val,

--- 745 unchanged lines hidden (view full) ---

1045 if (ret)
1046 return ret;
1047 return rv;
1048}
1049
1050/*
1051 * Input device (i.e. hotkeys)
1052 */
286/*
287 * This function evaluates an ACPI method, given an int as parameter, the
288 * method is searched within the scope of the handle, can be NULL. The output
289 * of the method is written is output, which can also be NULL
290 *
291 * returns 0 if write is successful, -1 else.
292 */
293static int write_acpi_int_ret(acpi_handle handle, const char *method, int val,

--- 745 unchanged lines hidden (view full) ---

1039 if (ret)
1040 return ret;
1041 return rv;
1042}
1043
1044/*
1045 * Input device (i.e. hotkeys)
1046 */
1053static struct key_entry *asus_get_entry_by_scancode(struct asus_laptop *asus,
1054 int code)
1055{
1056 struct key_entry *key;
1057
1058 for (key = asus->keymap; key->type != KE_END; key++)
1059 if (code == key->code)
1060 return key;
1061
1062 return NULL;
1063}
1064
1065static struct key_entry *asus_get_entry_by_keycode(struct asus_laptop *asus,
1066 int code)
1067{
1068 struct key_entry *key;
1069
1070 for (key = asus->keymap; key->type != KE_END; key++)
1071 if (code == key->keycode && key->type == KE_KEY)
1072 return key;
1073
1074 return NULL;
1075}
1076
1077static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1078{
1079 struct asus_laptop *asus = input_get_drvdata(dev);
1080 struct key_entry *key = asus_get_entry_by_scancode(asus, scancode);
1081
1082 if (key && key->type == KE_KEY) {
1083 *keycode = key->keycode;
1084 return 0;
1085 }
1086
1087 return -EINVAL;
1088}
1089
1090static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
1091{
1092 struct asus_laptop *asus = input_get_drvdata(dev);
1093 struct key_entry *key;
1094 int old_keycode;
1095
1096 if (keycode < 0 || keycode > KEY_MAX)
1097 return -EINVAL;
1098
1099 key = asus_get_entry_by_scancode(asus, scancode);
1100 if (key && key->type == KE_KEY) {
1101 old_keycode = key->keycode;
1102 key->keycode = keycode;
1103 set_bit(keycode, dev->keybit);
1104 if (!asus_get_entry_by_keycode(asus, old_keycode))
1105 clear_bit(old_keycode, dev->keybit);
1106 return 0;
1107 }
1108
1109 return -EINVAL;
1110}
1111
1112static void asus_input_notify(struct asus_laptop *asus, int event)
1113{
1047static void asus_input_notify(struct asus_laptop *asus, int event)
1048{
1114 struct key_entry *key;
1115
1116 key = asus_get_entry_by_scancode(asus, event);
1117 if (!key)
1118 return ;
1119
1120 switch (key->type) {
1121 case KE_KEY:
1122 input_report_key(asus->inputdev, key->keycode, 1);
1123 input_sync(asus->inputdev);
1124 input_report_key(asus->inputdev, key->keycode, 0);
1125 input_sync(asus->inputdev);
1126 break;
1127 }
1049 if (asus->inputdev)
1050 sparse_keymap_report_event(asus->inputdev, event, 1, true);
1128}
1129
1130static int asus_input_init(struct asus_laptop *asus)
1131{
1051}
1052
1053static int asus_input_init(struct asus_laptop *asus)
1054{
1132 const struct key_entry *key;
1133 int result;
1055 struct input_dev *input;
1056 int error;
1134
1057
1135 asus->inputdev = input_allocate_device();
1136 if (!asus->inputdev) {
1058 input = input_allocate_device();
1059 if (!input) {
1137 pr_info("Unable to allocate input device\n");
1138 return 0;
1139 }
1060 pr_info("Unable to allocate input device\n");
1061 return 0;
1062 }
1140 asus->inputdev->name = "Asus Laptop extra buttons";
1141 asus->inputdev->dev.parent = &asus->platform_device->dev;
1142 asus->inputdev->phys = ASUS_LAPTOP_FILE "/input0";
1143 asus->inputdev->id.bustype = BUS_HOST;
1144 asus->inputdev->getkeycode = asus_getkeycode;
1145 asus->inputdev->setkeycode = asus_setkeycode;
1146 input_set_drvdata(asus->inputdev, asus);
1063 input->name = "Asus Laptop extra buttons";
1064 input->phys = ASUS_LAPTOP_FILE "/input0";
1065 input->id.bustype = BUS_HOST;
1066 input->dev.parent = &asus->platform_device->dev;
1067 input_set_drvdata(input, asus);
1147
1068
1148 asus->keymap = kmemdup(asus_keymap, sizeof(asus_keymap),
1149 GFP_KERNEL);
1150 for (key = asus->keymap; key->type != KE_END; key++) {
1151 switch (key->type) {
1152 case KE_KEY:
1153 set_bit(EV_KEY, asus->inputdev->evbit);
1154 set_bit(key->keycode, asus->inputdev->keybit);
1155 break;
1156 }
1069 error = sparse_keymap_setup(input, asus_keymap, NULL);
1070 if (error) {
1071 pr_err("Unable to setup input device keymap\n");
1072 goto err_keymap;
1157 }
1073 }
1158 result = input_register_device(asus->inputdev);
1159 if (result) {
1074 error = input_register_device(input);
1075 if (error) {
1160 pr_info("Unable to register input device\n");
1076 pr_info("Unable to register input device\n");
1161 input_free_device(asus->inputdev);
1077 goto err_device;
1162 }
1078 }
1163 return result;
1079
1080 asus->inputdev = input;
1081 return 0;
1082
1083err_keymap:
1084 sparse_keymap_free(input);
1085err_device:
1086 input_free_device(input);
1087 return error;
1164}
1165
1166static void asus_input_exit(struct asus_laptop *asus)
1167{
1088}
1089
1090static void asus_input_exit(struct asus_laptop *asus)
1091{
1168 if (asus->inputdev)
1092 if (asus->inputdev) {
1093 sparse_keymap_free(asus->inputdev);
1169 input_unregister_device(asus->inputdev);
1094 input_unregister_device(asus->inputdev);
1095 }
1170}
1171
1172/*
1173 * ACPI driver
1174 */
1175static void asus_acpi_notify(struct acpi_device *device, u32 event)
1176{
1177 struct asus_laptop *asus = acpi_driver_data(device);

--- 424 unchanged lines hidden ---
1096}
1097
1098/*
1099 * ACPI driver
1100 */
1101static void asus_acpi_notify(struct acpi_device *device, u32 event)
1102{
1103 struct asus_laptop *asus = acpi_driver_data(device);

--- 424 unchanged lines hidden ---