diff options
| -rw-r--r-- | drivers/misc/sony-laptop.c | 190 |
1 files changed, 140 insertions, 50 deletions
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 5300cad9cd7f..af69b3bd01da 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
| @@ -142,45 +142,124 @@ struct sony_laptop_keypress { | |||
| 142 | int key; | 142 | int key; |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | /* Correspondance table between sonypi events and input layer events */ | 145 | /* Correspondance table between sonypi events |
| 146 | static struct { | 146 | * and input layer indexes in the keymap |
| 147 | int sonypiev; | 147 | */ |
| 148 | int inputev; | 148 | static int sony_laptop_input_index[] = { |
| 149 | } sony_laptop_inputkeys[] = { | 149 | -1, /* no event */ |
| 150 | { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, | 150 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN */ |
| 151 | { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, | 151 | -1, /* SONYPI_EVENT_JOGDIAL_UP */ |
| 152 | { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, | 152 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ |
| 153 | { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, | 153 | -1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */ |
| 154 | { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, | 154 | -1, /* SONYPI_EVENT_JOGDIAL_PRESSED */ |
| 155 | { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, | 155 | -1, /* SONYPI_EVENT_JOGDIAL_RELEASED */ |
| 156 | { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, | 156 | 0, /* SONYPI_EVENT_CAPTURE_PRESSED */ |
| 157 | { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, | 157 | 1, /* SONYPI_EVENT_CAPTURE_RELEASED */ |
| 158 | { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, | 158 | 2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ |
| 159 | { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, | 159 | 3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ |
| 160 | { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, | 160 | 4, /* SONYPI_EVENT_FNKEY_ESC */ |
| 161 | { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, | 161 | 5, /* SONYPI_EVENT_FNKEY_F1 */ |
| 162 | { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, | 162 | 6, /* SONYPI_EVENT_FNKEY_F2 */ |
| 163 | { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, | 163 | 7, /* SONYPI_EVENT_FNKEY_F3 */ |
| 164 | { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, | 164 | 8, /* SONYPI_EVENT_FNKEY_F4 */ |
| 165 | { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, | 165 | 9, /* SONYPI_EVENT_FNKEY_F5 */ |
| 166 | { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, | 166 | 10, /* SONYPI_EVENT_FNKEY_F6 */ |
| 167 | { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, | 167 | 11, /* SONYPI_EVENT_FNKEY_F7 */ |
| 168 | { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, | 168 | 12, /* SONYPI_EVENT_FNKEY_F8 */ |
| 169 | { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, | 169 | 13, /* SONYPI_EVENT_FNKEY_F9 */ |
| 170 | { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, | 170 | 14, /* SONYPI_EVENT_FNKEY_F10 */ |
| 171 | { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, | 171 | 15, /* SONYPI_EVENT_FNKEY_F11 */ |
| 172 | { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, | 172 | 16, /* SONYPI_EVENT_FNKEY_F12 */ |
| 173 | { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, | 173 | 17, /* SONYPI_EVENT_FNKEY_1 */ |
| 174 | { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, | 174 | 18, /* SONYPI_EVENT_FNKEY_2 */ |
| 175 | { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, | 175 | 19, /* SONYPI_EVENT_FNKEY_D */ |
| 176 | { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, | 176 | 20, /* SONYPI_EVENT_FNKEY_E */ |
| 177 | { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, | 177 | 21, /* SONYPI_EVENT_FNKEY_F */ |
| 178 | { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, | 178 | 22, /* SONYPI_EVENT_FNKEY_S */ |
| 179 | { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, | 179 | 23, /* SONYPI_EVENT_FNKEY_B */ |
| 180 | { SONYPI_EVENT_WIRELESS_ON, KEY_WLAN }, | 180 | 24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */ |
| 181 | { SONYPI_EVENT_WIRELESS_OFF, KEY_WLAN }, | 181 | 25, /* SONYPI_EVENT_PKEY_P1 */ |
| 182 | { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, | 182 | 26, /* SONYPI_EVENT_PKEY_P2 */ |
| 183 | { 0, 0 }, | 183 | 27, /* SONYPI_EVENT_PKEY_P3 */ |
| 184 | 28, /* SONYPI_EVENT_BACK_PRESSED */ | ||
| 185 | -1, /* SONYPI_EVENT_LID_CLOSED */ | ||
| 186 | -1, /* SONYPI_EVENT_LID_OPENED */ | ||
| 187 | 29, /* SONYPI_EVENT_BLUETOOTH_ON */ | ||
| 188 | 30, /* SONYPI_EVENT_BLUETOOTH_OFF */ | ||
| 189 | 31, /* SONYPI_EVENT_HELP_PRESSED */ | ||
| 190 | 32, /* SONYPI_EVENT_FNKEY_ONLY */ | ||
| 191 | 33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
| 192 | 34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
| 193 | 35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
| 194 | 36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
| 195 | 37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
| 196 | 38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
| 197 | 39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
| 198 | 40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
| 199 | 41, /* SONYPI_EVENT_ZOOM_PRESSED */ | ||
| 200 | 42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
| 201 | 43, /* SONYPI_EVENT_MEYE_FACE */ | ||
| 202 | 44, /* SONYPI_EVENT_MEYE_OPPOSITE */ | ||
| 203 | 45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
| 204 | 46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
| 205 | -1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */ | ||
| 206 | -1, /* SONYPI_EVENT_BATTERY_INSERT */ | ||
| 207 | -1, /* SONYPI_EVENT_BATTERY_REMOVE */ | ||
| 208 | -1, /* SONYPI_EVENT_FNKEY_RELEASED */ | ||
| 209 | 47, /* SONYPI_EVENT_WIRELESS_ON */ | ||
| 210 | 48, /* SONYPI_EVENT_WIRELESS_OFF */ | ||
| 211 | }; | ||
| 212 | |||
| 213 | static int sony_laptop_input_keycode_map[] = { | ||
| 214 | KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ | ||
| 215 | KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ | ||
| 216 | KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ | ||
| 217 | KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ | ||
| 218 | KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ | ||
| 219 | KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ | ||
| 220 | KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ | ||
| 221 | KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ | ||
| 222 | KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ | ||
| 223 | KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ | ||
| 224 | KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ | ||
| 225 | KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ | ||
| 226 | KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ | ||
| 227 | KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ | ||
| 228 | KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ | ||
| 229 | KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ | ||
| 230 | KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ | ||
| 231 | KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ | ||
| 232 | KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ | ||
| 233 | KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ | ||
| 234 | KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ | ||
| 235 | KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ | ||
| 236 | KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ | ||
| 237 | KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ | ||
| 238 | KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ | ||
| 239 | KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ | ||
| 240 | KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ | ||
| 241 | KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ | ||
| 242 | KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ | ||
| 243 | KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ | ||
| 244 | KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ | ||
| 245 | KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ | ||
| 246 | KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ | ||
| 247 | KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
| 248 | KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
| 249 | KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
| 250 | KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
| 251 | KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
| 252 | KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
| 253 | KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
| 254 | KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
| 255 | KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ | ||
| 256 | BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
| 257 | KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ | ||
| 258 | KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ | ||
| 259 | KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
| 260 | KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
| 261 | KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ | ||
| 262 | KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ | ||
| 184 | }; | 263 | }; |
| 185 | 264 | ||
| 186 | /* release buttons after a short delay if pressed */ | 265 | /* release buttons after a short delay if pressed */ |
| @@ -204,7 +283,6 @@ static void sony_laptop_report_input_event(u8 event) | |||
| 204 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; | 283 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; |
| 205 | struct input_dev *key_dev = sony_laptop_input.key_dev; | 284 | struct input_dev *key_dev = sony_laptop_input.key_dev; |
| 206 | struct sony_laptop_keypress kp = { NULL }; | 285 | struct sony_laptop_keypress kp = { NULL }; |
| 207 | int i; | ||
| 208 | 286 | ||
| 209 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { | 287 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { |
| 210 | /* Nothing, not all VAIOs generate this event */ | 288 | /* Nothing, not all VAIOs generate this event */ |
| @@ -233,17 +311,22 @@ static void sony_laptop_report_input_event(u8 event) | |||
| 233 | break; | 311 | break; |
| 234 | 312 | ||
| 235 | default: | 313 | default: |
| 236 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 314 | if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) { |
| 237 | if (event == sony_laptop_inputkeys[i].sonypiev) { | 315 | dprintk("sony_laptop_report_input_event, event not known: %d\n", event); |
| 316 | break; | ||
| 317 | } | ||
| 318 | if (sony_laptop_input_index[event] != -1) { | ||
| 319 | kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]]; | ||
| 320 | if (kp.key != KEY_UNKNOWN) | ||
| 238 | kp.dev = key_dev; | 321 | kp.dev = key_dev; |
| 239 | kp.key = sony_laptop_inputkeys[i].inputev; | 322 | } |
| 240 | break; | ||
| 241 | } | ||
| 242 | break; | 323 | break; |
| 243 | } | 324 | } |
| 244 | 325 | ||
| 245 | if (kp.dev) { | 326 | if (kp.dev) { |
| 246 | input_report_key(kp.dev, kp.key, 1); | 327 | input_report_key(kp.dev, kp.key, 1); |
| 328 | /* we emit the scancode so we can always remap the key */ | ||
| 329 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | ||
| 247 | input_sync(kp.dev); | 330 | input_sync(kp.dev); |
| 248 | kfifo_put(sony_laptop_input.fifo, | 331 | kfifo_put(sony_laptop_input.fifo, |
| 249 | (unsigned char *)&kp, sizeof(kp)); | 332 | (unsigned char *)&kp, sizeof(kp)); |
| @@ -298,11 +381,18 @@ static int sony_laptop_setup_input(void) | |||
| 298 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; | 381 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; |
| 299 | 382 | ||
| 300 | /* Initialize the Input Drivers: special keys */ | 383 | /* Initialize the Input Drivers: special keys */ |
| 301 | key_dev->evbit[0] = BIT(EV_KEY); | 384 | set_bit(EV_KEY, key_dev->evbit); |
| 302 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 385 | set_bit(EV_MSC, key_dev->evbit); |
| 303 | if (sony_laptop_inputkeys[i].inputev) | 386 | set_bit(MSC_SCAN, key_dev->mscbit); |
| 304 | set_bit(sony_laptop_inputkeys[i].inputev, | 387 | key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); |
| 305 | key_dev->keybit); | 388 | key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); |
| 389 | key_dev->keycode = &sony_laptop_input_keycode_map; | ||
| 390 | for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { | ||
| 391 | if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { | ||
| 392 | set_bit(sony_laptop_input_keycode_map[i], | ||
| 393 | key_dev->keybit); | ||
| 394 | } | ||
| 395 | } | ||
| 306 | 396 | ||
| 307 | error = input_register_device(key_dev); | 397 | error = input_register_device(key_dev); |
| 308 | if (error) | 398 | if (error) |
