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