1 /* 2 * ACPI Sony Notebook Control Driver (SNC and SPIC) 3 * 4 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> 5 * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it> 6 * 7 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c 8 * which are copyrighted by their respective authors. 9 * 10 * The SNY6001 driver part is based on the sonypi driver which includes 11 * material from: 12 * 13 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net> 14 * 15 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org> 16 * 17 * Copyright (C) 2001-2002 Alcôve <www.alcove.com> 18 * 19 * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> 20 * 21 * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> 22 * 23 * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp> 24 * 25 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> 26 * 27 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. 28 * 29 * This program is free software; you can redistribute it and/or modify 30 * it under the terms of the GNU General Public License as published by 31 * the Free Software Foundation; either version 2 of the License, or 32 * (at your option) any later version. 33 * 34 * This program is distributed in the hope that it will be useful, 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 * GNU General Public License for more details. 38 * 39 * You should have received a copy of the GNU General Public License 40 * along with this program; if not, write to the Free Software 41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 42 * 43 */ 44 45 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 46 47 #include <linux/kernel.h> 48 #include <linux/module.h> 49 #include <linux/moduleparam.h> 50 #include <linux/init.h> 51 #include <linux/types.h> 52 #include <linux/backlight.h> 53 #include <linux/platform_device.h> 54 #include <linux/err.h> 55 #include <linux/dmi.h> 56 #include <linux/pci.h> 57 #include <linux/interrupt.h> 58 #include <linux/delay.h> 59 #include <linux/input.h> 60 #include <linux/kfifo.h> 61 #include <linux/workqueue.h> 62 #include <linux/acpi.h> 63 #include <linux/slab.h> 64 #include <acpi/acpi_drivers.h> 65 #include <acpi/acpi_bus.h> 66 #include <asm/uaccess.h> 67 #include <linux/sonypi.h> 68 #include <linux/sony-laptop.h> 69 #include <linux/rfkill.h> 70 #ifdef CONFIG_SONYPI_COMPAT 71 #include <linux/poll.h> 72 #include <linux/miscdevice.h> 73 #endif 74 75 #define dprintk(fmt, ...) \ 76 do { \ 77 if (debug) \ 78 pr_warn(fmt, ##__VA_ARGS__); \ 79 } while (0) 80 81 #define SONY_LAPTOP_DRIVER_VERSION "0.6" 82 83 #define SONY_NC_CLASS "sony-nc" 84 #define SONY_NC_HID "SNY5001" 85 #define SONY_NC_DRIVER_NAME "Sony Notebook Control Driver" 86 87 #define SONY_PIC_CLASS "sony-pic" 88 #define SONY_PIC_HID "SNY6001" 89 #define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control Driver" 90 91 MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); 92 MODULE_DESCRIPTION("Sony laptop extras driver (SPIC and SNC ACPI device)"); 93 MODULE_LICENSE("GPL"); 94 MODULE_VERSION(SONY_LAPTOP_DRIVER_VERSION); 95 96 static int debug; 97 module_param(debug, int, 0); 98 MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " 99 "the development of this driver"); 100 101 static int no_spic; /* = 0 */ 102 module_param(no_spic, int, 0444); 103 MODULE_PARM_DESC(no_spic, 104 "set this if you don't want to enable the SPIC device"); 105 106 static int compat; /* = 0 */ 107 module_param(compat, int, 0444); 108 MODULE_PARM_DESC(compat, 109 "set this if you want to enable backward compatibility mode"); 110 111 static unsigned long mask = 0xffffffff; 112 module_param(mask, ulong, 0644); 113 MODULE_PARM_DESC(mask, 114 "set this to the mask of event you want to enable (see doc)"); 115 116 static int camera; /* = 0 */ 117 module_param(camera, int, 0444); 118 MODULE_PARM_DESC(camera, 119 "set this to 1 to enable Motion Eye camera controls " 120 "(only use it if you have a C1VE or C1VN model)"); 121 122 #ifdef CONFIG_SONYPI_COMPAT 123 static int minor = -1; 124 module_param(minor, int, 0); 125 MODULE_PARM_DESC(minor, 126 "minor number of the misc device for the SPIC compatibility code, " 127 "default is -1 (automatic)"); 128 #endif 129 130 static int kbd_backlight = 1; 131 module_param(kbd_backlight, int, 0444); 132 MODULE_PARM_DESC(kbd_backlight, 133 "set this to 0 to disable keyboard backlight, " 134 "1 to enable it (default: 0)"); 135 136 static int kbd_backlight_timeout; /* = 0 */ 137 module_param(kbd_backlight_timeout, int, 0444); 138 MODULE_PARM_DESC(kbd_backlight_timeout, 139 "set this to 0 to set the default 10 seconds timeout, " 140 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " 141 "(default: 0)"); 142 143 static void sony_nc_kbd_backlight_resume(void); 144 145 enum sony_nc_rfkill { 146 SONY_WIFI, 147 SONY_BLUETOOTH, 148 SONY_WWAN, 149 SONY_WIMAX, 150 N_SONY_RFKILL, 151 }; 152 153 static int sony_rfkill_handle; 154 static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; 155 static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; 156 static void sony_nc_rfkill_update(void); 157 158 /*********** Input Devices ***********/ 159 160 #define SONY_LAPTOP_BUF_SIZE 128 161 struct sony_laptop_input_s { 162 atomic_t users; 163 struct input_dev *jog_dev; 164 struct input_dev *key_dev; 165 struct kfifo fifo; 166 spinlock_t fifo_lock; 167 struct timer_list release_key_timer; 168 }; 169 170 static struct sony_laptop_input_s sony_laptop_input = { 171 .users = ATOMIC_INIT(0), 172 }; 173 174 struct sony_laptop_keypress { 175 struct input_dev *dev; 176 int key; 177 }; 178 179 /* Correspondance table between sonypi events 180 * and input layer indexes in the keymap 181 */ 182 static int sony_laptop_input_index[] = { 183 -1, /* 0 no event */ 184 -1, /* 1 SONYPI_EVENT_JOGDIAL_DOWN */ 185 -1, /* 2 SONYPI_EVENT_JOGDIAL_UP */ 186 -1, /* 3 SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ 187 -1, /* 4 SONYPI_EVENT_JOGDIAL_UP_PRESSED */ 188 -1, /* 5 SONYPI_EVENT_JOGDIAL_PRESSED */ 189 -1, /* 6 SONYPI_EVENT_JOGDIAL_RELEASED */ 190 0, /* 7 SONYPI_EVENT_CAPTURE_PRESSED */ 191 1, /* 8 SONYPI_EVENT_CAPTURE_RELEASED */ 192 2, /* 9 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 193 3, /* 10 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 194 4, /* 11 SONYPI_EVENT_FNKEY_ESC */ 195 5, /* 12 SONYPI_EVENT_FNKEY_F1 */ 196 6, /* 13 SONYPI_EVENT_FNKEY_F2 */ 197 7, /* 14 SONYPI_EVENT_FNKEY_F3 */ 198 8, /* 15 SONYPI_EVENT_FNKEY_F4 */ 199 9, /* 16 SONYPI_EVENT_FNKEY_F5 */ 200 10, /* 17 SONYPI_EVENT_FNKEY_F6 */ 201 11, /* 18 SONYPI_EVENT_FNKEY_F7 */ 202 12, /* 19 SONYPI_EVENT_FNKEY_F8 */ 203 13, /* 20 SONYPI_EVENT_FNKEY_F9 */ 204 14, /* 21 SONYPI_EVENT_FNKEY_F10 */ 205 15, /* 22 SONYPI_EVENT_FNKEY_F11 */ 206 16, /* 23 SONYPI_EVENT_FNKEY_F12 */ 207 17, /* 24 SONYPI_EVENT_FNKEY_1 */ 208 18, /* 25 SONYPI_EVENT_FNKEY_2 */ 209 19, /* 26 SONYPI_EVENT_FNKEY_D */ 210 20, /* 27 SONYPI_EVENT_FNKEY_E */ 211 21, /* 28 SONYPI_EVENT_FNKEY_F */ 212 22, /* 29 SONYPI_EVENT_FNKEY_S */ 213 23, /* 30 SONYPI_EVENT_FNKEY_B */ 214 24, /* 31 SONYPI_EVENT_BLUETOOTH_PRESSED */ 215 25, /* 32 SONYPI_EVENT_PKEY_P1 */ 216 26, /* 33 SONYPI_EVENT_PKEY_P2 */ 217 27, /* 34 SONYPI_EVENT_PKEY_P3 */ 218 28, /* 35 SONYPI_EVENT_BACK_PRESSED */ 219 -1, /* 36 SONYPI_EVENT_LID_CLOSED */ 220 -1, /* 37 SONYPI_EVENT_LID_OPENED */ 221 29, /* 38 SONYPI_EVENT_BLUETOOTH_ON */ 222 30, /* 39 SONYPI_EVENT_BLUETOOTH_OFF */ 223 31, /* 40 SONYPI_EVENT_HELP_PRESSED */ 224 32, /* 41 SONYPI_EVENT_FNKEY_ONLY */ 225 33, /* 42 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 226 34, /* 43 SONYPI_EVENT_JOGDIAL_FAST_UP */ 227 35, /* 44 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 228 36, /* 45 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 229 37, /* 46 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 230 38, /* 47 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 231 39, /* 48 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 232 40, /* 49 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 233 41, /* 50 SONYPI_EVENT_ZOOM_PRESSED */ 234 42, /* 51 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 235 43, /* 52 SONYPI_EVENT_MEYE_FACE */ 236 44, /* 53 SONYPI_EVENT_MEYE_OPPOSITE */ 237 45, /* 54 SONYPI_EVENT_MEMORYSTICK_INSERT */ 238 46, /* 55 SONYPI_EVENT_MEMORYSTICK_EJECT */ 239 -1, /* 56 SONYPI_EVENT_ANYBUTTON_RELEASED */ 240 -1, /* 57 SONYPI_EVENT_BATTERY_INSERT */ 241 -1, /* 58 SONYPI_EVENT_BATTERY_REMOVE */ 242 -1, /* 59 SONYPI_EVENT_FNKEY_RELEASED */ 243 47, /* 60 SONYPI_EVENT_WIRELESS_ON */ 244 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */ 245 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */ 246 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 247 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */ 248 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */ 249 53, /* 66 SONYPI_EVENT_PKEY_P4 */ 250 54, /* 67 SONYPI_EVENT_PKEY_P5 */ 251 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */ 252 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ 253 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 254 -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ 255 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */ 256 59, /* 72 SONYPI_EVENT_VENDOR_PRESSED */ 257 }; 258 259 static int sony_laptop_input_keycode_map[] = { 260 KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ 261 KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ 262 KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 263 KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 264 KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ 265 KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ 266 KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ 267 KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ 268 KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ 269 KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ 270 KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ 271 KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ 272 KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ 273 KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ 274 KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ 275 KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ 276 KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ 277 KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ 278 KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ 279 KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ 280 KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ 281 KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ 282 KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ 283 KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ 284 KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ 285 KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ 286 KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ 287 KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ 288 KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ 289 KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ 290 KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ 291 KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ 292 KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ 293 KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 294 KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ 295 KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 296 KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 297 KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 298 KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 299 KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 300 KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 301 KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ 302 BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 303 KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ 304 KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ 305 KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ 306 KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ 307 KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ 308 KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ 309 KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */ 310 KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 311 KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */ 312 KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */ 313 KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */ 314 KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */ 315 KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ 316 KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ 317 KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 318 KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */ 319 KEY_VENDOR, /* 59 SONYPI_EVENT_VENDOR_PRESSED */ 320 }; 321 322 /* release buttons after a short delay if pressed */ 323 static void do_sony_laptop_release_key(unsigned long unused) 324 { 325 struct sony_laptop_keypress kp; 326 unsigned long flags; 327 328 spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags); 329 330 if (kfifo_out(&sony_laptop_input.fifo, 331 (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { 332 input_report_key(kp.dev, kp.key, 0); 333 input_sync(kp.dev); 334 } 335 336 /* If there is something in the fifo schedule next release. */ 337 if (kfifo_len(&sony_laptop_input.fifo) != 0) 338 mod_timer(&sony_laptop_input.release_key_timer, 339 jiffies + msecs_to_jiffies(10)); 340 341 spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags); 342 } 343 344 /* forward event to the input subsystem */ 345 static void sony_laptop_report_input_event(u8 event) 346 { 347 struct input_dev *jog_dev = sony_laptop_input.jog_dev; 348 struct input_dev *key_dev = sony_laptop_input.key_dev; 349 struct sony_laptop_keypress kp = { NULL }; 350 int scancode = -1; 351 352 if (event == SONYPI_EVENT_FNKEY_RELEASED || 353 event == SONYPI_EVENT_ANYBUTTON_RELEASED) { 354 /* Nothing, not all VAIOs generate this event */ 355 return; 356 } 357 358 /* report events */ 359 switch (event) { 360 /* jog_dev events */ 361 case SONYPI_EVENT_JOGDIAL_UP: 362 case SONYPI_EVENT_JOGDIAL_UP_PRESSED: 363 input_report_rel(jog_dev, REL_WHEEL, 1); 364 input_sync(jog_dev); 365 return; 366 367 case SONYPI_EVENT_JOGDIAL_DOWN: 368 case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: 369 input_report_rel(jog_dev, REL_WHEEL, -1); 370 input_sync(jog_dev); 371 return; 372 373 /* key_dev events */ 374 case SONYPI_EVENT_JOGDIAL_PRESSED: 375 kp.key = BTN_MIDDLE; 376 kp.dev = jog_dev; 377 break; 378 379 default: 380 if (event >= ARRAY_SIZE(sony_laptop_input_index)) { 381 dprintk("sony_laptop_report_input_event, event not known: %d\n", event); 382 break; 383 } 384 if ((scancode = sony_laptop_input_index[event]) != -1) { 385 kp.key = sony_laptop_input_keycode_map[scancode]; 386 if (kp.key != KEY_UNKNOWN) 387 kp.dev = key_dev; 388 } 389 break; 390 } 391 392 if (kp.dev) { 393 /* if we have a scancode we emit it so we can always 394 remap the key */ 395 if (scancode != -1) 396 input_event(kp.dev, EV_MSC, MSC_SCAN, scancode); 397 input_report_key(kp.dev, kp.key, 1); 398 input_sync(kp.dev); 399 400 /* schedule key release */ 401 kfifo_in_locked(&sony_laptop_input.fifo, 402 (unsigned char *)&kp, sizeof(kp), 403 &sony_laptop_input.fifo_lock); 404 mod_timer(&sony_laptop_input.release_key_timer, 405 jiffies + msecs_to_jiffies(10)); 406 } else 407 dprintk("unknown input event %.2x\n", event); 408 } 409 410 static int sony_laptop_setup_input(struct acpi_device *acpi_device) 411 { 412 struct input_dev *jog_dev; 413 struct input_dev *key_dev; 414 int i; 415 int error; 416 417 /* don't run again if already initialized */ 418 if (atomic_add_return(1, &sony_laptop_input.users) > 1) 419 return 0; 420 421 /* kfifo */ 422 spin_lock_init(&sony_laptop_input.fifo_lock); 423 error = kfifo_alloc(&sony_laptop_input.fifo, 424 SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 425 if (error) { 426 pr_err("kfifo_alloc failed\n"); 427 goto err_dec_users; 428 } 429 430 setup_timer(&sony_laptop_input.release_key_timer, 431 do_sony_laptop_release_key, 0); 432 433 /* input keys */ 434 key_dev = input_allocate_device(); 435 if (!key_dev) { 436 error = -ENOMEM; 437 goto err_free_kfifo; 438 } 439 440 key_dev->name = "Sony Vaio Keys"; 441 key_dev->id.bustype = BUS_ISA; 442 key_dev->id.vendor = PCI_VENDOR_ID_SONY; 443 key_dev->dev.parent = &acpi_device->dev; 444 445 /* Initialize the Input Drivers: special keys */ 446 input_set_capability(key_dev, EV_MSC, MSC_SCAN); 447 448 __set_bit(EV_KEY, key_dev->evbit); 449 key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); 450 key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); 451 key_dev->keycode = &sony_laptop_input_keycode_map; 452 for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) 453 __set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit); 454 __clear_bit(KEY_RESERVED, key_dev->keybit); 455 456 error = input_register_device(key_dev); 457 if (error) 458 goto err_free_keydev; 459 460 sony_laptop_input.key_dev = key_dev; 461 462 /* jogdial */ 463 jog_dev = input_allocate_device(); 464 if (!jog_dev) { 465 error = -ENOMEM; 466 goto err_unregister_keydev; 467 } 468 469 jog_dev->name = "Sony Vaio Jogdial"; 470 jog_dev->id.bustype = BUS_ISA; 471 jog_dev->id.vendor = PCI_VENDOR_ID_SONY; 472 jog_dev->dev.parent = &acpi_device->dev; 473 474 input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE); 475 input_set_capability(jog_dev, EV_REL, REL_WHEEL); 476 477 error = input_register_device(jog_dev); 478 if (error) 479 goto err_free_jogdev; 480 481 sony_laptop_input.jog_dev = jog_dev; 482 483 return 0; 484 485 err_free_jogdev: 486 input_free_device(jog_dev); 487 488 err_unregister_keydev: 489 input_unregister_device(key_dev); 490 /* to avoid kref underflow below at input_free_device */ 491 key_dev = NULL; 492 493 err_free_keydev: 494 input_free_device(key_dev); 495 496 err_free_kfifo: 497 kfifo_free(&sony_laptop_input.fifo); 498 499 err_dec_users: 500 atomic_dec(&sony_laptop_input.users); 501 return error; 502 } 503 504 static void sony_laptop_remove_input(void) 505 { 506 struct sony_laptop_keypress kp = { NULL }; 507 508 /* Cleanup only after the last user has gone */ 509 if (!atomic_dec_and_test(&sony_laptop_input.users)) 510 return; 511 512 del_timer_sync(&sony_laptop_input.release_key_timer); 513 514 /* 515 * Generate key-up events for remaining keys. Note that we don't 516 * need locking since nobody is adding new events to the kfifo. 517 */ 518 while (kfifo_out(&sony_laptop_input.fifo, 519 (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { 520 input_report_key(kp.dev, kp.key, 0); 521 input_sync(kp.dev); 522 } 523 524 /* destroy input devs */ 525 input_unregister_device(sony_laptop_input.key_dev); 526 sony_laptop_input.key_dev = NULL; 527 528 if (sony_laptop_input.jog_dev) { 529 input_unregister_device(sony_laptop_input.jog_dev); 530 sony_laptop_input.jog_dev = NULL; 531 } 532 533 kfifo_free(&sony_laptop_input.fifo); 534 } 535 536 /*********** Platform Device ***********/ 537 538 static atomic_t sony_pf_users = ATOMIC_INIT(0); 539 static struct platform_driver sony_pf_driver = { 540 .driver = { 541 .name = "sony-laptop", 542 .owner = THIS_MODULE, 543 } 544 }; 545 static struct platform_device *sony_pf_device; 546 547 static int sony_pf_add(void) 548 { 549 int ret = 0; 550 551 /* don't run again if already initialized */ 552 if (atomic_add_return(1, &sony_pf_users) > 1) 553 return 0; 554 555 ret = platform_driver_register(&sony_pf_driver); 556 if (ret) 557 goto out; 558 559 sony_pf_device = platform_device_alloc("sony-laptop", -1); 560 if (!sony_pf_device) { 561 ret = -ENOMEM; 562 goto out_platform_registered; 563 } 564 565 ret = platform_device_add(sony_pf_device); 566 if (ret) 567 goto out_platform_alloced; 568 569 return 0; 570 571 out_platform_alloced: 572 platform_device_put(sony_pf_device); 573 sony_pf_device = NULL; 574 out_platform_registered: 575 platform_driver_unregister(&sony_pf_driver); 576 out: 577 atomic_dec(&sony_pf_users); 578 return ret; 579 } 580 581 static void sony_pf_remove(void) 582 { 583 /* deregister only after the last user has gone */ 584 if (!atomic_dec_and_test(&sony_pf_users)) 585 return; 586 587 platform_device_unregister(sony_pf_device); 588 platform_driver_unregister(&sony_pf_driver); 589 } 590 591 /*********** SNC (SNY5001) Device ***********/ 592 593 /* the device uses 1-based values, while the backlight subsystem uses 594 0-based values */ 595 #define SONY_MAX_BRIGHTNESS 8 596 597 #define SNC_VALIDATE_IN 0 598 #define SNC_VALIDATE_OUT 1 599 600 static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *, 601 char *); 602 static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *, 603 const char *, size_t); 604 static int boolean_validate(const int, const int); 605 static int brightness_default_validate(const int, const int); 606 607 struct sony_nc_value { 608 char *name; /* name of the entry */ 609 char **acpiget; /* names of the ACPI get function */ 610 char **acpiset; /* names of the ACPI set function */ 611 int (*validate)(const int, const int); /* input/output validation */ 612 int value; /* current setting */ 613 int valid; /* Has ever been set */ 614 int debug; /* active only in debug mode ? */ 615 struct device_attribute devattr; /* sysfs attribute */ 616 }; 617 618 #define SNC_HANDLE_NAMES(_name, _values...) \ 619 static char *snc_##_name[] = { _values, NULL } 620 621 #define SNC_HANDLE(_name, _getters, _setters, _validate, _debug) \ 622 { \ 623 .name = __stringify(_name), \ 624 .acpiget = _getters, \ 625 .acpiset = _setters, \ 626 .validate = _validate, \ 627 .debug = _debug, \ 628 .devattr = __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \ 629 } 630 631 #define SNC_HANDLE_NULL { .name = NULL } 632 633 SNC_HANDLE_NAMES(fnkey_get, "GHKE"); 634 635 SNC_HANDLE_NAMES(brightness_def_get, "GPBR"); 636 SNC_HANDLE_NAMES(brightness_def_set, "SPBR"); 637 638 SNC_HANDLE_NAMES(cdpower_get, "GCDP"); 639 SNC_HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); 640 641 SNC_HANDLE_NAMES(audiopower_get, "GAZP"); 642 SNC_HANDLE_NAMES(audiopower_set, "AZPW"); 643 644 SNC_HANDLE_NAMES(lanpower_get, "GLNP"); 645 SNC_HANDLE_NAMES(lanpower_set, "LNPW"); 646 647 SNC_HANDLE_NAMES(lidstate_get, "GLID"); 648 649 SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); 650 SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); 651 652 SNC_HANDLE_NAMES(gainbass_get, "GMGB"); 653 SNC_HANDLE_NAMES(gainbass_set, "CMGB"); 654 655 SNC_HANDLE_NAMES(PID_get, "GPID"); 656 657 SNC_HANDLE_NAMES(CTR_get, "GCTR"); 658 SNC_HANDLE_NAMES(CTR_set, "SCTR"); 659 660 SNC_HANDLE_NAMES(PCR_get, "GPCR"); 661 SNC_HANDLE_NAMES(PCR_set, "SPCR"); 662 663 SNC_HANDLE_NAMES(CMI_get, "GCMI"); 664 SNC_HANDLE_NAMES(CMI_set, "SCMI"); 665 666 static struct sony_nc_value sony_nc_values[] = { 667 SNC_HANDLE(brightness_default, snc_brightness_def_get, 668 snc_brightness_def_set, brightness_default_validate, 0), 669 SNC_HANDLE(fnkey, snc_fnkey_get, NULL, NULL, 0), 670 SNC_HANDLE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0), 671 SNC_HANDLE(audiopower, snc_audiopower_get, snc_audiopower_set, 672 boolean_validate, 0), 673 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, 674 boolean_validate, 1), 675 SNC_HANDLE(lidstate, snc_lidstate_get, NULL, 676 boolean_validate, 0), 677 SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, 678 boolean_validate, 0), 679 SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, 680 boolean_validate, 0), 681 /* unknown methods */ 682 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), 683 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), 684 SNC_HANDLE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1), 685 SNC_HANDLE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1), 686 SNC_HANDLE_NULL 687 }; 688 689 static acpi_handle sony_nc_acpi_handle; 690 static struct acpi_device *sony_nc_acpi_device = NULL; 691 692 /* 693 * acpi_evaluate_object wrappers 694 */ 695 static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) 696 { 697 struct acpi_buffer output; 698 union acpi_object out_obj; 699 acpi_status status; 700 701 output.length = sizeof(out_obj); 702 output.pointer = &out_obj; 703 704 status = acpi_evaluate_object(handle, name, NULL, &output); 705 if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) { 706 *result = out_obj.integer.value; 707 return 0; 708 } 709 710 pr_warn("acpi_callreadfunc failed\n"); 711 712 return -1; 713 } 714 715 static int acpi_callsetfunc(acpi_handle handle, char *name, int value, 716 int *result) 717 { 718 struct acpi_object_list params; 719 union acpi_object in_obj; 720 struct acpi_buffer output; 721 union acpi_object out_obj; 722 acpi_status status; 723 724 params.count = 1; 725 params.pointer = &in_obj; 726 in_obj.type = ACPI_TYPE_INTEGER; 727 in_obj.integer.value = value; 728 729 output.length = sizeof(out_obj); 730 output.pointer = &out_obj; 731 732 status = acpi_evaluate_object(handle, name, ¶ms, &output); 733 if (status == AE_OK) { 734 if (result != NULL) { 735 if (out_obj.type != ACPI_TYPE_INTEGER) { 736 pr_warn("acpi_evaluate_object bad return type\n"); 737 return -1; 738 } 739 *result = out_obj.integer.value; 740 } 741 return 0; 742 } 743 744 pr_warn("acpi_evaluate_object failed\n"); 745 746 return -1; 747 } 748 749 struct sony_nc_handles { 750 u16 cap[0x10]; 751 struct device_attribute devattr; 752 }; 753 754 static struct sony_nc_handles *handles; 755 756 static ssize_t sony_nc_handles_show(struct device *dev, 757 struct device_attribute *attr, char *buffer) 758 { 759 ssize_t len = 0; 760 int i; 761 762 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 763 len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ", 764 handles->cap[i]); 765 } 766 len += snprintf(buffer + len, PAGE_SIZE - len, "\n"); 767 768 return len; 769 } 770 771 static int sony_nc_handles_setup(struct platform_device *pd) 772 { 773 int i; 774 int result; 775 776 handles = kzalloc(sizeof(*handles), GFP_KERNEL); 777 if (!handles) 778 return -ENOMEM; 779 780 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 781 if (!acpi_callsetfunc(sony_nc_acpi_handle, 782 "SN00", i + 0x20, &result)) { 783 dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n", 784 result, i); 785 handles->cap[i] = result; 786 } 787 } 788 789 if (debug) { 790 sysfs_attr_init(&handles->devattr.attr); 791 handles->devattr.attr.name = "handles"; 792 handles->devattr.attr.mode = S_IRUGO; 793 handles->devattr.show = sony_nc_handles_show; 794 795 /* allow reading capabilities via sysfs */ 796 if (device_create_file(&pd->dev, &handles->devattr)) { 797 kfree(handles); 798 handles = NULL; 799 return -1; 800 } 801 } 802 803 return 0; 804 } 805 806 static int sony_nc_handles_cleanup(struct platform_device *pd) 807 { 808 if (handles) { 809 if (debug) 810 device_remove_file(&pd->dev, &handles->devattr); 811 kfree(handles); 812 handles = NULL; 813 } 814 return 0; 815 } 816 817 static int sony_find_snc_handle(int handle) 818 { 819 int i; 820 821 /* not initialized yet, return early */ 822 if (!handles) 823 return -1; 824 825 for (i = 0; i < 0x10; i++) { 826 if (handles->cap[i] == handle) { 827 dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", 828 handle, i); 829 return i; 830 } 831 } 832 dprintk("handle 0x%.4x not found\n", handle); 833 return -1; 834 } 835 836 static int sony_call_snc_handle(int handle, int argument, int *result) 837 { 838 int ret = 0; 839 int offset = sony_find_snc_handle(handle); 840 841 if (offset < 0) 842 return -1; 843 844 ret = acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument, 845 result); 846 dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", offset | argument, 847 *result); 848 return ret; 849 } 850 851 /* 852 * sony_nc_values input/output validate functions 853 */ 854 855 /* brightness_default_validate: 856 * 857 * manipulate input output values to keep consistency with the 858 * backlight framework for which brightness values are 0-based. 859 */ 860 static int brightness_default_validate(const int direction, const int value) 861 { 862 switch (direction) { 863 case SNC_VALIDATE_OUT: 864 return value - 1; 865 case SNC_VALIDATE_IN: 866 if (value >= 0 && value < SONY_MAX_BRIGHTNESS) 867 return value + 1; 868 } 869 return -EINVAL; 870 } 871 872 /* boolean_validate: 873 * 874 * on input validate boolean values 0/1, on output just pass the 875 * received value. 876 */ 877 static int boolean_validate(const int direction, const int value) 878 { 879 if (direction == SNC_VALIDATE_IN) { 880 if (value != 0 && value != 1) 881 return -EINVAL; 882 } 883 return value; 884 } 885 886 /* 887 * Sysfs show/store common to all sony_nc_values 888 */ 889 static ssize_t sony_nc_sysfs_show(struct device *dev, struct device_attribute *attr, 890 char *buffer) 891 { 892 int value; 893 struct sony_nc_value *item = 894 container_of(attr, struct sony_nc_value, devattr); 895 896 if (!*item->acpiget) 897 return -EIO; 898 899 if (acpi_callgetfunc(sony_nc_acpi_handle, *item->acpiget, &value) < 0) 900 return -EIO; 901 902 if (item->validate) 903 value = item->validate(SNC_VALIDATE_OUT, value); 904 905 return snprintf(buffer, PAGE_SIZE, "%d\n", value); 906 } 907 908 static ssize_t sony_nc_sysfs_store(struct device *dev, 909 struct device_attribute *attr, 910 const char *buffer, size_t count) 911 { 912 int value; 913 struct sony_nc_value *item = 914 container_of(attr, struct sony_nc_value, devattr); 915 916 if (!item->acpiset) 917 return -EIO; 918 919 if (count > 31) 920 return -EINVAL; 921 922 value = simple_strtoul(buffer, NULL, 10); 923 924 if (item->validate) 925 value = item->validate(SNC_VALIDATE_IN, value); 926 927 if (value < 0) 928 return value; 929 930 if (acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, value, NULL) < 0) 931 return -EIO; 932 item->value = value; 933 item->valid = 1; 934 return count; 935 } 936 937 938 /* 939 * Backlight device 940 */ 941 struct sony_backlight_props { 942 struct backlight_device *dev; 943 int handle; 944 u8 offset; 945 u8 maxlvl; 946 }; 947 struct sony_backlight_props sony_bl_props; 948 949 static int sony_backlight_update_status(struct backlight_device *bd) 950 { 951 return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", 952 bd->props.brightness + 1, NULL); 953 } 954 955 static int sony_backlight_get_brightness(struct backlight_device *bd) 956 { 957 int value; 958 959 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value)) 960 return 0; 961 /* brightness levels are 1-based, while backlight ones are 0-based */ 962 return value - 1; 963 } 964 965 static int sony_nc_get_brightness_ng(struct backlight_device *bd) 966 { 967 int result; 968 struct sony_backlight_props *sdev = 969 (struct sony_backlight_props *)bl_get_data(bd); 970 971 sony_call_snc_handle(sdev->handle, 0x0200, &result); 972 973 return (result & 0xff) - sdev->offset; 974 } 975 976 static int sony_nc_update_status_ng(struct backlight_device *bd) 977 { 978 int value, result; 979 struct sony_backlight_props *sdev = 980 (struct sony_backlight_props *)bl_get_data(bd); 981 982 value = bd->props.brightness + sdev->offset; 983 if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) 984 return -EIO; 985 986 return value; 987 } 988 989 static const struct backlight_ops sony_backlight_ops = { 990 .options = BL_CORE_SUSPENDRESUME, 991 .update_status = sony_backlight_update_status, 992 .get_brightness = sony_backlight_get_brightness, 993 }; 994 static const struct backlight_ops sony_backlight_ng_ops = { 995 .options = BL_CORE_SUSPENDRESUME, 996 .update_status = sony_nc_update_status_ng, 997 .get_brightness = sony_nc_get_brightness_ng, 998 }; 999 1000 /* 1001 * New SNC-only Vaios event mapping to driver known keys 1002 */ 1003 struct sony_nc_event { 1004 u8 data; 1005 u8 event; 1006 }; 1007 1008 static struct sony_nc_event sony_100_events[] = { 1009 { 0x90, SONYPI_EVENT_PKEY_P1 }, 1010 { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1011 { 0x91, SONYPI_EVENT_PKEY_P2 }, 1012 { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1013 { 0x81, SONYPI_EVENT_FNKEY_F1 }, 1014 { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, 1015 { 0x82, SONYPI_EVENT_FNKEY_F2 }, 1016 { 0x02, SONYPI_EVENT_FNKEY_RELEASED }, 1017 { 0x83, SONYPI_EVENT_FNKEY_F3 }, 1018 { 0x03, SONYPI_EVENT_FNKEY_RELEASED }, 1019 { 0x84, SONYPI_EVENT_FNKEY_F4 }, 1020 { 0x04, SONYPI_EVENT_FNKEY_RELEASED }, 1021 { 0x85, SONYPI_EVENT_FNKEY_F5 }, 1022 { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, 1023 { 0x86, SONYPI_EVENT_FNKEY_F6 }, 1024 { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, 1025 { 0x87, SONYPI_EVENT_FNKEY_F7 }, 1026 { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, 1027 { 0x89, SONYPI_EVENT_FNKEY_F9 }, 1028 { 0x09, SONYPI_EVENT_FNKEY_RELEASED }, 1029 { 0x8A, SONYPI_EVENT_FNKEY_F10 }, 1030 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, 1031 { 0x8C, SONYPI_EVENT_FNKEY_F12 }, 1032 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, 1033 { 0x9d, SONYPI_EVENT_ZOOM_PRESSED }, 1034 { 0x1d, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1035 { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, 1036 { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1037 { 0xa1, SONYPI_EVENT_MEDIA_PRESSED }, 1038 { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1039 { 0xa4, SONYPI_EVENT_CD_EJECT_PRESSED }, 1040 { 0x24, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1041 { 0xa5, SONYPI_EVENT_VENDOR_PRESSED }, 1042 { 0x25, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1043 { 0xa6, SONYPI_EVENT_HELP_PRESSED }, 1044 { 0x26, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1045 { 0, 0 }, 1046 }; 1047 1048 static struct sony_nc_event sony_127_events[] = { 1049 { 0x81, SONYPI_EVENT_MODEKEY_PRESSED }, 1050 { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1051 { 0x82, SONYPI_EVENT_PKEY_P1 }, 1052 { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1053 { 0x83, SONYPI_EVENT_PKEY_P2 }, 1054 { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1055 { 0x84, SONYPI_EVENT_PKEY_P3 }, 1056 { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1057 { 0x85, SONYPI_EVENT_PKEY_P4 }, 1058 { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1059 { 0x86, SONYPI_EVENT_PKEY_P5 }, 1060 { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1061 { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED }, 1062 { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1063 { 0, 0 }, 1064 }; 1065 1066 /* 1067 * ACPI callbacks 1068 */ 1069 static void sony_nc_notify(struct acpi_device *device, u32 event) 1070 { 1071 u32 ev = event; 1072 1073 if (ev >= 0x90) { 1074 /* New-style event */ 1075 int result; 1076 int key_handle = 0; 1077 ev -= 0x90; 1078 1079 if (sony_find_snc_handle(0x100) == ev) 1080 key_handle = 0x100; 1081 if (sony_find_snc_handle(0x127) == ev) 1082 key_handle = 0x127; 1083 1084 if (key_handle) { 1085 struct sony_nc_event *key_event; 1086 1087 if (sony_call_snc_handle(key_handle, 0x200, &result)) { 1088 dprintk("sony_nc_notify, unable to decode" 1089 " event 0x%.2x 0x%.2x\n", key_handle, 1090 ev); 1091 /* restore the original event */ 1092 ev = event; 1093 } else { 1094 ev = result & 0xFF; 1095 1096 if (key_handle == 0x100) 1097 key_event = sony_100_events; 1098 else 1099 key_event = sony_127_events; 1100 1101 for (; key_event->data; key_event++) { 1102 if (key_event->data == ev) { 1103 ev = key_event->event; 1104 break; 1105 } 1106 } 1107 1108 if (!key_event->data) 1109 pr_info("Unknown event: 0x%x 0x%x\n", 1110 key_handle, ev); 1111 else 1112 sony_laptop_report_input_event(ev); 1113 } 1114 } else if (sony_find_snc_handle(sony_rfkill_handle) == ev) { 1115 sony_nc_rfkill_update(); 1116 return; 1117 } 1118 } else 1119 sony_laptop_report_input_event(ev); 1120 1121 dprintk("sony_nc_notify, event: 0x%.2x\n", ev); 1122 acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); 1123 } 1124 1125 static acpi_status sony_walk_callback(acpi_handle handle, u32 level, 1126 void *context, void **return_value) 1127 { 1128 struct acpi_device_info *info; 1129 1130 if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { 1131 pr_warn("method: name: %4.4s, args %X\n", 1132 (char *)&info->name, info->param_count); 1133 1134 kfree(info); 1135 } 1136 1137 return AE_OK; 1138 } 1139 1140 /* 1141 * ACPI device 1142 */ 1143 static int sony_nc_function_setup(struct acpi_device *device) 1144 { 1145 int result; 1146 1147 /* Enable all events */ 1148 acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result); 1149 1150 /* Setup hotkeys */ 1151 sony_call_snc_handle(0x0100, 0, &result); 1152 sony_call_snc_handle(0x0101, 0, &result); 1153 sony_call_snc_handle(0x0102, 0x100, &result); 1154 sony_call_snc_handle(0x0127, 0, &result); 1155 1156 return 0; 1157 } 1158 1159 static int sony_nc_resume(struct acpi_device *device) 1160 { 1161 struct sony_nc_value *item; 1162 acpi_handle handle; 1163 1164 for (item = sony_nc_values; item->name; item++) { 1165 int ret; 1166 1167 if (!item->valid) 1168 continue; 1169 ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, 1170 item->value, NULL); 1171 if (ret < 0) { 1172 pr_err("%s: %d\n", __func__, ret); 1173 break; 1174 } 1175 } 1176 1177 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", 1178 &handle))) { 1179 if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) 1180 dprintk("ECON Method failed\n"); 1181 } 1182 1183 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", 1184 &handle))) { 1185 dprintk("Doing SNC setup\n"); 1186 sony_nc_function_setup(device); 1187 } 1188 1189 /* re-read rfkill state */ 1190 sony_nc_rfkill_update(); 1191 1192 /* restore kbd backlight states */ 1193 sony_nc_kbd_backlight_resume(); 1194 1195 return 0; 1196 } 1197 1198 static void sony_nc_rfkill_cleanup(void) 1199 { 1200 int i; 1201 1202 for (i = 0; i < N_SONY_RFKILL; i++) { 1203 if (sony_rfkill_devices[i]) { 1204 rfkill_unregister(sony_rfkill_devices[i]); 1205 rfkill_destroy(sony_rfkill_devices[i]); 1206 } 1207 } 1208 } 1209 1210 static int sony_nc_rfkill_set(void *data, bool blocked) 1211 { 1212 int result; 1213 int argument = sony_rfkill_address[(long) data] + 0x100; 1214 1215 if (!blocked) 1216 argument |= 0xff0000; 1217 1218 return sony_call_snc_handle(sony_rfkill_handle, argument, &result); 1219 } 1220 1221 static const struct rfkill_ops sony_rfkill_ops = { 1222 .set_block = sony_nc_rfkill_set, 1223 }; 1224 1225 static int sony_nc_setup_rfkill(struct acpi_device *device, 1226 enum sony_nc_rfkill nc_type) 1227 { 1228 int err = 0; 1229 struct rfkill *rfk; 1230 enum rfkill_type type; 1231 const char *name; 1232 int result; 1233 bool hwblock; 1234 1235 switch (nc_type) { 1236 case SONY_WIFI: 1237 type = RFKILL_TYPE_WLAN; 1238 name = "sony-wifi"; 1239 break; 1240 case SONY_BLUETOOTH: 1241 type = RFKILL_TYPE_BLUETOOTH; 1242 name = "sony-bluetooth"; 1243 break; 1244 case SONY_WWAN: 1245 type = RFKILL_TYPE_WWAN; 1246 name = "sony-wwan"; 1247 break; 1248 case SONY_WIMAX: 1249 type = RFKILL_TYPE_WIMAX; 1250 name = "sony-wimax"; 1251 break; 1252 default: 1253 return -EINVAL; 1254 } 1255 1256 rfk = rfkill_alloc(name, &device->dev, type, 1257 &sony_rfkill_ops, (void *)nc_type); 1258 if (!rfk) 1259 return -ENOMEM; 1260 1261 sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); 1262 hwblock = !(result & 0x1); 1263 rfkill_set_hw_state(rfk, hwblock); 1264 1265 err = rfkill_register(rfk); 1266 if (err) { 1267 rfkill_destroy(rfk); 1268 return err; 1269 } 1270 sony_rfkill_devices[nc_type] = rfk; 1271 return err; 1272 } 1273 1274 static void sony_nc_rfkill_update(void) 1275 { 1276 enum sony_nc_rfkill i; 1277 int result; 1278 bool hwblock; 1279 1280 sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); 1281 hwblock = !(result & 0x1); 1282 1283 for (i = 0; i < N_SONY_RFKILL; i++) { 1284 int argument = sony_rfkill_address[i]; 1285 1286 if (!sony_rfkill_devices[i]) 1287 continue; 1288 1289 if (hwblock) { 1290 if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) { 1291 /* we already know we're blocked */ 1292 } 1293 continue; 1294 } 1295 1296 sony_call_snc_handle(sony_rfkill_handle, argument, &result); 1297 rfkill_set_states(sony_rfkill_devices[i], 1298 !(result & 0xf), false); 1299 } 1300 } 1301 1302 static void sony_nc_rfkill_setup(struct acpi_device *device) 1303 { 1304 int offset; 1305 u8 dev_code, i; 1306 acpi_status status; 1307 struct acpi_object_list params; 1308 union acpi_object in_obj; 1309 union acpi_object *device_enum; 1310 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1311 1312 offset = sony_find_snc_handle(0x124); 1313 if (offset == -1) { 1314 offset = sony_find_snc_handle(0x135); 1315 if (offset == -1) 1316 return; 1317 else 1318 sony_rfkill_handle = 0x135; 1319 } else 1320 sony_rfkill_handle = 0x124; 1321 dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle); 1322 1323 /* need to read the whole buffer returned by the acpi call to SN06 1324 * here otherwise we may miss some features 1325 */ 1326 params.count = 1; 1327 params.pointer = &in_obj; 1328 in_obj.type = ACPI_TYPE_INTEGER; 1329 in_obj.integer.value = offset; 1330 status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, 1331 &buffer); 1332 if (ACPI_FAILURE(status)) { 1333 dprintk("Radio device enumeration failed\n"); 1334 return; 1335 } 1336 1337 device_enum = (union acpi_object *) buffer.pointer; 1338 if (!device_enum) { 1339 pr_err("No SN06 return object\n"); 1340 goto out_no_enum; 1341 } 1342 if (device_enum->type != ACPI_TYPE_BUFFER) { 1343 pr_err("Invalid SN06 return object 0x%.2x\n", 1344 device_enum->type); 1345 goto out_no_enum; 1346 } 1347 1348 /* the buffer is filled with magic numbers describing the devices 1349 * available, 0xff terminates the enumeration 1350 */ 1351 for (i = 0; i < device_enum->buffer.length; i++) { 1352 1353 dev_code = *(device_enum->buffer.pointer + i); 1354 if (dev_code == 0xff) 1355 break; 1356 1357 dprintk("Radio devices, looking at 0x%.2x\n", dev_code); 1358 1359 if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI]) 1360 sony_nc_setup_rfkill(device, SONY_WIFI); 1361 1362 if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH]) 1363 sony_nc_setup_rfkill(device, SONY_BLUETOOTH); 1364 1365 if ((0xf0 & dev_code) == 0x20 && 1366 !sony_rfkill_devices[SONY_WWAN]) 1367 sony_nc_setup_rfkill(device, SONY_WWAN); 1368 1369 if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX]) 1370 sony_nc_setup_rfkill(device, SONY_WIMAX); 1371 } 1372 1373 out_no_enum: 1374 kfree(buffer.pointer); 1375 return; 1376 } 1377 1378 /* Keyboard backlight feature */ 1379 #define KBDBL_HANDLER 0x137 1380 #define KBDBL_PRESENT 0xB00 1381 #define SET_MODE 0xC00 1382 #define SET_STATE 0xD00 1383 #define SET_TIMEOUT 0xE00 1384 1385 struct kbd_backlight { 1386 int mode; 1387 int timeout; 1388 struct device_attribute mode_attr; 1389 struct device_attribute timeout_attr; 1390 }; 1391 1392 static struct kbd_backlight *kbdbl_handle; 1393 1394 static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value) 1395 { 1396 int result; 1397 1398 if (value > 1) 1399 return -EINVAL; 1400 1401 if (sony_call_snc_handle(KBDBL_HANDLER, 1402 (value << 0x10) | SET_MODE, &result)) 1403 return -EIO; 1404 1405 /* Try to turn the light on/off immediately */ 1406 sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE, 1407 &result); 1408 1409 kbdbl_handle->mode = value; 1410 1411 return 0; 1412 } 1413 1414 static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev, 1415 struct device_attribute *attr, 1416 const char *buffer, size_t count) 1417 { 1418 int ret = 0; 1419 unsigned long value; 1420 1421 if (count > 31) 1422 return -EINVAL; 1423 1424 if (strict_strtoul(buffer, 10, &value)) 1425 return -EINVAL; 1426 1427 ret = __sony_nc_kbd_backlight_mode_set(value); 1428 if (ret < 0) 1429 return ret; 1430 1431 return count; 1432 } 1433 1434 static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev, 1435 struct device_attribute *attr, char *buffer) 1436 { 1437 ssize_t count = 0; 1438 count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode); 1439 return count; 1440 } 1441 1442 static int __sony_nc_kbd_backlight_timeout_set(u8 value) 1443 { 1444 int result; 1445 1446 if (value > 3) 1447 return -EINVAL; 1448 1449 if (sony_call_snc_handle(KBDBL_HANDLER, 1450 (value << 0x10) | SET_TIMEOUT, &result)) 1451 return -EIO; 1452 1453 kbdbl_handle->timeout = value; 1454 1455 return 0; 1456 } 1457 1458 static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev, 1459 struct device_attribute *attr, 1460 const char *buffer, size_t count) 1461 { 1462 int ret = 0; 1463 unsigned long value; 1464 1465 if (count > 31) 1466 return -EINVAL; 1467 1468 if (strict_strtoul(buffer, 10, &value)) 1469 return -EINVAL; 1470 1471 ret = __sony_nc_kbd_backlight_timeout_set(value); 1472 if (ret < 0) 1473 return ret; 1474 1475 return count; 1476 } 1477 1478 static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev, 1479 struct device_attribute *attr, char *buffer) 1480 { 1481 ssize_t count = 0; 1482 count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout); 1483 return count; 1484 } 1485 1486 static int sony_nc_kbd_backlight_setup(struct platform_device *pd) 1487 { 1488 int result; 1489 1490 if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result)) 1491 return 0; 1492 if (!(result & 0x02)) 1493 return 0; 1494 1495 kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL); 1496 if (!kbdbl_handle) 1497 return -ENOMEM; 1498 1499 sysfs_attr_init(&kbdbl_handle->mode_attr.attr); 1500 kbdbl_handle->mode_attr.attr.name = "kbd_backlight"; 1501 kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR; 1502 kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show; 1503 kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store; 1504 1505 sysfs_attr_init(&kbdbl_handle->timeout_attr.attr); 1506 kbdbl_handle->timeout_attr.attr.name = "kbd_backlight_timeout"; 1507 kbdbl_handle->timeout_attr.attr.mode = S_IRUGO | S_IWUSR; 1508 kbdbl_handle->timeout_attr.show = sony_nc_kbd_backlight_timeout_show; 1509 kbdbl_handle->timeout_attr.store = sony_nc_kbd_backlight_timeout_store; 1510 1511 if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr)) 1512 goto outkzalloc; 1513 1514 if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr)) 1515 goto outmode; 1516 1517 __sony_nc_kbd_backlight_mode_set(kbd_backlight); 1518 __sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout); 1519 1520 return 0; 1521 1522 outmode: 1523 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); 1524 outkzalloc: 1525 kfree(kbdbl_handle); 1526 kbdbl_handle = NULL; 1527 return -1; 1528 } 1529 1530 static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) 1531 { 1532 if (kbdbl_handle) { 1533 int result; 1534 1535 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); 1536 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); 1537 1538 /* restore the default hw behaviour */ 1539 sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result); 1540 sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result); 1541 1542 kfree(kbdbl_handle); 1543 } 1544 return 0; 1545 } 1546 1547 static void sony_nc_kbd_backlight_resume(void) 1548 { 1549 int ignore = 0; 1550 1551 if (!kbdbl_handle) 1552 return; 1553 1554 if (kbdbl_handle->mode == 0) 1555 sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore); 1556 1557 if (kbdbl_handle->timeout != 0) 1558 sony_call_snc_handle(KBDBL_HANDLER, 1559 (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT, 1560 &ignore); 1561 } 1562 1563 static void sony_nc_backlight_ng_read_limits(int handle, 1564 struct sony_backlight_props *props) 1565 { 1566 int offset; 1567 acpi_status status; 1568 u8 brlvl, i; 1569 u8 min = 0xff, max = 0x00; 1570 struct acpi_object_list params; 1571 union acpi_object in_obj; 1572 union acpi_object *lvl_enum; 1573 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1574 1575 props->handle = handle; 1576 props->offset = 0; 1577 props->maxlvl = 0xff; 1578 1579 offset = sony_find_snc_handle(handle); 1580 if (offset < 0) 1581 return; 1582 1583 /* try to read the boundaries from ACPI tables, if we fail the above 1584 * defaults should be reasonable 1585 */ 1586 params.count = 1; 1587 params.pointer = &in_obj; 1588 in_obj.type = ACPI_TYPE_INTEGER; 1589 in_obj.integer.value = offset; 1590 status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, 1591 &buffer); 1592 if (ACPI_FAILURE(status)) 1593 return; 1594 1595 lvl_enum = (union acpi_object *) buffer.pointer; 1596 if (!lvl_enum) { 1597 pr_err("No SN06 return object."); 1598 return; 1599 } 1600 if (lvl_enum->type != ACPI_TYPE_BUFFER) { 1601 pr_err("Invalid SN06 return object 0x%.2x\n", 1602 lvl_enum->type); 1603 goto out_invalid; 1604 } 1605 1606 /* the buffer lists brightness levels available, brightness levels are 1607 * from 0 to 8 in the array, other values are used by ALS control. 1608 */ 1609 for (i = 0; i < 9 && i < lvl_enum->buffer.length; i++) { 1610 1611 brlvl = *(lvl_enum->buffer.pointer + i); 1612 dprintk("Brightness level: %d\n", brlvl); 1613 1614 if (!brlvl) 1615 break; 1616 1617 if (brlvl > max) 1618 max = brlvl; 1619 if (brlvl < min) 1620 min = brlvl; 1621 } 1622 props->offset = min; 1623 props->maxlvl = max; 1624 dprintk("Brightness levels: min=%d max=%d\n", props->offset, 1625 props->maxlvl); 1626 1627 out_invalid: 1628 kfree(buffer.pointer); 1629 return; 1630 } 1631 1632 static void sony_nc_backlight_setup(void) 1633 { 1634 acpi_handle unused; 1635 int max_brightness = 0; 1636 const struct backlight_ops *ops = NULL; 1637 struct backlight_properties props; 1638 1639 if (sony_find_snc_handle(0x12f) != -1) { 1640 ops = &sony_backlight_ng_ops; 1641 sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); 1642 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 1643 1644 } else if (sony_find_snc_handle(0x137) != -1) { 1645 ops = &sony_backlight_ng_ops; 1646 sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); 1647 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 1648 1649 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", 1650 &unused))) { 1651 ops = &sony_backlight_ops; 1652 max_brightness = SONY_MAX_BRIGHTNESS - 1; 1653 1654 } else 1655 return; 1656 1657 memset(&props, 0, sizeof(struct backlight_properties)); 1658 props.type = BACKLIGHT_PLATFORM; 1659 props.max_brightness = max_brightness; 1660 sony_bl_props.dev = backlight_device_register("sony", NULL, 1661 &sony_bl_props, 1662 ops, &props); 1663 1664 if (IS_ERR(sony_bl_props.dev)) { 1665 pr_warn("unable to register backlight device\n"); 1666 sony_bl_props.dev = NULL; 1667 } else 1668 sony_bl_props.dev->props.brightness = 1669 ops->get_brightness(sony_bl_props.dev); 1670 } 1671 1672 static void sony_nc_backlight_cleanup(void) 1673 { 1674 if (sony_bl_props.dev) 1675 backlight_device_unregister(sony_bl_props.dev); 1676 } 1677 1678 static int sony_nc_add(struct acpi_device *device) 1679 { 1680 acpi_status status; 1681 int result = 0; 1682 acpi_handle handle; 1683 struct sony_nc_value *item; 1684 1685 pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); 1686 1687 sony_nc_acpi_device = device; 1688 strcpy(acpi_device_class(device), "sony/hotkey"); 1689 1690 sony_nc_acpi_handle = device->handle; 1691 1692 /* read device status */ 1693 result = acpi_bus_get_status(device); 1694 /* bail IFF the above call was successful and the device is not present */ 1695 if (!result && !device->status.present) { 1696 dprintk("Device not present\n"); 1697 result = -ENODEV; 1698 goto outwalk; 1699 } 1700 1701 result = sony_pf_add(); 1702 if (result) 1703 goto outpresent; 1704 1705 if (debug) { 1706 status = acpi_walk_namespace(ACPI_TYPE_METHOD, 1707 sony_nc_acpi_handle, 1, sony_walk_callback, 1708 NULL, NULL, NULL); 1709 if (ACPI_FAILURE(status)) { 1710 pr_warn("unable to walk acpi resources\n"); 1711 result = -ENODEV; 1712 goto outpresent; 1713 } 1714 } 1715 1716 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", 1717 &handle))) { 1718 if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) 1719 dprintk("ECON Method failed\n"); 1720 } 1721 1722 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", 1723 &handle))) { 1724 dprintk("Doing SNC setup\n"); 1725 result = sony_nc_handles_setup(sony_pf_device); 1726 if (result) 1727 goto outpresent; 1728 result = sony_nc_kbd_backlight_setup(sony_pf_device); 1729 if (result) 1730 goto outsnc; 1731 sony_nc_function_setup(device); 1732 sony_nc_rfkill_setup(device); 1733 } 1734 1735 /* setup input devices and helper fifo */ 1736 result = sony_laptop_setup_input(device); 1737 if (result) { 1738 pr_err("Unable to create input devices\n"); 1739 goto outkbdbacklight; 1740 } 1741 1742 if (acpi_video_backlight_support()) { 1743 pr_info("brightness ignored, must be controlled by ACPI video driver\n"); 1744 } else { 1745 sony_nc_backlight_setup(); 1746 } 1747 1748 /* create sony_pf sysfs attributes related to the SNC device */ 1749 for (item = sony_nc_values; item->name; ++item) { 1750 1751 if (!debug && item->debug) 1752 continue; 1753 1754 /* find the available acpiget as described in the DSDT */ 1755 for (; item->acpiget && *item->acpiget; ++item->acpiget) { 1756 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, 1757 *item->acpiget, 1758 &handle))) { 1759 dprintk("Found %s getter: %s\n", 1760 item->name, *item->acpiget); 1761 item->devattr.attr.mode |= S_IRUGO; 1762 break; 1763 } 1764 } 1765 1766 /* find the available acpiset as described in the DSDT */ 1767 for (; item->acpiset && *item->acpiset; ++item->acpiset) { 1768 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, 1769 *item->acpiset, 1770 &handle))) { 1771 dprintk("Found %s setter: %s\n", 1772 item->name, *item->acpiset); 1773 item->devattr.attr.mode |= S_IWUSR; 1774 break; 1775 } 1776 } 1777 1778 if (item->devattr.attr.mode != 0) { 1779 result = 1780 device_create_file(&sony_pf_device->dev, 1781 &item->devattr); 1782 if (result) 1783 goto out_sysfs; 1784 } 1785 } 1786 1787 return 0; 1788 1789 out_sysfs: 1790 for (item = sony_nc_values; item->name; ++item) { 1791 device_remove_file(&sony_pf_device->dev, &item->devattr); 1792 } 1793 sony_nc_backlight_cleanup(); 1794 1795 sony_laptop_remove_input(); 1796 1797 outkbdbacklight: 1798 sony_nc_kbd_backlight_cleanup(sony_pf_device); 1799 1800 outsnc: 1801 sony_nc_handles_cleanup(sony_pf_device); 1802 1803 outpresent: 1804 sony_pf_remove(); 1805 1806 outwalk: 1807 sony_nc_rfkill_cleanup(); 1808 return result; 1809 } 1810 1811 static int sony_nc_remove(struct acpi_device *device, int type) 1812 { 1813 struct sony_nc_value *item; 1814 1815 sony_nc_backlight_cleanup(); 1816 1817 sony_nc_acpi_device = NULL; 1818 1819 for (item = sony_nc_values; item->name; ++item) { 1820 device_remove_file(&sony_pf_device->dev, &item->devattr); 1821 } 1822 1823 sony_nc_kbd_backlight_cleanup(sony_pf_device); 1824 sony_nc_handles_cleanup(sony_pf_device); 1825 sony_pf_remove(); 1826 sony_laptop_remove_input(); 1827 sony_nc_rfkill_cleanup(); 1828 dprintk(SONY_NC_DRIVER_NAME " removed.\n"); 1829 1830 return 0; 1831 } 1832 1833 static const struct acpi_device_id sony_device_ids[] = { 1834 {SONY_NC_HID, 0}, 1835 {SONY_PIC_HID, 0}, 1836 {"", 0}, 1837 }; 1838 MODULE_DEVICE_TABLE(acpi, sony_device_ids); 1839 1840 static const struct acpi_device_id sony_nc_device_ids[] = { 1841 {SONY_NC_HID, 0}, 1842 {"", 0}, 1843 }; 1844 1845 static struct acpi_driver sony_nc_driver = { 1846 .name = SONY_NC_DRIVER_NAME, 1847 .class = SONY_NC_CLASS, 1848 .ids = sony_nc_device_ids, 1849 .owner = THIS_MODULE, 1850 .ops = { 1851 .add = sony_nc_add, 1852 .remove = sony_nc_remove, 1853 .resume = sony_nc_resume, 1854 .notify = sony_nc_notify, 1855 }, 1856 }; 1857 1858 /*********** SPIC (SNY6001) Device ***********/ 1859 1860 #define SONYPI_DEVICE_TYPE1 0x00000001 1861 #define SONYPI_DEVICE_TYPE2 0x00000002 1862 #define SONYPI_DEVICE_TYPE3 0x00000004 1863 1864 #define SONYPI_TYPE1_OFFSET 0x04 1865 #define SONYPI_TYPE2_OFFSET 0x12 1866 #define SONYPI_TYPE3_OFFSET 0x12 1867 1868 struct sony_pic_ioport { 1869 struct acpi_resource_io io1; 1870 struct acpi_resource_io io2; 1871 struct list_head list; 1872 }; 1873 1874 struct sony_pic_irq { 1875 struct acpi_resource_irq irq; 1876 struct list_head list; 1877 }; 1878 1879 struct sonypi_eventtypes { 1880 u8 data; 1881 unsigned long mask; 1882 struct sonypi_event *events; 1883 }; 1884 1885 struct sony_pic_dev { 1886 struct acpi_device *acpi_dev; 1887 struct sony_pic_irq *cur_irq; 1888 struct sony_pic_ioport *cur_ioport; 1889 struct list_head interrupts; 1890 struct list_head ioports; 1891 struct mutex lock; 1892 struct sonypi_eventtypes *event_types; 1893 int (*handle_irq)(const u8, const u8); 1894 int model; 1895 u16 evport_offset; 1896 u8 camera_power; 1897 u8 bluetooth_power; 1898 u8 wwan_power; 1899 }; 1900 1901 static struct sony_pic_dev spic_dev = { 1902 .interrupts = LIST_HEAD_INIT(spic_dev.interrupts), 1903 .ioports = LIST_HEAD_INIT(spic_dev.ioports), 1904 }; 1905 1906 static int spic_drv_registered; 1907 1908 /* Event masks */ 1909 #define SONYPI_JOGGER_MASK 0x00000001 1910 #define SONYPI_CAPTURE_MASK 0x00000002 1911 #define SONYPI_FNKEY_MASK 0x00000004 1912 #define SONYPI_BLUETOOTH_MASK 0x00000008 1913 #define SONYPI_PKEY_MASK 0x00000010 1914 #define SONYPI_BACK_MASK 0x00000020 1915 #define SONYPI_HELP_MASK 0x00000040 1916 #define SONYPI_LID_MASK 0x00000080 1917 #define SONYPI_ZOOM_MASK 0x00000100 1918 #define SONYPI_THUMBPHRASE_MASK 0x00000200 1919 #define SONYPI_MEYE_MASK 0x00000400 1920 #define SONYPI_MEMORYSTICK_MASK 0x00000800 1921 #define SONYPI_BATTERY_MASK 0x00001000 1922 #define SONYPI_WIRELESS_MASK 0x00002000 1923 1924 struct sonypi_event { 1925 u8 data; 1926 u8 event; 1927 }; 1928 1929 /* The set of possible button release events */ 1930 static struct sonypi_event sonypi_releaseev[] = { 1931 { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1932 { 0, 0 } 1933 }; 1934 1935 /* The set of possible jogger events */ 1936 static struct sonypi_event sonypi_joggerev[] = { 1937 { 0x1f, SONYPI_EVENT_JOGDIAL_UP }, 1938 { 0x01, SONYPI_EVENT_JOGDIAL_DOWN }, 1939 { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED }, 1940 { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED }, 1941 { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP }, 1942 { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN }, 1943 { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED }, 1944 { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED }, 1945 { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP }, 1946 { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN }, 1947 { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED }, 1948 { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, 1949 { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED }, 1950 { 0, 0 } 1951 }; 1952 1953 /* The set of possible capture button events */ 1954 static struct sonypi_event sonypi_captureev[] = { 1955 { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED }, 1956 { 0x07, SONYPI_EVENT_CAPTURE_PRESSED }, 1957 { 0x40, SONYPI_EVENT_CAPTURE_PRESSED }, 1958 { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, 1959 { 0, 0 } 1960 }; 1961 1962 /* The set of possible fnkeys events */ 1963 static struct sonypi_event sonypi_fnkeyev[] = { 1964 { 0x10, SONYPI_EVENT_FNKEY_ESC }, 1965 { 0x11, SONYPI_EVENT_FNKEY_F1 }, 1966 { 0x12, SONYPI_EVENT_FNKEY_F2 }, 1967 { 0x13, SONYPI_EVENT_FNKEY_F3 }, 1968 { 0x14, SONYPI_EVENT_FNKEY_F4 }, 1969 { 0x15, SONYPI_EVENT_FNKEY_F5 }, 1970 { 0x16, SONYPI_EVENT_FNKEY_F6 }, 1971 { 0x17, SONYPI_EVENT_FNKEY_F7 }, 1972 { 0x18, SONYPI_EVENT_FNKEY_F8 }, 1973 { 0x19, SONYPI_EVENT_FNKEY_F9 }, 1974 { 0x1a, SONYPI_EVENT_FNKEY_F10 }, 1975 { 0x1b, SONYPI_EVENT_FNKEY_F11 }, 1976 { 0x1c, SONYPI_EVENT_FNKEY_F12 }, 1977 { 0x1f, SONYPI_EVENT_FNKEY_RELEASED }, 1978 { 0x21, SONYPI_EVENT_FNKEY_1 }, 1979 { 0x22, SONYPI_EVENT_FNKEY_2 }, 1980 { 0x31, SONYPI_EVENT_FNKEY_D }, 1981 { 0x32, SONYPI_EVENT_FNKEY_E }, 1982 { 0x33, SONYPI_EVENT_FNKEY_F }, 1983 { 0x34, SONYPI_EVENT_FNKEY_S }, 1984 { 0x35, SONYPI_EVENT_FNKEY_B }, 1985 { 0x36, SONYPI_EVENT_FNKEY_ONLY }, 1986 { 0, 0 } 1987 }; 1988 1989 /* The set of possible program key events */ 1990 static struct sonypi_event sonypi_pkeyev[] = { 1991 { 0x01, SONYPI_EVENT_PKEY_P1 }, 1992 { 0x02, SONYPI_EVENT_PKEY_P2 }, 1993 { 0x04, SONYPI_EVENT_PKEY_P3 }, 1994 { 0x20, SONYPI_EVENT_PKEY_P1 }, 1995 { 0, 0 } 1996 }; 1997 1998 /* The set of possible bluetooth events */ 1999 static struct sonypi_event sonypi_blueev[] = { 2000 { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED }, 2001 { 0x59, SONYPI_EVENT_BLUETOOTH_ON }, 2002 { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF }, 2003 { 0, 0 } 2004 }; 2005 2006 /* The set of possible wireless events */ 2007 static struct sonypi_event sonypi_wlessev[] = { 2008 { 0x59, SONYPI_EVENT_IGNORE }, 2009 { 0x5a, SONYPI_EVENT_IGNORE }, 2010 { 0, 0 } 2011 }; 2012 2013 /* The set of possible back button events */ 2014 static struct sonypi_event sonypi_backev[] = { 2015 { 0x20, SONYPI_EVENT_BACK_PRESSED }, 2016 { 0, 0 } 2017 }; 2018 2019 /* The set of possible help button events */ 2020 static struct sonypi_event sonypi_helpev[] = { 2021 { 0x3b, SONYPI_EVENT_HELP_PRESSED }, 2022 { 0, 0 } 2023 }; 2024 2025 2026 /* The set of possible lid events */ 2027 static struct sonypi_event sonypi_lidev[] = { 2028 { 0x51, SONYPI_EVENT_LID_CLOSED }, 2029 { 0x50, SONYPI_EVENT_LID_OPENED }, 2030 { 0, 0 } 2031 }; 2032 2033 /* The set of possible zoom events */ 2034 static struct sonypi_event sonypi_zoomev[] = { 2035 { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, 2036 { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED }, 2037 { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED }, 2038 { 0x04, SONYPI_EVENT_ZOOM_PRESSED }, 2039 { 0, 0 } 2040 }; 2041 2042 /* The set of possible thumbphrase events */ 2043 static struct sonypi_event sonypi_thumbphraseev[] = { 2044 { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED }, 2045 { 0, 0 } 2046 }; 2047 2048 /* The set of possible motioneye camera events */ 2049 static struct sonypi_event sonypi_meyeev[] = { 2050 { 0x00, SONYPI_EVENT_MEYE_FACE }, 2051 { 0x01, SONYPI_EVENT_MEYE_OPPOSITE }, 2052 { 0, 0 } 2053 }; 2054 2055 /* The set of possible memorystick events */ 2056 static struct sonypi_event sonypi_memorystickev[] = { 2057 { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT }, 2058 { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT }, 2059 { 0, 0 } 2060 }; 2061 2062 /* The set of possible battery events */ 2063 static struct sonypi_event sonypi_batteryev[] = { 2064 { 0x20, SONYPI_EVENT_BATTERY_INSERT }, 2065 { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, 2066 { 0, 0 } 2067 }; 2068 2069 /* The set of possible volume events */ 2070 static struct sonypi_event sonypi_volumeev[] = { 2071 { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED }, 2072 { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED }, 2073 { 0, 0 } 2074 }; 2075 2076 /* The set of possible brightness events */ 2077 static struct sonypi_event sonypi_brightnessev[] = { 2078 { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED }, 2079 { 0, 0 } 2080 }; 2081 2082 static struct sonypi_eventtypes type1_events[] = { 2083 { 0, 0xffffffff, sonypi_releaseev }, 2084 { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, 2085 { 0x30, SONYPI_LID_MASK, sonypi_lidev }, 2086 { 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev }, 2087 { 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev }, 2088 { 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 2089 { 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 2090 { 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, 2091 { 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 2092 { 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, 2093 { 0 }, 2094 }; 2095 static struct sonypi_eventtypes type2_events[] = { 2096 { 0, 0xffffffff, sonypi_releaseev }, 2097 { 0x38, SONYPI_LID_MASK, sonypi_lidev }, 2098 { 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, 2099 { 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, 2100 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 2101 { 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 2102 { 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, 2103 { 0x11, SONYPI_BACK_MASK, sonypi_backev }, 2104 { 0x21, SONYPI_HELP_MASK, sonypi_helpev }, 2105 { 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, 2106 { 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, 2107 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 2108 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 2109 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 2110 { 0 }, 2111 }; 2112 static struct sonypi_eventtypes type3_events[] = { 2113 { 0, 0xffffffff, sonypi_releaseev }, 2114 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 2115 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, 2116 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 2117 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 2118 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 2119 { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev }, 2120 { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev }, 2121 { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev }, 2122 { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev }, 2123 { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev }, 2124 { 0 }, 2125 }; 2126 2127 /* low level spic calls */ 2128 #define ITERATIONS_LONG 10000 2129 #define ITERATIONS_SHORT 10 2130 #define wait_on_command(command, iterations) { \ 2131 unsigned int n = iterations; \ 2132 while (--n && (command)) \ 2133 udelay(1); \ 2134 if (!n) \ 2135 dprintk("command failed at %s : %s (line %d)\n", \ 2136 __FILE__, __func__, __LINE__); \ 2137 } 2138 2139 static u8 sony_pic_call1(u8 dev) 2140 { 2141 u8 v1, v2; 2142 2143 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 2144 ITERATIONS_LONG); 2145 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 2146 v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); 2147 v2 = inb_p(spic_dev.cur_ioport->io1.minimum); 2148 dprintk("sony_pic_call1(0x%.2x): 0x%.4x\n", dev, (v2 << 8) | v1); 2149 return v2; 2150 } 2151 2152 static u8 sony_pic_call2(u8 dev, u8 fn) 2153 { 2154 u8 v1; 2155 2156 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 2157 ITERATIONS_LONG); 2158 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 2159 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 2160 ITERATIONS_LONG); 2161 outb(fn, spic_dev.cur_ioport->io1.minimum); 2162 v1 = inb_p(spic_dev.cur_ioport->io1.minimum); 2163 dprintk("sony_pic_call2(0x%.2x - 0x%.2x): 0x%.4x\n", dev, fn, v1); 2164 return v1; 2165 } 2166 2167 static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) 2168 { 2169 u8 v1; 2170 2171 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 2172 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 2173 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 2174 outb(fn, spic_dev.cur_ioport->io1.minimum); 2175 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 2176 outb(v, spic_dev.cur_ioport->io1.minimum); 2177 v1 = inb_p(spic_dev.cur_ioport->io1.minimum); 2178 dprintk("sony_pic_call3(0x%.2x - 0x%.2x - 0x%.2x): 0x%.4x\n", 2179 dev, fn, v, v1); 2180 return v1; 2181 } 2182 2183 /* 2184 * minidrivers for SPIC models 2185 */ 2186 static int type3_handle_irq(const u8 data_mask, const u8 ev) 2187 { 2188 /* 2189 * 0x31 could mean we have to take some extra action and wait for 2190 * the next irq for some Type3 models, it will generate a new 2191 * irq and we can read new data from the device: 2192 * - 0x5c and 0x5f requires 0xA0 2193 * - 0x61 requires 0xB3 2194 */ 2195 if (data_mask == 0x31) { 2196 if (ev == 0x5c || ev == 0x5f) 2197 sony_pic_call1(0xA0); 2198 else if (ev == 0x61) 2199 sony_pic_call1(0xB3); 2200 return 0; 2201 } 2202 return 1; 2203 } 2204 2205 static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 2206 { 2207 struct pci_dev *pcidev; 2208 2209 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 2210 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 2211 if (pcidev) { 2212 dev->model = SONYPI_DEVICE_TYPE1; 2213 dev->evport_offset = SONYPI_TYPE1_OFFSET; 2214 dev->event_types = type1_events; 2215 goto out; 2216 } 2217 2218 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 2219 PCI_DEVICE_ID_INTEL_ICH6_1, NULL); 2220 if (pcidev) { 2221 dev->model = SONYPI_DEVICE_TYPE2; 2222 dev->evport_offset = SONYPI_TYPE2_OFFSET; 2223 dev->event_types = type2_events; 2224 goto out; 2225 } 2226 2227 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 2228 PCI_DEVICE_ID_INTEL_ICH7_1, NULL); 2229 if (pcidev) { 2230 dev->model = SONYPI_DEVICE_TYPE3; 2231 dev->handle_irq = type3_handle_irq; 2232 dev->evport_offset = SONYPI_TYPE3_OFFSET; 2233 dev->event_types = type3_events; 2234 goto out; 2235 } 2236 2237 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 2238 PCI_DEVICE_ID_INTEL_ICH8_4, NULL); 2239 if (pcidev) { 2240 dev->model = SONYPI_DEVICE_TYPE3; 2241 dev->handle_irq = type3_handle_irq; 2242 dev->evport_offset = SONYPI_TYPE3_OFFSET; 2243 dev->event_types = type3_events; 2244 goto out; 2245 } 2246 2247 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 2248 PCI_DEVICE_ID_INTEL_ICH9_1, NULL); 2249 if (pcidev) { 2250 dev->model = SONYPI_DEVICE_TYPE3; 2251 dev->handle_irq = type3_handle_irq; 2252 dev->evport_offset = SONYPI_TYPE3_OFFSET; 2253 dev->event_types = type3_events; 2254 goto out; 2255 } 2256 2257 /* default */ 2258 dev->model = SONYPI_DEVICE_TYPE2; 2259 dev->evport_offset = SONYPI_TYPE2_OFFSET; 2260 dev->event_types = type2_events; 2261 2262 out: 2263 if (pcidev) 2264 pci_dev_put(pcidev); 2265 2266 pr_info("detected Type%d model\n", 2267 dev->model == SONYPI_DEVICE_TYPE1 ? 1 : 2268 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); 2269 } 2270 2271 /* camera tests and poweron/poweroff */ 2272 #define SONYPI_CAMERA_PICTURE 5 2273 #define SONYPI_CAMERA_CONTROL 0x10 2274 2275 #define SONYPI_CAMERA_BRIGHTNESS 0 2276 #define SONYPI_CAMERA_CONTRAST 1 2277 #define SONYPI_CAMERA_HUE 2 2278 #define SONYPI_CAMERA_COLOR 3 2279 #define SONYPI_CAMERA_SHARPNESS 4 2280 2281 #define SONYPI_CAMERA_EXPOSURE_MASK 0xC 2282 #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3 2283 #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30 2284 #define SONYPI_CAMERA_MUTE_MASK 0x40 2285 2286 /* the rest don't need a loop until not 0xff */ 2287 #define SONYPI_CAMERA_AGC 6 2288 #define SONYPI_CAMERA_AGC_MASK 0x30 2289 #define SONYPI_CAMERA_SHUTTER_MASK 0x7 2290 2291 #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7 2292 #define SONYPI_CAMERA_CONTROL 0x10 2293 2294 #define SONYPI_CAMERA_STATUS 7 2295 #define SONYPI_CAMERA_STATUS_READY 0x2 2296 #define SONYPI_CAMERA_STATUS_POSITION 0x4 2297 2298 #define SONYPI_DIRECTION_BACKWARDS 0x4 2299 2300 #define SONYPI_CAMERA_REVISION 8 2301 #define SONYPI_CAMERA_ROMVERSION 9 2302 2303 static int __sony_pic_camera_ready(void) 2304 { 2305 u8 v; 2306 2307 v = sony_pic_call2(0x8f, SONYPI_CAMERA_STATUS); 2308 return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY)); 2309 } 2310 2311 static int __sony_pic_camera_off(void) 2312 { 2313 if (!camera) { 2314 pr_warn("camera control not enabled\n"); 2315 return -ENODEV; 2316 } 2317 2318 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, 2319 SONYPI_CAMERA_MUTE_MASK), 2320 ITERATIONS_SHORT); 2321 2322 if (spic_dev.camera_power) { 2323 sony_pic_call2(0x91, 0); 2324 spic_dev.camera_power = 0; 2325 } 2326 return 0; 2327 } 2328 2329 static int __sony_pic_camera_on(void) 2330 { 2331 int i, j, x; 2332 2333 if (!camera) { 2334 pr_warn("camera control not enabled\n"); 2335 return -ENODEV; 2336 } 2337 2338 if (spic_dev.camera_power) 2339 return 0; 2340 2341 for (j = 5; j > 0; j--) { 2342 2343 for (x = 0; x < 100 && sony_pic_call2(0x91, 0x1); x++) 2344 msleep(10); 2345 sony_pic_call1(0x93); 2346 2347 for (i = 400; i > 0; i--) { 2348 if (__sony_pic_camera_ready()) 2349 break; 2350 msleep(10); 2351 } 2352 if (i) 2353 break; 2354 } 2355 2356 if (j == 0) { 2357 pr_warn("failed to power on camera\n"); 2358 return -ENODEV; 2359 } 2360 2361 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, 2362 0x5a), 2363 ITERATIONS_SHORT); 2364 2365 spic_dev.camera_power = 1; 2366 return 0; 2367 } 2368 2369 /* External camera command (exported to the motion eye v4l driver) */ 2370 int sony_pic_camera_command(int command, u8 value) 2371 { 2372 if (!camera) 2373 return -EIO; 2374 2375 mutex_lock(&spic_dev.lock); 2376 2377 switch (command) { 2378 case SONY_PIC_COMMAND_SETCAMERA: 2379 if (value) 2380 __sony_pic_camera_on(); 2381 else 2382 __sony_pic_camera_off(); 2383 break; 2384 case SONY_PIC_COMMAND_SETCAMERABRIGHTNESS: 2385 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_BRIGHTNESS, value), 2386 ITERATIONS_SHORT); 2387 break; 2388 case SONY_PIC_COMMAND_SETCAMERACONTRAST: 2389 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTRAST, value), 2390 ITERATIONS_SHORT); 2391 break; 2392 case SONY_PIC_COMMAND_SETCAMERAHUE: 2393 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_HUE, value), 2394 ITERATIONS_SHORT); 2395 break; 2396 case SONY_PIC_COMMAND_SETCAMERACOLOR: 2397 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_COLOR, value), 2398 ITERATIONS_SHORT); 2399 break; 2400 case SONY_PIC_COMMAND_SETCAMERASHARPNESS: 2401 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_SHARPNESS, value), 2402 ITERATIONS_SHORT); 2403 break; 2404 case SONY_PIC_COMMAND_SETCAMERAPICTURE: 2405 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, value), 2406 ITERATIONS_SHORT); 2407 break; 2408 case SONY_PIC_COMMAND_SETCAMERAAGC: 2409 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_AGC, value), 2410 ITERATIONS_SHORT); 2411 break; 2412 default: 2413 pr_err("sony_pic_camera_command invalid: %d\n", command); 2414 break; 2415 } 2416 mutex_unlock(&spic_dev.lock); 2417 return 0; 2418 } 2419 EXPORT_SYMBOL(sony_pic_camera_command); 2420 2421 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */ 2422 static void __sony_pic_set_wwanpower(u8 state) 2423 { 2424 state = !!state; 2425 if (spic_dev.wwan_power == state) 2426 return; 2427 sony_pic_call2(0xB0, state); 2428 sony_pic_call1(0x82); 2429 spic_dev.wwan_power = state; 2430 } 2431 2432 static ssize_t sony_pic_wwanpower_store(struct device *dev, 2433 struct device_attribute *attr, 2434 const char *buffer, size_t count) 2435 { 2436 unsigned long value; 2437 if (count > 31) 2438 return -EINVAL; 2439 2440 value = simple_strtoul(buffer, NULL, 10); 2441 mutex_lock(&spic_dev.lock); 2442 __sony_pic_set_wwanpower(value); 2443 mutex_unlock(&spic_dev.lock); 2444 2445 return count; 2446 } 2447 2448 static ssize_t sony_pic_wwanpower_show(struct device *dev, 2449 struct device_attribute *attr, char *buffer) 2450 { 2451 ssize_t count; 2452 mutex_lock(&spic_dev.lock); 2453 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.wwan_power); 2454 mutex_unlock(&spic_dev.lock); 2455 return count; 2456 } 2457 2458 /* bluetooth subsystem power state */ 2459 static void __sony_pic_set_bluetoothpower(u8 state) 2460 { 2461 state = !!state; 2462 if (spic_dev.bluetooth_power == state) 2463 return; 2464 sony_pic_call2(0x96, state); 2465 sony_pic_call1(0x82); 2466 spic_dev.bluetooth_power = state; 2467 } 2468 2469 static ssize_t sony_pic_bluetoothpower_store(struct device *dev, 2470 struct device_attribute *attr, 2471 const char *buffer, size_t count) 2472 { 2473 unsigned long value; 2474 if (count > 31) 2475 return -EINVAL; 2476 2477 value = simple_strtoul(buffer, NULL, 10); 2478 mutex_lock(&spic_dev.lock); 2479 __sony_pic_set_bluetoothpower(value); 2480 mutex_unlock(&spic_dev.lock); 2481 2482 return count; 2483 } 2484 2485 static ssize_t sony_pic_bluetoothpower_show(struct device *dev, 2486 struct device_attribute *attr, char *buffer) 2487 { 2488 ssize_t count = 0; 2489 mutex_lock(&spic_dev.lock); 2490 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power); 2491 mutex_unlock(&spic_dev.lock); 2492 return count; 2493 } 2494 2495 /* fan speed */ 2496 /* FAN0 information (reverse engineered from ACPI tables) */ 2497 #define SONY_PIC_FAN0_STATUS 0x93 2498 static int sony_pic_set_fanspeed(unsigned long value) 2499 { 2500 return ec_write(SONY_PIC_FAN0_STATUS, value); 2501 } 2502 2503 static int sony_pic_get_fanspeed(u8 *value) 2504 { 2505 return ec_read(SONY_PIC_FAN0_STATUS, value); 2506 } 2507 2508 static ssize_t sony_pic_fanspeed_store(struct device *dev, 2509 struct device_attribute *attr, 2510 const char *buffer, size_t count) 2511 { 2512 unsigned long value; 2513 if (count > 31) 2514 return -EINVAL; 2515 2516 value = simple_strtoul(buffer, NULL, 10); 2517 if (sony_pic_set_fanspeed(value)) 2518 return -EIO; 2519 2520 return count; 2521 } 2522 2523 static ssize_t sony_pic_fanspeed_show(struct device *dev, 2524 struct device_attribute *attr, char *buffer) 2525 { 2526 u8 value = 0; 2527 if (sony_pic_get_fanspeed(&value)) 2528 return -EIO; 2529 2530 return snprintf(buffer, PAGE_SIZE, "%d\n", value); 2531 } 2532 2533 #define SPIC_ATTR(_name, _mode) \ 2534 struct device_attribute spic_attr_##_name = __ATTR(_name, \ 2535 _mode, sony_pic_## _name ##_show, \ 2536 sony_pic_## _name ##_store) 2537 2538 static SPIC_ATTR(bluetoothpower, 0644); 2539 static SPIC_ATTR(wwanpower, 0644); 2540 static SPIC_ATTR(fanspeed, 0644); 2541 2542 static struct attribute *spic_attributes[] = { 2543 &spic_attr_bluetoothpower.attr, 2544 &spic_attr_wwanpower.attr, 2545 &spic_attr_fanspeed.attr, 2546 NULL 2547 }; 2548 2549 static struct attribute_group spic_attribute_group = { 2550 .attrs = spic_attributes 2551 }; 2552 2553 /******** SONYPI compatibility **********/ 2554 #ifdef CONFIG_SONYPI_COMPAT 2555 2556 /* battery / brightness / temperature addresses */ 2557 #define SONYPI_BAT_FLAGS 0x81 2558 #define SONYPI_LCD_LIGHT 0x96 2559 #define SONYPI_BAT1_PCTRM 0xa0 2560 #define SONYPI_BAT1_LEFT 0xa2 2561 #define SONYPI_BAT1_MAXRT 0xa4 2562 #define SONYPI_BAT2_PCTRM 0xa8 2563 #define SONYPI_BAT2_LEFT 0xaa 2564 #define SONYPI_BAT2_MAXRT 0xac 2565 #define SONYPI_BAT1_MAXTK 0xb0 2566 #define SONYPI_BAT1_FULL 0xb2 2567 #define SONYPI_BAT2_MAXTK 0xb8 2568 #define SONYPI_BAT2_FULL 0xba 2569 #define SONYPI_TEMP_STATUS 0xC1 2570 2571 struct sonypi_compat_s { 2572 struct fasync_struct *fifo_async; 2573 struct kfifo fifo; 2574 spinlock_t fifo_lock; 2575 wait_queue_head_t fifo_proc_list; 2576 atomic_t open_count; 2577 }; 2578 static struct sonypi_compat_s sonypi_compat = { 2579 .open_count = ATOMIC_INIT(0), 2580 }; 2581 2582 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 2583 { 2584 return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async); 2585 } 2586 2587 static int sonypi_misc_release(struct inode *inode, struct file *file) 2588 { 2589 atomic_dec(&sonypi_compat.open_count); 2590 return 0; 2591 } 2592 2593 static int sonypi_misc_open(struct inode *inode, struct file *file) 2594 { 2595 /* Flush input queue on first open */ 2596 unsigned long flags; 2597 2598 spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); 2599 2600 if (atomic_inc_return(&sonypi_compat.open_count) == 1) 2601 kfifo_reset(&sonypi_compat.fifo); 2602 2603 spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); 2604 2605 return 0; 2606 } 2607 2608 static ssize_t sonypi_misc_read(struct file *file, char __user *buf, 2609 size_t count, loff_t *pos) 2610 { 2611 ssize_t ret; 2612 unsigned char c; 2613 2614 if ((kfifo_len(&sonypi_compat.fifo) == 0) && 2615 (file->f_flags & O_NONBLOCK)) 2616 return -EAGAIN; 2617 2618 ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, 2619 kfifo_len(&sonypi_compat.fifo) != 0); 2620 if (ret) 2621 return ret; 2622 2623 while (ret < count && 2624 (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c), 2625 &sonypi_compat.fifo_lock) == sizeof(c))) { 2626 if (put_user(c, buf++)) 2627 return -EFAULT; 2628 ret++; 2629 } 2630 2631 if (ret > 0) { 2632 struct inode *inode = file->f_path.dentry->d_inode; 2633 inode->i_atime = current_fs_time(inode->i_sb); 2634 } 2635 2636 return ret; 2637 } 2638 2639 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) 2640 { 2641 poll_wait(file, &sonypi_compat.fifo_proc_list, wait); 2642 if (kfifo_len(&sonypi_compat.fifo)) 2643 return POLLIN | POLLRDNORM; 2644 return 0; 2645 } 2646 2647 static int ec_read16(u8 addr, u16 *value) 2648 { 2649 u8 val_lb, val_hb; 2650 if (ec_read(addr, &val_lb)) 2651 return -1; 2652 if (ec_read(addr + 1, &val_hb)) 2653 return -1; 2654 *value = val_lb | (val_hb << 8); 2655 return 0; 2656 } 2657 2658 static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, 2659 unsigned long arg) 2660 { 2661 int ret = 0; 2662 void __user *argp = (void __user *)arg; 2663 u8 val8; 2664 u16 val16; 2665 int value; 2666 2667 mutex_lock(&spic_dev.lock); 2668 switch (cmd) { 2669 case SONYPI_IOCGBRT: 2670 if (sony_bl_props.dev == NULL) { 2671 ret = -EIO; 2672 break; 2673 } 2674 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value)) { 2675 ret = -EIO; 2676 break; 2677 } 2678 val8 = ((value & 0xff) - 1) << 5; 2679 if (copy_to_user(argp, &val8, sizeof(val8))) 2680 ret = -EFAULT; 2681 break; 2682 case SONYPI_IOCSBRT: 2683 if (sony_bl_props.dev == NULL) { 2684 ret = -EIO; 2685 break; 2686 } 2687 if (copy_from_user(&val8, argp, sizeof(val8))) { 2688 ret = -EFAULT; 2689 break; 2690 } 2691 if (acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", 2692 (val8 >> 5) + 1, NULL)) { 2693 ret = -EIO; 2694 break; 2695 } 2696 /* sync the backlight device status */ 2697 sony_bl_props.dev->props.brightness = 2698 sony_backlight_get_brightness(sony_bl_props.dev); 2699 break; 2700 case SONYPI_IOCGBAT1CAP: 2701 if (ec_read16(SONYPI_BAT1_FULL, &val16)) { 2702 ret = -EIO; 2703 break; 2704 } 2705 if (copy_to_user(argp, &val16, sizeof(val16))) 2706 ret = -EFAULT; 2707 break; 2708 case SONYPI_IOCGBAT1REM: 2709 if (ec_read16(SONYPI_BAT1_LEFT, &val16)) { 2710 ret = -EIO; 2711 break; 2712 } 2713 if (copy_to_user(argp, &val16, sizeof(val16))) 2714 ret = -EFAULT; 2715 break; 2716 case SONYPI_IOCGBAT2CAP: 2717 if (ec_read16(SONYPI_BAT2_FULL, &val16)) { 2718 ret = -EIO; 2719 break; 2720 } 2721 if (copy_to_user(argp, &val16, sizeof(val16))) 2722 ret = -EFAULT; 2723 break; 2724 case SONYPI_IOCGBAT2REM: 2725 if (ec_read16(SONYPI_BAT2_LEFT, &val16)) { 2726 ret = -EIO; 2727 break; 2728 } 2729 if (copy_to_user(argp, &val16, sizeof(val16))) 2730 ret = -EFAULT; 2731 break; 2732 case SONYPI_IOCGBATFLAGS: 2733 if (ec_read(SONYPI_BAT_FLAGS, &val8)) { 2734 ret = -EIO; 2735 break; 2736 } 2737 val8 &= 0x07; 2738 if (copy_to_user(argp, &val8, sizeof(val8))) 2739 ret = -EFAULT; 2740 break; 2741 case SONYPI_IOCGBLUE: 2742 val8 = spic_dev.bluetooth_power; 2743 if (copy_to_user(argp, &val8, sizeof(val8))) 2744 ret = -EFAULT; 2745 break; 2746 case SONYPI_IOCSBLUE: 2747 if (copy_from_user(&val8, argp, sizeof(val8))) { 2748 ret = -EFAULT; 2749 break; 2750 } 2751 __sony_pic_set_bluetoothpower(val8); 2752 break; 2753 /* FAN Controls */ 2754 case SONYPI_IOCGFAN: 2755 if (sony_pic_get_fanspeed(&val8)) { 2756 ret = -EIO; 2757 break; 2758 } 2759 if (copy_to_user(argp, &val8, sizeof(val8))) 2760 ret = -EFAULT; 2761 break; 2762 case SONYPI_IOCSFAN: 2763 if (copy_from_user(&val8, argp, sizeof(val8))) { 2764 ret = -EFAULT; 2765 break; 2766 } 2767 if (sony_pic_set_fanspeed(val8)) 2768 ret = -EIO; 2769 break; 2770 /* GET Temperature (useful under APM) */ 2771 case SONYPI_IOCGTEMP: 2772 if (ec_read(SONYPI_TEMP_STATUS, &val8)) { 2773 ret = -EIO; 2774 break; 2775 } 2776 if (copy_to_user(argp, &val8, sizeof(val8))) 2777 ret = -EFAULT; 2778 break; 2779 default: 2780 ret = -EINVAL; 2781 } 2782 mutex_unlock(&spic_dev.lock); 2783 return ret; 2784 } 2785 2786 static const struct file_operations sonypi_misc_fops = { 2787 .owner = THIS_MODULE, 2788 .read = sonypi_misc_read, 2789 .poll = sonypi_misc_poll, 2790 .open = sonypi_misc_open, 2791 .release = sonypi_misc_release, 2792 .fasync = sonypi_misc_fasync, 2793 .unlocked_ioctl = sonypi_misc_ioctl, 2794 .llseek = noop_llseek, 2795 }; 2796 2797 static struct miscdevice sonypi_misc_device = { 2798 .minor = MISC_DYNAMIC_MINOR, 2799 .name = "sonypi", 2800 .fops = &sonypi_misc_fops, 2801 }; 2802 2803 static void sonypi_compat_report_event(u8 event) 2804 { 2805 kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event, 2806 sizeof(event), &sonypi_compat.fifo_lock); 2807 kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); 2808 wake_up_interruptible(&sonypi_compat.fifo_proc_list); 2809 } 2810 2811 static int sonypi_compat_init(void) 2812 { 2813 int error; 2814 2815 spin_lock_init(&sonypi_compat.fifo_lock); 2816 error = 2817 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 2818 if (error) { 2819 pr_err("kfifo_alloc failed\n"); 2820 return error; 2821 } 2822 2823 init_waitqueue_head(&sonypi_compat.fifo_proc_list); 2824 2825 if (minor != -1) 2826 sonypi_misc_device.minor = minor; 2827 error = misc_register(&sonypi_misc_device); 2828 if (error) { 2829 pr_err("misc_register failed\n"); 2830 goto err_free_kfifo; 2831 } 2832 if (minor == -1) 2833 pr_info("device allocated minor is %d\n", 2834 sonypi_misc_device.minor); 2835 2836 return 0; 2837 2838 err_free_kfifo: 2839 kfifo_free(&sonypi_compat.fifo); 2840 return error; 2841 } 2842 2843 static void sonypi_compat_exit(void) 2844 { 2845 misc_deregister(&sonypi_misc_device); 2846 kfifo_free(&sonypi_compat.fifo); 2847 } 2848 #else 2849 static int sonypi_compat_init(void) { return 0; } 2850 static void sonypi_compat_exit(void) { } 2851 static void sonypi_compat_report_event(u8 event) { } 2852 #endif /* CONFIG_SONYPI_COMPAT */ 2853 2854 /* 2855 * ACPI callbacks 2856 */ 2857 static acpi_status 2858 sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) 2859 { 2860 u32 i; 2861 struct sony_pic_dev *dev = (struct sony_pic_dev *)context; 2862 2863 switch (resource->type) { 2864 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 2865 { 2866 /* start IO enumeration */ 2867 struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); 2868 if (!ioport) 2869 return AE_ERROR; 2870 2871 list_add(&ioport->list, &dev->ioports); 2872 return AE_OK; 2873 } 2874 2875 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 2876 /* end IO enumeration */ 2877 return AE_OK; 2878 2879 case ACPI_RESOURCE_TYPE_IRQ: 2880 { 2881 struct acpi_resource_irq *p = &resource->data.irq; 2882 struct sony_pic_irq *interrupt = NULL; 2883 if (!p || !p->interrupt_count) { 2884 /* 2885 * IRQ descriptors may have no IRQ# bits set, 2886 * particularly those those w/ _STA disabled 2887 */ 2888 dprintk("Blank IRQ resource\n"); 2889 return AE_OK; 2890 } 2891 for (i = 0; i < p->interrupt_count; i++) { 2892 if (!p->interrupts[i]) { 2893 pr_warn("Invalid IRQ %d\n", 2894 p->interrupts[i]); 2895 continue; 2896 } 2897 interrupt = kzalloc(sizeof(*interrupt), 2898 GFP_KERNEL); 2899 if (!interrupt) 2900 return AE_ERROR; 2901 2902 list_add(&interrupt->list, &dev->interrupts); 2903 interrupt->irq.triggering = p->triggering; 2904 interrupt->irq.polarity = p->polarity; 2905 interrupt->irq.sharable = p->sharable; 2906 interrupt->irq.interrupt_count = 1; 2907 interrupt->irq.interrupts[0] = p->interrupts[i]; 2908 } 2909 return AE_OK; 2910 } 2911 case ACPI_RESOURCE_TYPE_IO: 2912 { 2913 struct acpi_resource_io *io = &resource->data.io; 2914 struct sony_pic_ioport *ioport = 2915 list_first_entry(&dev->ioports, struct sony_pic_ioport, list); 2916 if (!io) { 2917 dprintk("Blank IO resource\n"); 2918 return AE_OK; 2919 } 2920 2921 if (!ioport->io1.minimum) { 2922 memcpy(&ioport->io1, io, sizeof(*io)); 2923 dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, 2924 ioport->io1.address_length); 2925 } 2926 else if (!ioport->io2.minimum) { 2927 memcpy(&ioport->io2, io, sizeof(*io)); 2928 dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, 2929 ioport->io2.address_length); 2930 } 2931 else { 2932 pr_err("Unknown SPIC Type, more than 2 IO Ports\n"); 2933 return AE_ERROR; 2934 } 2935 return AE_OK; 2936 } 2937 default: 2938 dprintk("Resource %d isn't an IRQ nor an IO port\n", 2939 resource->type); 2940 2941 case ACPI_RESOURCE_TYPE_END_TAG: 2942 return AE_OK; 2943 } 2944 return AE_CTRL_TERMINATE; 2945 } 2946 2947 static int sony_pic_possible_resources(struct acpi_device *device) 2948 { 2949 int result = 0; 2950 acpi_status status = AE_OK; 2951 2952 if (!device) 2953 return -EINVAL; 2954 2955 /* get device status */ 2956 /* see acpi_pci_link_get_current acpi_pci_link_get_possible */ 2957 dprintk("Evaluating _STA\n"); 2958 result = acpi_bus_get_status(device); 2959 if (result) { 2960 pr_warn("Unable to read status\n"); 2961 goto end; 2962 } 2963 2964 if (!device->status.enabled) 2965 dprintk("Device disabled\n"); 2966 else 2967 dprintk("Device enabled\n"); 2968 2969 /* 2970 * Query and parse 'method' 2971 */ 2972 dprintk("Evaluating %s\n", METHOD_NAME__PRS); 2973 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, 2974 sony_pic_read_possible_resource, &spic_dev); 2975 if (ACPI_FAILURE(status)) { 2976 pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS); 2977 result = -ENODEV; 2978 } 2979 end: 2980 return result; 2981 } 2982 2983 /* 2984 * Disable the spic device by calling its _DIS method 2985 */ 2986 static int sony_pic_disable(struct acpi_device *device) 2987 { 2988 acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL, 2989 NULL); 2990 2991 if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND) 2992 return -ENXIO; 2993 2994 dprintk("Device disabled\n"); 2995 return 0; 2996 } 2997 2998 2999 /* 3000 * Based on drivers/acpi/pci_link.c:acpi_pci_link_set 3001 * 3002 * Call _SRS to set current resources 3003 */ 3004 static int sony_pic_enable(struct acpi_device *device, 3005 struct sony_pic_ioport *ioport, struct sony_pic_irq *irq) 3006 { 3007 acpi_status status; 3008 int result = 0; 3009 /* Type 1 resource layout is: 3010 * IO 3011 * IO 3012 * IRQNoFlags 3013 * End 3014 * 3015 * Type 2 and 3 resource layout is: 3016 * IO 3017 * IRQNoFlags 3018 * End 3019 */ 3020 struct { 3021 struct acpi_resource res1; 3022 struct acpi_resource res2; 3023 struct acpi_resource res3; 3024 struct acpi_resource res4; 3025 } *resource; 3026 struct acpi_buffer buffer = { 0, NULL }; 3027 3028 if (!ioport || !irq) 3029 return -EINVAL; 3030 3031 /* init acpi_buffer */ 3032 resource = kzalloc(sizeof(*resource) + 1, GFP_KERNEL); 3033 if (!resource) 3034 return -ENOMEM; 3035 3036 buffer.length = sizeof(*resource) + 1; 3037 buffer.pointer = resource; 3038 3039 /* setup Type 1 resources */ 3040 if (spic_dev.model == SONYPI_DEVICE_TYPE1) { 3041 3042 /* setup io resources */ 3043 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 3044 resource->res1.length = sizeof(struct acpi_resource); 3045 memcpy(&resource->res1.data.io, &ioport->io1, 3046 sizeof(struct acpi_resource_io)); 3047 3048 resource->res2.type = ACPI_RESOURCE_TYPE_IO; 3049 resource->res2.length = sizeof(struct acpi_resource); 3050 memcpy(&resource->res2.data.io, &ioport->io2, 3051 sizeof(struct acpi_resource_io)); 3052 3053 /* setup irq resource */ 3054 resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; 3055 resource->res3.length = sizeof(struct acpi_resource); 3056 memcpy(&resource->res3.data.irq, &irq->irq, 3057 sizeof(struct acpi_resource_irq)); 3058 /* we requested a shared irq */ 3059 resource->res3.data.irq.sharable = ACPI_SHARED; 3060 3061 resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; 3062 3063 } 3064 /* setup Type 2/3 resources */ 3065 else { 3066 /* setup io resource */ 3067 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 3068 resource->res1.length = sizeof(struct acpi_resource); 3069 memcpy(&resource->res1.data.io, &ioport->io1, 3070 sizeof(struct acpi_resource_io)); 3071 3072 /* setup irq resource */ 3073 resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; 3074 resource->res2.length = sizeof(struct acpi_resource); 3075 memcpy(&resource->res2.data.irq, &irq->irq, 3076 sizeof(struct acpi_resource_irq)); 3077 /* we requested a shared irq */ 3078 resource->res2.data.irq.sharable = ACPI_SHARED; 3079 3080 resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; 3081 } 3082 3083 /* Attempt to set the resource */ 3084 dprintk("Evaluating _SRS\n"); 3085 status = acpi_set_current_resources(device->handle, &buffer); 3086 3087 /* check for total failure */ 3088 if (ACPI_FAILURE(status)) { 3089 pr_err("Error evaluating _SRS\n"); 3090 result = -ENODEV; 3091 goto end; 3092 } 3093 3094 /* Necessary device initializations calls (from sonypi) */ 3095 sony_pic_call1(0x82); 3096 sony_pic_call2(0x81, 0xff); 3097 sony_pic_call1(compat ? 0x92 : 0x82); 3098 3099 end: 3100 kfree(resource); 3101 return result; 3102 } 3103 3104 /***************** 3105 * 3106 * ISR: some event is available 3107 * 3108 *****************/ 3109 static irqreturn_t sony_pic_irq(int irq, void *dev_id) 3110 { 3111 int i, j; 3112 u8 ev = 0; 3113 u8 data_mask = 0; 3114 u8 device_event = 0; 3115 3116 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; 3117 3118 ev = inb_p(dev->cur_ioport->io1.minimum); 3119 if (dev->cur_ioport->io2.minimum) 3120 data_mask = inb_p(dev->cur_ioport->io2.minimum); 3121 else 3122 data_mask = inb_p(dev->cur_ioport->io1.minimum + 3123 dev->evport_offset); 3124 3125 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 3126 ev, data_mask, dev->cur_ioport->io1.minimum, 3127 dev->evport_offset); 3128 3129 if (ev == 0x00 || ev == 0xff) 3130 return IRQ_HANDLED; 3131 3132 for (i = 0; dev->event_types[i].mask; i++) { 3133 3134 if ((data_mask & dev->event_types[i].data) != 3135 dev->event_types[i].data) 3136 continue; 3137 3138 if (!(mask & dev->event_types[i].mask)) 3139 continue; 3140 3141 for (j = 0; dev->event_types[i].events[j].event; j++) { 3142 if (ev == dev->event_types[i].events[j].data) { 3143 device_event = 3144 dev->event_types[i].events[j].event; 3145 /* some events may require ignoring */ 3146 if (!device_event) 3147 return IRQ_HANDLED; 3148 goto found; 3149 } 3150 } 3151 } 3152 /* Still not able to decode the event try to pass 3153 * it over to the minidriver 3154 */ 3155 if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0) 3156 return IRQ_HANDLED; 3157 3158 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 3159 ev, data_mask, dev->cur_ioport->io1.minimum, 3160 dev->evport_offset); 3161 return IRQ_HANDLED; 3162 3163 found: 3164 sony_laptop_report_input_event(device_event); 3165 acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); 3166 sonypi_compat_report_event(device_event); 3167 return IRQ_HANDLED; 3168 } 3169 3170 /***************** 3171 * 3172 * ACPI driver 3173 * 3174 *****************/ 3175 static int sony_pic_remove(struct acpi_device *device, int type) 3176 { 3177 struct sony_pic_ioport *io, *tmp_io; 3178 struct sony_pic_irq *irq, *tmp_irq; 3179 3180 if (sony_pic_disable(device)) { 3181 pr_err("Couldn't disable device\n"); 3182 return -ENXIO; 3183 } 3184 3185 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 3186 release_region(spic_dev.cur_ioport->io1.minimum, 3187 spic_dev.cur_ioport->io1.address_length); 3188 if (spic_dev.cur_ioport->io2.minimum) 3189 release_region(spic_dev.cur_ioport->io2.minimum, 3190 spic_dev.cur_ioport->io2.address_length); 3191 3192 sonypi_compat_exit(); 3193 3194 sony_laptop_remove_input(); 3195 3196 /* pf attrs */ 3197 sysfs_remove_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 3198 sony_pf_remove(); 3199 3200 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 3201 list_del(&io->list); 3202 kfree(io); 3203 } 3204 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 3205 list_del(&irq->list); 3206 kfree(irq); 3207 } 3208 spic_dev.cur_ioport = NULL; 3209 spic_dev.cur_irq = NULL; 3210 3211 dprintk(SONY_PIC_DRIVER_NAME " removed.\n"); 3212 return 0; 3213 } 3214 3215 static int sony_pic_add(struct acpi_device *device) 3216 { 3217 int result; 3218 struct sony_pic_ioport *io, *tmp_io; 3219 struct sony_pic_irq *irq, *tmp_irq; 3220 3221 pr_info("%s v%s\n", SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); 3222 3223 spic_dev.acpi_dev = device; 3224 strcpy(acpi_device_class(device), "sony/hotkey"); 3225 sony_pic_detect_device_type(&spic_dev); 3226 mutex_init(&spic_dev.lock); 3227 3228 /* read _PRS resources */ 3229 result = sony_pic_possible_resources(device); 3230 if (result) { 3231 pr_err("Unable to read possible resources\n"); 3232 goto err_free_resources; 3233 } 3234 3235 /* setup input devices and helper fifo */ 3236 result = sony_laptop_setup_input(device); 3237 if (result) { 3238 pr_err("Unable to create input devices\n"); 3239 goto err_free_resources; 3240 } 3241 3242 if (sonypi_compat_init()) 3243 goto err_remove_input; 3244 3245 /* request io port */ 3246 list_for_each_entry_reverse(io, &spic_dev.ioports, list) { 3247 if (request_region(io->io1.minimum, io->io1.address_length, 3248 "Sony Programmable I/O Device")) { 3249 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", 3250 io->io1.minimum, io->io1.maximum, 3251 io->io1.address_length); 3252 /* Type 1 have 2 ioports */ 3253 if (io->io2.minimum) { 3254 if (request_region(io->io2.minimum, 3255 io->io2.address_length, 3256 "Sony Programmable I/O Device")) { 3257 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", 3258 io->io2.minimum, io->io2.maximum, 3259 io->io2.address_length); 3260 spic_dev.cur_ioport = io; 3261 break; 3262 } 3263 else { 3264 dprintk("Unable to get I/O port2: " 3265 "0x%.4x (0x%.4x) + 0x%.2x\n", 3266 io->io2.minimum, io->io2.maximum, 3267 io->io2.address_length); 3268 release_region(io->io1.minimum, 3269 io->io1.address_length); 3270 } 3271 } 3272 else { 3273 spic_dev.cur_ioport = io; 3274 break; 3275 } 3276 } 3277 } 3278 if (!spic_dev.cur_ioport) { 3279 pr_err("Failed to request_region\n"); 3280 result = -ENODEV; 3281 goto err_remove_compat; 3282 } 3283 3284 /* request IRQ */ 3285 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { 3286 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, 3287 0, "sony-laptop", &spic_dev)) { 3288 dprintk("IRQ: %d - triggering: %d - " 3289 "polarity: %d - shr: %d\n", 3290 irq->irq.interrupts[0], 3291 irq->irq.triggering, 3292 irq->irq.polarity, 3293 irq->irq.sharable); 3294 spic_dev.cur_irq = irq; 3295 break; 3296 } 3297 } 3298 if (!spic_dev.cur_irq) { 3299 pr_err("Failed to request_irq\n"); 3300 result = -ENODEV; 3301 goto err_release_region; 3302 } 3303 3304 /* set resource status _SRS */ 3305 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 3306 if (result) { 3307 pr_err("Couldn't enable device\n"); 3308 goto err_free_irq; 3309 } 3310 3311 spic_dev.bluetooth_power = -1; 3312 /* create device attributes */ 3313 result = sony_pf_add(); 3314 if (result) 3315 goto err_disable_device; 3316 3317 result = sysfs_create_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 3318 if (result) 3319 goto err_remove_pf; 3320 3321 return 0; 3322 3323 err_remove_pf: 3324 sony_pf_remove(); 3325 3326 err_disable_device: 3327 sony_pic_disable(device); 3328 3329 err_free_irq: 3330 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 3331 3332 err_release_region: 3333 release_region(spic_dev.cur_ioport->io1.minimum, 3334 spic_dev.cur_ioport->io1.address_length); 3335 if (spic_dev.cur_ioport->io2.minimum) 3336 release_region(spic_dev.cur_ioport->io2.minimum, 3337 spic_dev.cur_ioport->io2.address_length); 3338 3339 err_remove_compat: 3340 sonypi_compat_exit(); 3341 3342 err_remove_input: 3343 sony_laptop_remove_input(); 3344 3345 err_free_resources: 3346 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 3347 list_del(&io->list); 3348 kfree(io); 3349 } 3350 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 3351 list_del(&irq->list); 3352 kfree(irq); 3353 } 3354 spic_dev.cur_ioport = NULL; 3355 spic_dev.cur_irq = NULL; 3356 3357 return result; 3358 } 3359 3360 static int sony_pic_suspend(struct acpi_device *device, pm_message_t state) 3361 { 3362 if (sony_pic_disable(device)) 3363 return -ENXIO; 3364 return 0; 3365 } 3366 3367 static int sony_pic_resume(struct acpi_device *device) 3368 { 3369 sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 3370 return 0; 3371 } 3372 3373 static const struct acpi_device_id sony_pic_device_ids[] = { 3374 {SONY_PIC_HID, 0}, 3375 {"", 0}, 3376 }; 3377 3378 static struct acpi_driver sony_pic_driver = { 3379 .name = SONY_PIC_DRIVER_NAME, 3380 .class = SONY_PIC_CLASS, 3381 .ids = sony_pic_device_ids, 3382 .owner = THIS_MODULE, 3383 .ops = { 3384 .add = sony_pic_add, 3385 .remove = sony_pic_remove, 3386 .suspend = sony_pic_suspend, 3387 .resume = sony_pic_resume, 3388 }, 3389 }; 3390 3391 static struct dmi_system_id __initdata sonypi_dmi_table[] = { 3392 { 3393 .ident = "Sony Vaio", 3394 .matches = { 3395 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3396 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"), 3397 }, 3398 }, 3399 { 3400 .ident = "Sony Vaio", 3401 .matches = { 3402 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 3403 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"), 3404 }, 3405 }, 3406 { } 3407 }; 3408 3409 static int __init sony_laptop_init(void) 3410 { 3411 int result; 3412 3413 if (!no_spic && dmi_check_system(sonypi_dmi_table)) { 3414 result = acpi_bus_register_driver(&sony_pic_driver); 3415 if (result) { 3416 pr_err("Unable to register SPIC driver\n"); 3417 goto out; 3418 } 3419 spic_drv_registered = 1; 3420 } 3421 3422 result = acpi_bus_register_driver(&sony_nc_driver); 3423 if (result) { 3424 pr_err("Unable to register SNC driver\n"); 3425 goto out_unregister_pic; 3426 } 3427 3428 return 0; 3429 3430 out_unregister_pic: 3431 if (spic_drv_registered) 3432 acpi_bus_unregister_driver(&sony_pic_driver); 3433 out: 3434 return result; 3435 } 3436 3437 static void __exit sony_laptop_exit(void) 3438 { 3439 acpi_bus_unregister_driver(&sony_nc_driver); 3440 if (spic_drv_registered) 3441 acpi_bus_unregister_driver(&sony_pic_driver); 3442 } 3443 3444 module_init(sony_laptop_init); 3445 module_exit(sony_laptop_exit); 3446