1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * ACPI Sony Notebook Control Driver (SNC and SPIC) 4 * 5 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> 6 * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it> 7 * 8 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c 9 * which are copyrighted by their respective authors. 10 * 11 * The SNY6001 driver part is based on the sonypi driver which includes 12 * material from: 13 * 14 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net> 15 * 16 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org> 17 * 18 * Copyright (C) 2001-2002 Alcôve <www.alcove.com> 19 * 20 * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> 21 * 22 * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> 23 * 24 * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp> 25 * 26 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> 27 * 28 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. 29 */ 30 31 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 32 33 #include <linux/kernel.h> 34 #include <linux/module.h> 35 #include <linux/moduleparam.h> 36 #include <linux/init.h> 37 #include <linux/types.h> 38 #include <linux/backlight.h> 39 #include <linux/platform_device.h> 40 #include <linux/err.h> 41 #include <linux/dmi.h> 42 #include <linux/pci.h> 43 #include <linux/interrupt.h> 44 #include <linux/delay.h> 45 #include <linux/input.h> 46 #include <linux/kfifo.h> 47 #include <linux/workqueue.h> 48 #include <linux/acpi.h> 49 #include <linux/slab.h> 50 #include <linux/sonypi.h> 51 #include <linux/rfkill.h> 52 #ifdef CONFIG_SONYPI_COMPAT 53 #include <linux/poll.h> 54 #include <linux/miscdevice.h> 55 #endif 56 #include <linux/uaccess.h> 57 #include <acpi/video.h> 58 59 #define dprintk(fmt, ...) \ 60 do { \ 61 if (debug) \ 62 pr_warn(fmt, ##__VA_ARGS__); \ 63 } while (0) 64 65 #define SONY_NC_CLASS "sony-nc" 66 #define SONY_NC_HID "SNY5001" 67 #define SONY_NC_DRIVER_NAME "Sony Notebook Control Driver" 68 69 #define SONY_PIC_CLASS "sony-pic" 70 #define SONY_PIC_HID "SNY6001" 71 #define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control Driver" 72 73 MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); 74 MODULE_DESCRIPTION("Sony laptop extras driver (SPIC and SNC ACPI device)"); 75 MODULE_LICENSE("GPL"); 76 77 static int debug; 78 module_param(debug, int, 0); 79 MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " 80 "the development of this driver"); 81 82 static int no_spic; /* = 0 */ 83 module_param(no_spic, int, 0444); 84 MODULE_PARM_DESC(no_spic, 85 "set this if you don't want to enable the SPIC device"); 86 87 static int compat; /* = 0 */ 88 module_param(compat, int, 0444); 89 MODULE_PARM_DESC(compat, 90 "set this if you want to enable backward compatibility mode"); 91 92 static unsigned long mask = 0xffffffff; 93 module_param(mask, ulong, 0644); 94 MODULE_PARM_DESC(mask, 95 "set this to the mask of event you want to enable (see doc)"); 96 97 static int camera; /* = 0 */ 98 module_param(camera, int, 0444); 99 MODULE_PARM_DESC(camera, 100 "set this to 1 to enable Motion Eye camera controls " 101 "(only use it if you have a C1VE or C1VN model)"); 102 103 #ifdef CONFIG_SONYPI_COMPAT 104 static int minor = -1; 105 module_param(minor, int, 0); 106 MODULE_PARM_DESC(minor, 107 "minor number of the misc device for the SPIC compatibility code, " 108 "default is -1 (automatic)"); 109 #endif 110 111 static int kbd_backlight = -1; 112 module_param(kbd_backlight, int, 0444); 113 MODULE_PARM_DESC(kbd_backlight, 114 "set this to 0 to disable keyboard backlight, " 115 "1 to enable it with automatic control and 2 to have it always " 116 "on (default: no change from current value)"); 117 118 static int kbd_backlight_timeout = -1; 119 module_param(kbd_backlight_timeout, int, 0444); 120 MODULE_PARM_DESC(kbd_backlight_timeout, 121 "meaningful values vary from 0 to 3 and their meaning depends " 122 "on the model (default: no change from current value)"); 123 124 #ifdef CONFIG_PM_SLEEP 125 static void sony_nc_thermal_resume(void); 126 #endif 127 static int sony_nc_kbd_backlight_setup(struct platform_device *pd, 128 unsigned int handle); 129 static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd, 130 unsigned int handle); 131 132 static int sony_nc_battery_care_setup(struct platform_device *pd, 133 unsigned int handle); 134 static void sony_nc_battery_care_cleanup(struct platform_device *pd); 135 136 static int sony_nc_thermal_setup(struct platform_device *pd); 137 static void sony_nc_thermal_cleanup(struct platform_device *pd); 138 139 static int sony_nc_lid_resume_setup(struct platform_device *pd, 140 unsigned int handle); 141 static void sony_nc_lid_resume_cleanup(struct platform_device *pd); 142 143 static int sony_nc_gfx_switch_setup(struct platform_device *pd, 144 unsigned int handle); 145 static void sony_nc_gfx_switch_cleanup(struct platform_device *pd); 146 static int __sony_nc_gfx_switch_status_get(void); 147 148 static int sony_nc_highspeed_charging_setup(struct platform_device *pd); 149 static void sony_nc_highspeed_charging_cleanup(struct platform_device *pd); 150 151 static int sony_nc_lowbatt_setup(struct platform_device *pd); 152 static void sony_nc_lowbatt_cleanup(struct platform_device *pd); 153 154 static int sony_nc_fanspeed_setup(struct platform_device *pd); 155 static void sony_nc_fanspeed_cleanup(struct platform_device *pd); 156 157 static int sony_nc_usb_charge_setup(struct platform_device *pd); 158 static void sony_nc_usb_charge_cleanup(struct platform_device *pd); 159 160 static int sony_nc_panelid_setup(struct platform_device *pd); 161 static void sony_nc_panelid_cleanup(struct platform_device *pd); 162 163 static int sony_nc_smart_conn_setup(struct platform_device *pd); 164 static void sony_nc_smart_conn_cleanup(struct platform_device *pd); 165 166 static int sony_nc_touchpad_setup(struct platform_device *pd, 167 unsigned int handle); 168 static void sony_nc_touchpad_cleanup(struct platform_device *pd); 169 170 enum sony_nc_rfkill { 171 SONY_WIFI, 172 SONY_BLUETOOTH, 173 SONY_WWAN, 174 SONY_WIMAX, 175 N_SONY_RFKILL, 176 }; 177 178 static int sony_rfkill_handle; 179 static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; 180 static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; 181 static int sony_nc_rfkill_setup(struct acpi_device *device, 182 unsigned int handle); 183 static void sony_nc_rfkill_cleanup(void); 184 static void sony_nc_rfkill_update(void); 185 186 /*********** Input Devices ***********/ 187 188 #define SONY_LAPTOP_BUF_SIZE 128 189 struct sony_laptop_input_s { 190 atomic_t users; 191 struct input_dev *jog_dev; 192 struct input_dev *key_dev; 193 struct kfifo fifo; 194 spinlock_t fifo_lock; 195 struct timer_list release_key_timer; 196 }; 197 198 static struct sony_laptop_input_s sony_laptop_input = { 199 .users = ATOMIC_INIT(0), 200 }; 201 202 struct sony_laptop_keypress { 203 struct input_dev *dev; 204 int key; 205 }; 206 207 /* Correspondance table between sonypi events 208 * and input layer indexes in the keymap 209 */ 210 static const int sony_laptop_input_index[] = { 211 -1, /* 0 no event */ 212 -1, /* 1 SONYPI_EVENT_JOGDIAL_DOWN */ 213 -1, /* 2 SONYPI_EVENT_JOGDIAL_UP */ 214 -1, /* 3 SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ 215 -1, /* 4 SONYPI_EVENT_JOGDIAL_UP_PRESSED */ 216 -1, /* 5 SONYPI_EVENT_JOGDIAL_PRESSED */ 217 -1, /* 6 SONYPI_EVENT_JOGDIAL_RELEASED */ 218 0, /* 7 SONYPI_EVENT_CAPTURE_PRESSED */ 219 1, /* 8 SONYPI_EVENT_CAPTURE_RELEASED */ 220 2, /* 9 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 221 3, /* 10 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 222 4, /* 11 SONYPI_EVENT_FNKEY_ESC */ 223 5, /* 12 SONYPI_EVENT_FNKEY_F1 */ 224 6, /* 13 SONYPI_EVENT_FNKEY_F2 */ 225 7, /* 14 SONYPI_EVENT_FNKEY_F3 */ 226 8, /* 15 SONYPI_EVENT_FNKEY_F4 */ 227 9, /* 16 SONYPI_EVENT_FNKEY_F5 */ 228 10, /* 17 SONYPI_EVENT_FNKEY_F6 */ 229 11, /* 18 SONYPI_EVENT_FNKEY_F7 */ 230 12, /* 19 SONYPI_EVENT_FNKEY_F8 */ 231 13, /* 20 SONYPI_EVENT_FNKEY_F9 */ 232 14, /* 21 SONYPI_EVENT_FNKEY_F10 */ 233 15, /* 22 SONYPI_EVENT_FNKEY_F11 */ 234 16, /* 23 SONYPI_EVENT_FNKEY_F12 */ 235 17, /* 24 SONYPI_EVENT_FNKEY_1 */ 236 18, /* 25 SONYPI_EVENT_FNKEY_2 */ 237 19, /* 26 SONYPI_EVENT_FNKEY_D */ 238 20, /* 27 SONYPI_EVENT_FNKEY_E */ 239 21, /* 28 SONYPI_EVENT_FNKEY_F */ 240 22, /* 29 SONYPI_EVENT_FNKEY_S */ 241 23, /* 30 SONYPI_EVENT_FNKEY_B */ 242 24, /* 31 SONYPI_EVENT_BLUETOOTH_PRESSED */ 243 25, /* 32 SONYPI_EVENT_PKEY_P1 */ 244 26, /* 33 SONYPI_EVENT_PKEY_P2 */ 245 27, /* 34 SONYPI_EVENT_PKEY_P3 */ 246 28, /* 35 SONYPI_EVENT_BACK_PRESSED */ 247 -1, /* 36 SONYPI_EVENT_LID_CLOSED */ 248 -1, /* 37 SONYPI_EVENT_LID_OPENED */ 249 29, /* 38 SONYPI_EVENT_BLUETOOTH_ON */ 250 30, /* 39 SONYPI_EVENT_BLUETOOTH_OFF */ 251 31, /* 40 SONYPI_EVENT_HELP_PRESSED */ 252 32, /* 41 SONYPI_EVENT_FNKEY_ONLY */ 253 33, /* 42 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 254 34, /* 43 SONYPI_EVENT_JOGDIAL_FAST_UP */ 255 35, /* 44 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 256 36, /* 45 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 257 37, /* 46 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 258 38, /* 47 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 259 39, /* 48 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 260 40, /* 49 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 261 41, /* 50 SONYPI_EVENT_ZOOM_PRESSED */ 262 42, /* 51 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 263 43, /* 52 SONYPI_EVENT_MEYE_FACE */ 264 44, /* 53 SONYPI_EVENT_MEYE_OPPOSITE */ 265 45, /* 54 SONYPI_EVENT_MEMORYSTICK_INSERT */ 266 46, /* 55 SONYPI_EVENT_MEMORYSTICK_EJECT */ 267 -1, /* 56 SONYPI_EVENT_ANYBUTTON_RELEASED */ 268 -1, /* 57 SONYPI_EVENT_BATTERY_INSERT */ 269 -1, /* 58 SONYPI_EVENT_BATTERY_REMOVE */ 270 -1, /* 59 SONYPI_EVENT_FNKEY_RELEASED */ 271 47, /* 60 SONYPI_EVENT_WIRELESS_ON */ 272 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */ 273 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */ 274 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 275 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */ 276 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */ 277 53, /* 66 SONYPI_EVENT_PKEY_P4 */ 278 54, /* 67 SONYPI_EVENT_PKEY_P5 */ 279 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */ 280 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ 281 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 282 -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ 283 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */ 284 59, /* 72 SONYPI_EVENT_VENDOR_PRESSED */ 285 }; 286 287 static int sony_laptop_input_keycode_map[] = { 288 KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ 289 KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ 290 KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 291 KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 292 KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ 293 KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ 294 KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ 295 KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ 296 KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ 297 KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ 298 KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ 299 KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ 300 KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ 301 KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ 302 KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ 303 KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ 304 KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ 305 KEY_FN_1, /* 17 SONYPI_EVENT_FNKEY_1 */ 306 KEY_FN_2, /* 18 SONYPI_EVENT_FNKEY_2 */ 307 KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ 308 KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ 309 KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ 310 KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ 311 KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ 312 KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ 313 KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ 314 KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ 315 KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ 316 KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ 317 KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ 318 KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ 319 KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ 320 KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ 321 KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 322 KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ 323 KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 324 KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 325 KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 326 KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 327 KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 328 KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 329 KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ 330 BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 331 KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ 332 KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ 333 KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ 334 KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ 335 KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ 336 KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ 337 KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */ 338 KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 339 KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */ 340 KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */ 341 KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */ 342 KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */ 343 KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ 344 KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ 345 KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 346 KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */ 347 KEY_VENDOR, /* 59 SONYPI_EVENT_VENDOR_PRESSED */ 348 }; 349 350 /* release buttons after a short delay if pressed */ 351 static void do_sony_laptop_release_key(struct timer_list *unused) 352 { 353 struct sony_laptop_keypress kp; 354 unsigned long flags; 355 356 spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags); 357 358 if (kfifo_out(&sony_laptop_input.fifo, 359 (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { 360 input_report_key(kp.dev, kp.key, 0); 361 input_sync(kp.dev); 362 } 363 364 /* If there is something in the fifo schedule next release. */ 365 if (kfifo_len(&sony_laptop_input.fifo) != 0) 366 mod_timer(&sony_laptop_input.release_key_timer, 367 jiffies + msecs_to_jiffies(10)); 368 369 spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags); 370 } 371 372 /* forward event to the input subsystem */ 373 static void sony_laptop_report_input_event(u8 event) 374 { 375 struct input_dev *jog_dev = sony_laptop_input.jog_dev; 376 struct input_dev *key_dev = sony_laptop_input.key_dev; 377 struct sony_laptop_keypress kp = { NULL }; 378 int scancode = -1; 379 380 if (event == SONYPI_EVENT_FNKEY_RELEASED || 381 event == SONYPI_EVENT_ANYBUTTON_RELEASED) { 382 /* Nothing, not all VAIOs generate this event */ 383 return; 384 } 385 386 /* report events */ 387 switch (event) { 388 /* jog_dev events */ 389 case SONYPI_EVENT_JOGDIAL_UP: 390 case SONYPI_EVENT_JOGDIAL_UP_PRESSED: 391 input_report_rel(jog_dev, REL_WHEEL, 1); 392 input_sync(jog_dev); 393 return; 394 395 case SONYPI_EVENT_JOGDIAL_DOWN: 396 case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: 397 input_report_rel(jog_dev, REL_WHEEL, -1); 398 input_sync(jog_dev); 399 return; 400 401 /* key_dev events */ 402 case SONYPI_EVENT_JOGDIAL_PRESSED: 403 kp.key = BTN_MIDDLE; 404 kp.dev = jog_dev; 405 break; 406 407 default: 408 if (event >= ARRAY_SIZE(sony_laptop_input_index)) { 409 dprintk("sony_laptop_report_input_event, event not known: %d\n", event); 410 break; 411 } 412 if ((scancode = sony_laptop_input_index[event]) != -1) { 413 kp.key = sony_laptop_input_keycode_map[scancode]; 414 if (kp.key != KEY_UNKNOWN) 415 kp.dev = key_dev; 416 } 417 break; 418 } 419 420 if (kp.dev) { 421 /* if we have a scancode we emit it so we can always 422 remap the key */ 423 if (scancode != -1) 424 input_event(kp.dev, EV_MSC, MSC_SCAN, scancode); 425 input_report_key(kp.dev, kp.key, 1); 426 input_sync(kp.dev); 427 428 /* schedule key release */ 429 kfifo_in_locked(&sony_laptop_input.fifo, 430 (unsigned char *)&kp, sizeof(kp), 431 &sony_laptop_input.fifo_lock); 432 mod_timer(&sony_laptop_input.release_key_timer, 433 jiffies + msecs_to_jiffies(10)); 434 } else 435 dprintk("unknown input event %.2x\n", event); 436 } 437 438 static int sony_laptop_setup_input(struct acpi_device *acpi_device) 439 { 440 struct input_dev *jog_dev; 441 struct input_dev *key_dev; 442 int i; 443 int error; 444 445 /* don't run again if already initialized */ 446 if (atomic_add_return(1, &sony_laptop_input.users) > 1) 447 return 0; 448 449 /* kfifo */ 450 spin_lock_init(&sony_laptop_input.fifo_lock); 451 error = kfifo_alloc(&sony_laptop_input.fifo, 452 SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 453 if (error) { 454 pr_err("kfifo_alloc failed\n"); 455 goto err_dec_users; 456 } 457 458 timer_setup(&sony_laptop_input.release_key_timer, 459 do_sony_laptop_release_key, 0); 460 461 /* input keys */ 462 key_dev = input_allocate_device(); 463 if (!key_dev) { 464 error = -ENOMEM; 465 goto err_free_kfifo; 466 } 467 468 key_dev->name = "Sony Vaio Keys"; 469 key_dev->id.bustype = BUS_ISA; 470 key_dev->id.vendor = PCI_VENDOR_ID_SONY; 471 key_dev->dev.parent = &acpi_device->dev; 472 473 /* Initialize the Input Drivers: special keys */ 474 input_set_capability(key_dev, EV_MSC, MSC_SCAN); 475 476 __set_bit(EV_KEY, key_dev->evbit); 477 key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); 478 key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); 479 key_dev->keycode = &sony_laptop_input_keycode_map; 480 for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) 481 __set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit); 482 __clear_bit(KEY_RESERVED, key_dev->keybit); 483 484 error = input_register_device(key_dev); 485 if (error) 486 goto err_free_keydev; 487 488 sony_laptop_input.key_dev = key_dev; 489 490 /* jogdial */ 491 jog_dev = input_allocate_device(); 492 if (!jog_dev) { 493 error = -ENOMEM; 494 goto err_unregister_keydev; 495 } 496 497 jog_dev->name = "Sony Vaio Jogdial"; 498 jog_dev->id.bustype = BUS_ISA; 499 jog_dev->id.vendor = PCI_VENDOR_ID_SONY; 500 jog_dev->dev.parent = &acpi_device->dev; 501 502 input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE); 503 input_set_capability(jog_dev, EV_REL, REL_WHEEL); 504 505 error = input_register_device(jog_dev); 506 if (error) 507 goto err_free_jogdev; 508 509 sony_laptop_input.jog_dev = jog_dev; 510 511 return 0; 512 513 err_free_jogdev: 514 input_free_device(jog_dev); 515 516 err_unregister_keydev: 517 input_unregister_device(key_dev); 518 /* to avoid kref underflow below at input_free_device */ 519 key_dev = NULL; 520 521 err_free_keydev: 522 input_free_device(key_dev); 523 524 err_free_kfifo: 525 kfifo_free(&sony_laptop_input.fifo); 526 527 err_dec_users: 528 atomic_dec(&sony_laptop_input.users); 529 return error; 530 } 531 532 static void sony_laptop_remove_input(void) 533 { 534 struct sony_laptop_keypress kp = { NULL }; 535 536 /* Cleanup only after the last user has gone */ 537 if (!atomic_dec_and_test(&sony_laptop_input.users)) 538 return; 539 540 timer_delete_sync(&sony_laptop_input.release_key_timer); 541 542 /* 543 * Generate key-up events for remaining keys. Note that we don't 544 * need locking since nobody is adding new events to the kfifo. 545 */ 546 while (kfifo_out(&sony_laptop_input.fifo, 547 (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { 548 input_report_key(kp.dev, kp.key, 0); 549 input_sync(kp.dev); 550 } 551 552 /* destroy input devs */ 553 input_unregister_device(sony_laptop_input.key_dev); 554 sony_laptop_input.key_dev = NULL; 555 556 if (sony_laptop_input.jog_dev) { 557 input_unregister_device(sony_laptop_input.jog_dev); 558 sony_laptop_input.jog_dev = NULL; 559 } 560 561 kfifo_free(&sony_laptop_input.fifo); 562 } 563 564 /*********** Platform Device ***********/ 565 566 static atomic_t sony_pf_users = ATOMIC_INIT(0); 567 static struct platform_driver sony_pf_driver = { 568 .driver = { 569 .name = "sony-laptop", 570 } 571 }; 572 static struct platform_device *sony_pf_device; 573 574 static int sony_pf_add(void) 575 { 576 int ret = 0; 577 578 /* don't run again if already initialized */ 579 if (atomic_add_return(1, &sony_pf_users) > 1) 580 return 0; 581 582 ret = platform_driver_register(&sony_pf_driver); 583 if (ret) 584 goto out; 585 586 sony_pf_device = platform_device_alloc("sony-laptop", PLATFORM_DEVID_NONE); 587 if (!sony_pf_device) { 588 ret = -ENOMEM; 589 goto out_platform_registered; 590 } 591 592 ret = platform_device_add(sony_pf_device); 593 if (ret) 594 goto out_platform_alloced; 595 596 return 0; 597 598 out_platform_alloced: 599 platform_device_put(sony_pf_device); 600 sony_pf_device = NULL; 601 out_platform_registered: 602 platform_driver_unregister(&sony_pf_driver); 603 out: 604 atomic_dec(&sony_pf_users); 605 return ret; 606 } 607 608 static void sony_pf_remove(void) 609 { 610 /* deregister only after the last user has gone */ 611 if (!atomic_dec_and_test(&sony_pf_users)) 612 return; 613 614 platform_device_unregister(sony_pf_device); 615 platform_driver_unregister(&sony_pf_driver); 616 } 617 618 /*********** SNC (SNY5001) Device ***********/ 619 620 /* the device uses 1-based values, while the backlight subsystem uses 621 0-based values */ 622 #define SONY_MAX_BRIGHTNESS 8 623 624 #define SNC_VALIDATE_IN 0 625 #define SNC_VALIDATE_OUT 1 626 627 static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *, 628 char *); 629 static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *, 630 const char *, size_t); 631 static int boolean_validate(const int, const int); 632 static int brightness_default_validate(const int, const int); 633 634 struct sony_nc_value { 635 char *name; /* name of the entry */ 636 char **acpiget; /* names of the ACPI get function */ 637 char **acpiset; /* names of the ACPI set function */ 638 int (*validate)(const int, const int); /* input/output validation */ 639 int value; /* current setting */ 640 int valid; /* Has ever been set */ 641 int debug; /* active only in debug mode ? */ 642 struct device_attribute devattr; /* sysfs attribute */ 643 }; 644 645 #define SNC_HANDLE_NAMES(_name, _values...) \ 646 static char *snc_##_name[] = { _values, NULL } 647 648 #define SNC_HANDLE(_name, _getters, _setters, _validate, _debug) \ 649 { \ 650 .name = __stringify(_name), \ 651 .acpiget = _getters, \ 652 .acpiset = _setters, \ 653 .validate = _validate, \ 654 .debug = _debug, \ 655 .devattr = __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \ 656 } 657 658 #define SNC_HANDLE_NULL { .name = NULL } 659 660 SNC_HANDLE_NAMES(fnkey_get, "GHKE"); 661 662 SNC_HANDLE_NAMES(brightness_def_get, "GPBR"); 663 SNC_HANDLE_NAMES(brightness_def_set, "SPBR"); 664 665 SNC_HANDLE_NAMES(cdpower_get, "GCDP"); 666 SNC_HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); 667 668 SNC_HANDLE_NAMES(audiopower_get, "GAZP"); 669 SNC_HANDLE_NAMES(audiopower_set, "AZPW"); 670 671 SNC_HANDLE_NAMES(lanpower_get, "GLNP"); 672 SNC_HANDLE_NAMES(lanpower_set, "LNPW"); 673 674 SNC_HANDLE_NAMES(lidstate_get, "GLID"); 675 676 SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); 677 SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); 678 679 SNC_HANDLE_NAMES(gainbass_get, "GMGB"); 680 SNC_HANDLE_NAMES(gainbass_set, "CMGB"); 681 682 SNC_HANDLE_NAMES(PID_get, "GPID"); 683 684 SNC_HANDLE_NAMES(CTR_get, "GCTR"); 685 SNC_HANDLE_NAMES(CTR_set, "SCTR"); 686 687 SNC_HANDLE_NAMES(PCR_get, "GPCR"); 688 SNC_HANDLE_NAMES(PCR_set, "SPCR"); 689 690 SNC_HANDLE_NAMES(CMI_get, "GCMI"); 691 SNC_HANDLE_NAMES(CMI_set, "SCMI"); 692 693 static struct sony_nc_value sony_nc_values[] = { 694 SNC_HANDLE(brightness_default, snc_brightness_def_get, 695 snc_brightness_def_set, brightness_default_validate, 0), 696 SNC_HANDLE(fnkey, snc_fnkey_get, NULL, NULL, 0), 697 SNC_HANDLE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0), 698 SNC_HANDLE(audiopower, snc_audiopower_get, snc_audiopower_set, 699 boolean_validate, 0), 700 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, 701 boolean_validate, 1), 702 SNC_HANDLE(lidstate, snc_lidstate_get, NULL, 703 boolean_validate, 0), 704 SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, 705 boolean_validate, 0), 706 SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, 707 boolean_validate, 0), 708 /* unknown methods */ 709 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), 710 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), 711 SNC_HANDLE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1), 712 SNC_HANDLE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1), 713 SNC_HANDLE_NULL 714 }; 715 716 static acpi_handle sony_nc_acpi_handle; 717 static struct acpi_device *sony_nc_acpi_device = NULL; 718 719 /* 720 * acpi_evaluate_object wrappers 721 * all useful calls into SNC methods take one or zero parameters and return 722 * integers or arrays. 723 */ 724 static union acpi_object *__call_snc_method(acpi_handle handle, char *method, 725 u64 *value) 726 { 727 union acpi_object *result = NULL; 728 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 729 acpi_status status; 730 731 if (value) { 732 struct acpi_object_list params; 733 union acpi_object in; 734 in.type = ACPI_TYPE_INTEGER; 735 in.integer.value = *value; 736 params.count = 1; 737 params.pointer = ∈ 738 status = acpi_evaluate_object(handle, method, ¶ms, &output); 739 dprintk("__call_snc_method: [%s:0x%.8x%.8x]\n", method, 740 (unsigned int)(*value >> 32), 741 (unsigned int)*value & 0xffffffff); 742 } else { 743 status = acpi_evaluate_object(handle, method, NULL, &output); 744 dprintk("__call_snc_method: [%s]\n", method); 745 } 746 747 if (ACPI_FAILURE(status)) { 748 pr_err("Failed to evaluate [%s]\n", method); 749 return NULL; 750 } 751 752 result = (union acpi_object *) output.pointer; 753 if (!result) 754 dprintk("No return object [%s]\n", method); 755 756 return result; 757 } 758 759 static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, 760 void *buffer, size_t buflen) 761 { 762 int ret = 0; 763 size_t len; 764 union acpi_object *object = __call_snc_method(handle, name, value); 765 766 if (!object) 767 return -EINVAL; 768 769 if (!buffer) { 770 /* do nothing */ 771 } else if (object->type == ACPI_TYPE_BUFFER) { 772 len = MIN(buflen, object->buffer.length); 773 memset(buffer, 0, buflen); 774 memcpy(buffer, object->buffer.pointer, len); 775 776 } else if (object->type == ACPI_TYPE_INTEGER) { 777 len = MIN(buflen, sizeof(object->integer.value)); 778 memset(buffer, 0, buflen); 779 memcpy(buffer, &object->integer.value, len); 780 781 } else { 782 pr_warn("Unexpected acpi_object: 0x%x\n", object->type); 783 ret = -EINVAL; 784 } 785 786 kfree(object); 787 return ret; 788 } 789 790 static int sony_nc_int_call(acpi_handle handle, char *name, int *value, int 791 *result) 792 { 793 int ret; 794 795 if (value) { 796 u64 v = *value; 797 798 ret = sony_nc_buffer_call(handle, name, &v, result, 799 sizeof(*result)); 800 } else { 801 ret = sony_nc_buffer_call(handle, name, NULL, result, 802 sizeof(*result)); 803 } 804 return ret; 805 } 806 807 struct sony_nc_handles { 808 u16 cap[0x10]; 809 struct device_attribute devattr; 810 }; 811 812 static struct sony_nc_handles *handles; 813 814 static ssize_t sony_nc_handles_show(struct device *dev, 815 struct device_attribute *attr, char *buffer) 816 { 817 ssize_t len = 0; 818 int i; 819 820 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 821 len += sysfs_emit_at(buffer, len, "0x%.4x ", handles->cap[i]); 822 } 823 len += sysfs_emit_at(buffer, len, "\n"); 824 825 return len; 826 } 827 828 static int sony_nc_handles_setup(struct platform_device *pd) 829 { 830 int i, r, result, arg; 831 832 handles = kzalloc(sizeof(*handles), GFP_KERNEL); 833 if (!handles) 834 return -ENOMEM; 835 836 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 837 arg = i + 0x20; 838 r = sony_nc_int_call(sony_nc_acpi_handle, "SN00", &arg, 839 &result); 840 if (!r) { 841 dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n", 842 result, i); 843 handles->cap[i] = result; 844 } 845 } 846 847 if (debug) { 848 sysfs_attr_init(&handles->devattr.attr); 849 handles->devattr.attr.name = "handles"; 850 handles->devattr.attr.mode = S_IRUGO; 851 handles->devattr.show = sony_nc_handles_show; 852 853 /* allow reading capabilities via sysfs */ 854 if (device_create_file(&pd->dev, &handles->devattr)) { 855 kfree(handles); 856 handles = NULL; 857 return -1; 858 } 859 } 860 861 return 0; 862 } 863 864 static int sony_nc_handles_cleanup(struct platform_device *pd) 865 { 866 if (handles) { 867 if (debug) 868 device_remove_file(&pd->dev, &handles->devattr); 869 kfree(handles); 870 handles = NULL; 871 } 872 return 0; 873 } 874 875 static int sony_find_snc_handle(int handle) 876 { 877 int i; 878 879 /* not initialized yet, return early */ 880 if (!handles || !handle) 881 return -EINVAL; 882 883 for (i = 0; i < 0x10; i++) { 884 if (handles->cap[i] == handle) { 885 dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", 886 handle, i); 887 return i; 888 } 889 } 890 dprintk("handle 0x%.4x not found\n", handle); 891 return -EINVAL; 892 } 893 894 static int sony_call_snc_handle(int handle, int argument, int *result) 895 { 896 int arg, ret = 0; 897 int offset = sony_find_snc_handle(handle); 898 899 if (offset < 0) 900 return offset; 901 902 arg = offset | argument; 903 ret = sony_nc_int_call(sony_nc_acpi_handle, "SN07", &arg, result); 904 dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", arg, *result); 905 return ret; 906 } 907 908 /* 909 * sony_nc_values input/output validate functions 910 */ 911 912 /* brightness_default_validate: 913 * 914 * manipulate input output values to keep consistency with the 915 * backlight framework for which brightness values are 0-based. 916 */ 917 static int brightness_default_validate(const int direction, const int value) 918 { 919 switch (direction) { 920 case SNC_VALIDATE_OUT: 921 return value - 1; 922 case SNC_VALIDATE_IN: 923 if (value >= 0 && value < SONY_MAX_BRIGHTNESS) 924 return value + 1; 925 } 926 return -EINVAL; 927 } 928 929 /* boolean_validate: 930 * 931 * on input validate boolean values 0/1, on output just pass the 932 * received value. 933 */ 934 static int boolean_validate(const int direction, const int value) 935 { 936 if (direction == SNC_VALIDATE_IN) { 937 if (value != 0 && value != 1) 938 return -EINVAL; 939 } 940 return value; 941 } 942 943 /* 944 * Sysfs show/store common to all sony_nc_values 945 */ 946 static ssize_t sony_nc_sysfs_show(struct device *dev, struct device_attribute *attr, 947 char *buffer) 948 { 949 int value, ret = 0; 950 struct sony_nc_value *item = 951 container_of(attr, struct sony_nc_value, devattr); 952 953 if (!*item->acpiget) 954 return -EIO; 955 956 ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiget, NULL, 957 &value); 958 if (ret < 0) 959 return -EIO; 960 961 if (item->validate) 962 value = item->validate(SNC_VALIDATE_OUT, value); 963 964 return sysfs_emit(buffer, "%d\n", value); 965 } 966 967 static ssize_t sony_nc_sysfs_store(struct device *dev, 968 struct device_attribute *attr, 969 const char *buffer, size_t count) 970 { 971 int value; 972 int ret = 0; 973 struct sony_nc_value *item = 974 container_of(attr, struct sony_nc_value, devattr); 975 976 if (!item->acpiset) 977 return -EIO; 978 979 if (count > 31) 980 return -EINVAL; 981 982 if (kstrtoint(buffer, 10, &value)) 983 return -EINVAL; 984 985 if (item->validate) 986 value = item->validate(SNC_VALIDATE_IN, value); 987 988 if (value < 0) 989 return value; 990 991 ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, 992 &value, NULL); 993 if (ret < 0) 994 return -EIO; 995 996 item->value = value; 997 item->valid = 1; 998 return count; 999 } 1000 1001 1002 /* 1003 * Backlight device 1004 */ 1005 struct sony_backlight_props { 1006 struct backlight_device *dev; 1007 int handle; 1008 int cmd_base; 1009 u8 offset; 1010 u8 maxlvl; 1011 }; 1012 static struct sony_backlight_props sony_bl_props; 1013 1014 static int sony_backlight_update_status(struct backlight_device *bd) 1015 { 1016 int arg = bd->props.brightness + 1; 1017 return sony_nc_int_call(sony_nc_acpi_handle, "SBRT", &arg, NULL); 1018 } 1019 1020 static int sony_backlight_get_brightness(struct backlight_device *bd) 1021 { 1022 int value; 1023 1024 if (sony_nc_int_call(sony_nc_acpi_handle, "GBRT", NULL, &value)) 1025 return 0; 1026 /* brightness levels are 1-based, while backlight ones are 0-based */ 1027 return value - 1; 1028 } 1029 1030 static int sony_nc_get_brightness_ng(struct backlight_device *bd) 1031 { 1032 int result; 1033 struct sony_backlight_props *sdev = 1034 (struct sony_backlight_props *)bl_get_data(bd); 1035 1036 sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result); 1037 1038 return (result & 0xff) - sdev->offset; 1039 } 1040 1041 static int sony_nc_update_status_ng(struct backlight_device *bd) 1042 { 1043 int value, result; 1044 struct sony_backlight_props *sdev = 1045 (struct sony_backlight_props *)bl_get_data(bd); 1046 1047 value = bd->props.brightness + sdev->offset; 1048 if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10), 1049 &result)) 1050 return -EIO; 1051 1052 return value; 1053 } 1054 1055 static const struct backlight_ops sony_backlight_ops = { 1056 .options = BL_CORE_SUSPENDRESUME, 1057 .update_status = sony_backlight_update_status, 1058 .get_brightness = sony_backlight_get_brightness, 1059 }; 1060 static const struct backlight_ops sony_backlight_ng_ops = { 1061 .options = BL_CORE_SUSPENDRESUME, 1062 .update_status = sony_nc_update_status_ng, 1063 .get_brightness = sony_nc_get_brightness_ng, 1064 }; 1065 1066 /* 1067 * New SNC-only Vaios event mapping to driver known keys 1068 */ 1069 struct sony_nc_event { 1070 u8 data; 1071 u8 event; 1072 }; 1073 1074 static struct sony_nc_event sony_100_events[] = { 1075 { 0x90, SONYPI_EVENT_PKEY_P1 }, 1076 { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1077 { 0x91, SONYPI_EVENT_PKEY_P2 }, 1078 { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1079 { 0x81, SONYPI_EVENT_FNKEY_F1 }, 1080 { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, 1081 { 0x82, SONYPI_EVENT_FNKEY_F2 }, 1082 { 0x02, SONYPI_EVENT_FNKEY_RELEASED }, 1083 { 0x83, SONYPI_EVENT_FNKEY_F3 }, 1084 { 0x03, SONYPI_EVENT_FNKEY_RELEASED }, 1085 { 0x84, SONYPI_EVENT_FNKEY_F4 }, 1086 { 0x04, SONYPI_EVENT_FNKEY_RELEASED }, 1087 { 0x85, SONYPI_EVENT_FNKEY_F5 }, 1088 { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, 1089 { 0x86, SONYPI_EVENT_FNKEY_F6 }, 1090 { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, 1091 { 0x87, SONYPI_EVENT_FNKEY_F7 }, 1092 { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, 1093 { 0x88, SONYPI_EVENT_FNKEY_F8 }, 1094 { 0x08, SONYPI_EVENT_FNKEY_RELEASED }, 1095 { 0x89, SONYPI_EVENT_FNKEY_F9 }, 1096 { 0x09, SONYPI_EVENT_FNKEY_RELEASED }, 1097 { 0x8A, SONYPI_EVENT_FNKEY_F10 }, 1098 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, 1099 { 0x8B, SONYPI_EVENT_FNKEY_F11 }, 1100 { 0x0B, SONYPI_EVENT_FNKEY_RELEASED }, 1101 { 0x8C, SONYPI_EVENT_FNKEY_F12 }, 1102 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, 1103 { 0x9d, SONYPI_EVENT_ZOOM_PRESSED }, 1104 { 0x1d, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1105 { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, 1106 { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1107 { 0xa1, SONYPI_EVENT_MEDIA_PRESSED }, 1108 { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1109 { 0xa4, SONYPI_EVENT_CD_EJECT_PRESSED }, 1110 { 0x24, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1111 { 0xa5, SONYPI_EVENT_VENDOR_PRESSED }, 1112 { 0x25, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1113 { 0xa6, SONYPI_EVENT_HELP_PRESSED }, 1114 { 0x26, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1115 { 0xa8, SONYPI_EVENT_FNKEY_1 }, 1116 { 0x28, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1117 { 0, 0 }, 1118 }; 1119 1120 static struct sony_nc_event sony_127_events[] = { 1121 { 0x81, SONYPI_EVENT_MODEKEY_PRESSED }, 1122 { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1123 { 0x82, SONYPI_EVENT_PKEY_P1 }, 1124 { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1125 { 0x83, SONYPI_EVENT_PKEY_P2 }, 1126 { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1127 { 0x84, SONYPI_EVENT_PKEY_P3 }, 1128 { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1129 { 0x85, SONYPI_EVENT_PKEY_P4 }, 1130 { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1131 { 0x86, SONYPI_EVENT_PKEY_P5 }, 1132 { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1133 { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED }, 1134 { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1135 { 0, 0 }, 1136 }; 1137 1138 static int sony_nc_hotkeys_decode(u32 event, unsigned int handle) 1139 { 1140 int ret = -EINVAL; 1141 unsigned int result = 0; 1142 struct sony_nc_event *key_event; 1143 1144 if (sony_call_snc_handle(handle, 0x200, &result)) { 1145 dprintk("Unable to decode event 0x%.2x 0x%.2x\n", handle, 1146 event); 1147 return -EINVAL; 1148 } 1149 1150 result &= 0xFF; 1151 1152 if (handle == 0x0100) 1153 key_event = sony_100_events; 1154 else 1155 key_event = sony_127_events; 1156 1157 for (; key_event->data; key_event++) { 1158 if (key_event->data == result) { 1159 ret = key_event->event; 1160 break; 1161 } 1162 } 1163 1164 if (!key_event->data) 1165 pr_info("Unknown hotkey 0x%.2x/0x%.2x (handle 0x%.2x)\n", 1166 event, result, handle); 1167 1168 return ret; 1169 } 1170 1171 /* 1172 * ACPI callbacks 1173 */ 1174 enum event_types { 1175 HOTKEY = 1, 1176 KILLSWITCH, 1177 GFX_SWITCH 1178 }; 1179 static void sony_nc_notify(struct acpi_device *device, u32 event) 1180 { 1181 u32 real_ev = event; 1182 u8 ev_type = 0; 1183 int ret; 1184 1185 dprintk("sony_nc_notify, event: 0x%.2x\n", event); 1186 1187 if (event >= 0x90) { 1188 unsigned int result = 0; 1189 unsigned int arg = 0; 1190 unsigned int handle = 0; 1191 unsigned int offset = event - 0x90; 1192 1193 if (offset >= ARRAY_SIZE(handles->cap)) { 1194 pr_err("Event 0x%x outside of capabilities list\n", 1195 event); 1196 return; 1197 } 1198 handle = handles->cap[offset]; 1199 1200 /* list of handles known for generating events */ 1201 switch (handle) { 1202 /* hotkey event */ 1203 case 0x0100: 1204 case 0x0127: 1205 ev_type = HOTKEY; 1206 ret = sony_nc_hotkeys_decode(event, handle); 1207 1208 if (ret > 0) { 1209 sony_laptop_report_input_event(ret); 1210 real_ev = ret; 1211 } 1212 1213 break; 1214 1215 /* wlan switch */ 1216 case 0x0124: 1217 case 0x0135: 1218 /* events on this handle are reported when the 1219 * switch changes position or for battery 1220 * events. We'll notify both of them but only 1221 * update the rfkill device status when the 1222 * switch is moved. 1223 */ 1224 ev_type = KILLSWITCH; 1225 sony_call_snc_handle(handle, 0x0100, &result); 1226 real_ev = result & 0x03; 1227 1228 /* hw switch event */ 1229 if (real_ev == 1) 1230 sony_nc_rfkill_update(); 1231 1232 break; 1233 1234 case 0x0128: 1235 case 0x0146: 1236 /* Hybrid GFX switching */ 1237 sony_call_snc_handle(handle, 0x0000, &result); 1238 dprintk("GFX switch event received (reason: %s)\n", 1239 (result == 0x1) ? "switch change" : 1240 (result == 0x2) ? "output switch" : 1241 (result == 0x3) ? "output switch" : 1242 ""); 1243 1244 ev_type = GFX_SWITCH; 1245 real_ev = __sony_nc_gfx_switch_status_get(); 1246 break; 1247 1248 case 0x015B: 1249 /* Hybrid GFX switching SVS151290S */ 1250 ev_type = GFX_SWITCH; 1251 real_ev = __sony_nc_gfx_switch_status_get(); 1252 break; 1253 default: 1254 dprintk("Unknown event 0x%x for handle 0x%x\n", 1255 event, handle); 1256 break; 1257 } 1258 1259 /* clear the event (and the event reason when present) */ 1260 arg = 1 << offset; 1261 sony_nc_int_call(sony_nc_acpi_handle, "SN05", &arg, &result); 1262 1263 } else { 1264 /* old style event */ 1265 ev_type = HOTKEY; 1266 sony_laptop_report_input_event(real_ev); 1267 } 1268 acpi_bus_generate_netlink_event(sony_nc_acpi_device->pnp.device_class, 1269 dev_name(&sony_nc_acpi_device->dev), ev_type, real_ev); 1270 } 1271 1272 static acpi_status sony_walk_callback(acpi_handle handle, u32 level, 1273 void *context, void **return_value) 1274 { 1275 struct acpi_device_info *info; 1276 1277 if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { 1278 pr_warn("method: name: %4.4s, args %X\n", 1279 (char *)&info->name, info->param_count); 1280 1281 kfree(info); 1282 } 1283 1284 return AE_OK; 1285 } 1286 1287 /* 1288 * ACPI device 1289 */ 1290 static void sony_nc_function_setup(struct acpi_device *device, 1291 struct platform_device *pf_device) 1292 { 1293 unsigned int i, result, bitmask, arg; 1294 1295 if (!handles) 1296 return; 1297 1298 /* setup found handles here */ 1299 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 1300 unsigned int handle = handles->cap[i]; 1301 1302 if (!handle) 1303 continue; 1304 1305 dprintk("setting up handle 0x%.4x\n", handle); 1306 1307 switch (handle) { 1308 case 0x0100: 1309 case 0x0101: 1310 case 0x0127: 1311 /* setup hotkeys */ 1312 sony_call_snc_handle(handle, 0, &result); 1313 break; 1314 case 0x0102: 1315 /* setup hotkeys */ 1316 sony_call_snc_handle(handle, 0x100, &result); 1317 break; 1318 case 0x0105: 1319 case 0x0148: 1320 /* touchpad enable/disable */ 1321 result = sony_nc_touchpad_setup(pf_device, handle); 1322 if (result) 1323 pr_err("couldn't set up touchpad control function (%d)\n", 1324 result); 1325 break; 1326 case 0x0115: 1327 case 0x0136: 1328 case 0x013f: 1329 result = sony_nc_battery_care_setup(pf_device, handle); 1330 if (result) 1331 pr_err("couldn't set up battery care function (%d)\n", 1332 result); 1333 break; 1334 case 0x0119: 1335 case 0x015D: 1336 result = sony_nc_lid_resume_setup(pf_device, handle); 1337 if (result) 1338 pr_err("couldn't set up lid resume function (%d)\n", 1339 result); 1340 break; 1341 case 0x0122: 1342 result = sony_nc_thermal_setup(pf_device); 1343 if (result) 1344 pr_err("couldn't set up thermal profile function (%d)\n", 1345 result); 1346 break; 1347 case 0x0128: 1348 case 0x0146: 1349 case 0x015B: 1350 result = sony_nc_gfx_switch_setup(pf_device, handle); 1351 if (result) 1352 pr_err("couldn't set up GFX Switch status (%d)\n", 1353 result); 1354 break; 1355 case 0x0131: 1356 result = sony_nc_highspeed_charging_setup(pf_device); 1357 if (result) 1358 pr_err("couldn't set up high speed charging function (%d)\n", 1359 result); 1360 break; 1361 case 0x0124: 1362 case 0x0135: 1363 result = sony_nc_rfkill_setup(device, handle); 1364 if (result) 1365 pr_err("couldn't set up rfkill support (%d)\n", 1366 result); 1367 break; 1368 case 0x0137: 1369 case 0x0143: 1370 case 0x014b: 1371 case 0x014c: 1372 case 0x0153: 1373 case 0x0163: 1374 result = sony_nc_kbd_backlight_setup(pf_device, handle); 1375 if (result) 1376 pr_err("couldn't set up keyboard backlight function (%d)\n", 1377 result); 1378 break; 1379 case 0x0121: 1380 result = sony_nc_lowbatt_setup(pf_device); 1381 if (result) 1382 pr_err("couldn't set up low battery function (%d)\n", 1383 result); 1384 break; 1385 case 0x0149: 1386 result = sony_nc_fanspeed_setup(pf_device); 1387 if (result) 1388 pr_err("couldn't set up fan speed function (%d)\n", 1389 result); 1390 break; 1391 case 0x0155: 1392 result = sony_nc_usb_charge_setup(pf_device); 1393 if (result) 1394 pr_err("couldn't set up USB charge support (%d)\n", 1395 result); 1396 break; 1397 case 0x011D: 1398 result = sony_nc_panelid_setup(pf_device); 1399 if (result) 1400 pr_err("couldn't set up panel ID function (%d)\n", 1401 result); 1402 break; 1403 case 0x0168: 1404 result = sony_nc_smart_conn_setup(pf_device); 1405 if (result) 1406 pr_err("couldn't set up smart connect support (%d)\n", 1407 result); 1408 break; 1409 default: 1410 continue; 1411 } 1412 } 1413 1414 /* Enable all events */ 1415 arg = 0x10; 1416 if (!sony_nc_int_call(sony_nc_acpi_handle, "SN00", &arg, &bitmask)) 1417 sony_nc_int_call(sony_nc_acpi_handle, "SN02", &bitmask, 1418 &result); 1419 } 1420 1421 static void sony_nc_function_cleanup(struct platform_device *pd) 1422 { 1423 unsigned int i, result, bitmask, handle; 1424 1425 if (!handles) 1426 return; 1427 1428 /* get enabled events and disable them */ 1429 sony_nc_int_call(sony_nc_acpi_handle, "SN01", NULL, &bitmask); 1430 sony_nc_int_call(sony_nc_acpi_handle, "SN03", &bitmask, &result); 1431 1432 /* cleanup handles here */ 1433 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 1434 1435 handle = handles->cap[i]; 1436 1437 if (!handle) 1438 continue; 1439 1440 switch (handle) { 1441 case 0x0105: 1442 case 0x0148: 1443 sony_nc_touchpad_cleanup(pd); 1444 break; 1445 case 0x0115: 1446 case 0x0136: 1447 case 0x013f: 1448 sony_nc_battery_care_cleanup(pd); 1449 break; 1450 case 0x0119: 1451 case 0x015D: 1452 sony_nc_lid_resume_cleanup(pd); 1453 break; 1454 case 0x0122: 1455 sony_nc_thermal_cleanup(pd); 1456 break; 1457 case 0x0128: 1458 case 0x0146: 1459 case 0x015B: 1460 sony_nc_gfx_switch_cleanup(pd); 1461 break; 1462 case 0x0131: 1463 sony_nc_highspeed_charging_cleanup(pd); 1464 break; 1465 case 0x0124: 1466 case 0x0135: 1467 sony_nc_rfkill_cleanup(); 1468 break; 1469 case 0x0137: 1470 case 0x0143: 1471 case 0x014b: 1472 case 0x014c: 1473 case 0x0153: 1474 case 0x0163: 1475 sony_nc_kbd_backlight_cleanup(pd, handle); 1476 break; 1477 case 0x0121: 1478 sony_nc_lowbatt_cleanup(pd); 1479 break; 1480 case 0x0149: 1481 sony_nc_fanspeed_cleanup(pd); 1482 break; 1483 case 0x0155: 1484 sony_nc_usb_charge_cleanup(pd); 1485 break; 1486 case 0x011D: 1487 sony_nc_panelid_cleanup(pd); 1488 break; 1489 case 0x0168: 1490 sony_nc_smart_conn_cleanup(pd); 1491 break; 1492 default: 1493 continue; 1494 } 1495 } 1496 1497 /* finally cleanup the handles list */ 1498 sony_nc_handles_cleanup(pd); 1499 } 1500 1501 #ifdef CONFIG_PM_SLEEP 1502 static void sony_nc_function_resume(void) 1503 { 1504 unsigned int i, result, bitmask, arg; 1505 1506 dprintk("Resuming SNC device\n"); 1507 1508 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 1509 unsigned int handle = handles->cap[i]; 1510 1511 if (!handle) 1512 continue; 1513 1514 switch (handle) { 1515 case 0x0100: 1516 case 0x0101: 1517 case 0x0127: 1518 /* re-enable hotkeys */ 1519 sony_call_snc_handle(handle, 0, &result); 1520 break; 1521 case 0x0102: 1522 /* re-enable hotkeys */ 1523 sony_call_snc_handle(handle, 0x100, &result); 1524 break; 1525 case 0x0122: 1526 sony_nc_thermal_resume(); 1527 break; 1528 case 0x0124: 1529 case 0x0135: 1530 sony_nc_rfkill_update(); 1531 break; 1532 default: 1533 continue; 1534 } 1535 } 1536 1537 /* Enable all events */ 1538 arg = 0x10; 1539 if (!sony_nc_int_call(sony_nc_acpi_handle, "SN00", &arg, &bitmask)) 1540 sony_nc_int_call(sony_nc_acpi_handle, "SN02", &bitmask, 1541 &result); 1542 } 1543 1544 static int sony_nc_resume(struct device *dev) 1545 { 1546 struct sony_nc_value *item; 1547 1548 for (item = sony_nc_values; item->name; item++) { 1549 int ret; 1550 1551 if (!item->valid) 1552 continue; 1553 ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, 1554 &item->value, NULL); 1555 if (ret < 0) { 1556 pr_err("%s: %d\n", __func__, ret); 1557 break; 1558 } 1559 } 1560 1561 if (acpi_has_method(sony_nc_acpi_handle, "ECON")) { 1562 int arg = 1; 1563 if (sony_nc_int_call(sony_nc_acpi_handle, "ECON", &arg, NULL)) 1564 dprintk("ECON Method failed\n"); 1565 } 1566 1567 if (acpi_has_method(sony_nc_acpi_handle, "SN00")) 1568 sony_nc_function_resume(); 1569 1570 return 0; 1571 } 1572 #endif 1573 1574 static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); 1575 1576 static void sony_nc_rfkill_cleanup(void) 1577 { 1578 int i; 1579 1580 for (i = 0; i < N_SONY_RFKILL; i++) { 1581 if (sony_rfkill_devices[i]) { 1582 rfkill_unregister(sony_rfkill_devices[i]); 1583 rfkill_destroy(sony_rfkill_devices[i]); 1584 } 1585 } 1586 } 1587 1588 static int sony_nc_rfkill_set(void *data, bool blocked) 1589 { 1590 int result; 1591 int argument = sony_rfkill_address[(long) data] + 0x100; 1592 1593 if (!blocked) 1594 argument |= 0x070000; 1595 1596 return sony_call_snc_handle(sony_rfkill_handle, argument, &result); 1597 } 1598 1599 static const struct rfkill_ops sony_rfkill_ops = { 1600 .set_block = sony_nc_rfkill_set, 1601 }; 1602 1603 static int sony_nc_setup_rfkill(struct acpi_device *device, 1604 enum sony_nc_rfkill nc_type) 1605 { 1606 int err; 1607 struct rfkill *rfk; 1608 enum rfkill_type type; 1609 const char *name; 1610 int result; 1611 bool hwblock, swblock; 1612 1613 switch (nc_type) { 1614 case SONY_WIFI: 1615 type = RFKILL_TYPE_WLAN; 1616 name = "sony-wifi"; 1617 break; 1618 case SONY_BLUETOOTH: 1619 type = RFKILL_TYPE_BLUETOOTH; 1620 name = "sony-bluetooth"; 1621 break; 1622 case SONY_WWAN: 1623 type = RFKILL_TYPE_WWAN; 1624 name = "sony-wwan"; 1625 break; 1626 case SONY_WIMAX: 1627 type = RFKILL_TYPE_WIMAX; 1628 name = "sony-wimax"; 1629 break; 1630 default: 1631 return -EINVAL; 1632 } 1633 1634 rfk = rfkill_alloc(name, &device->dev, type, 1635 &sony_rfkill_ops, (void *)nc_type); 1636 if (!rfk) 1637 return -ENOMEM; 1638 1639 err = sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); 1640 if (err < 0) { 1641 rfkill_destroy(rfk); 1642 return err; 1643 } 1644 hwblock = !(result & 0x1); 1645 1646 err = sony_call_snc_handle(sony_rfkill_handle, 1647 sony_rfkill_address[nc_type], 1648 &result); 1649 if (err < 0) { 1650 rfkill_destroy(rfk); 1651 return err; 1652 } 1653 swblock = !(result & 0x2); 1654 1655 rfkill_init_sw_state(rfk, swblock); 1656 rfkill_set_hw_state(rfk, hwblock); 1657 1658 err = rfkill_register(rfk); 1659 if (err) { 1660 rfkill_destroy(rfk); 1661 return err; 1662 } 1663 sony_rfkill_devices[nc_type] = rfk; 1664 return err; 1665 } 1666 1667 static void sony_nc_rfkill_update(void) 1668 { 1669 enum sony_nc_rfkill i; 1670 int result; 1671 bool hwblock; 1672 1673 sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); 1674 hwblock = !(result & 0x1); 1675 1676 for (i = 0; i < N_SONY_RFKILL; i++) { 1677 int argument = sony_rfkill_address[i]; 1678 1679 if (!sony_rfkill_devices[i]) 1680 continue; 1681 1682 if (hwblock) { 1683 if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) { 1684 /* we already know we're blocked */ 1685 } 1686 continue; 1687 } 1688 1689 sony_call_snc_handle(sony_rfkill_handle, argument, &result); 1690 rfkill_set_states(sony_rfkill_devices[i], 1691 !(result & 0x2), false); 1692 } 1693 } 1694 1695 static int sony_nc_rfkill_setup(struct acpi_device *device, 1696 unsigned int handle) 1697 { 1698 u64 offset; 1699 int i; 1700 unsigned char buffer[32] = { 0 }; 1701 1702 offset = sony_find_snc_handle(handle); 1703 sony_rfkill_handle = handle; 1704 1705 i = sony_nc_buffer_call(sony_nc_acpi_handle, "SN06", &offset, buffer, 1706 32); 1707 if (i < 0) 1708 return i; 1709 1710 /* The buffer is filled with magic numbers describing the devices 1711 * available, 0xff terminates the enumeration. 1712 * Known codes: 1713 * 0x00 WLAN 1714 * 0x10 BLUETOOTH 1715 * 0x20 WWAN GPRS-EDGE 1716 * 0x21 WWAN HSDPA 1717 * 0x22 WWAN EV-DO 1718 * 0x23 WWAN GPS 1719 * 0x25 Gobi WWAN no GPS 1720 * 0x26 Gobi WWAN + GPS 1721 * 0x28 Gobi WWAN no GPS 1722 * 0x29 Gobi WWAN + GPS 1723 * 0x30 WIMAX 1724 * 0x50 Gobi WWAN no GPS 1725 * 0x51 Gobi WWAN + GPS 1726 * 0x70 no SIM card slot 1727 * 0x71 SIM card slot 1728 */ 1729 for (i = 0; i < ARRAY_SIZE(buffer); i++) { 1730 1731 if (buffer[i] == 0xff) 1732 break; 1733 1734 dprintk("Radio devices, found 0x%.2x\n", buffer[i]); 1735 1736 if (buffer[i] == 0 && !sony_rfkill_devices[SONY_WIFI]) 1737 sony_nc_setup_rfkill(device, SONY_WIFI); 1738 1739 if (buffer[i] == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH]) 1740 sony_nc_setup_rfkill(device, SONY_BLUETOOTH); 1741 1742 if (((0xf0 & buffer[i]) == 0x20 || 1743 (0xf0 & buffer[i]) == 0x50) && 1744 !sony_rfkill_devices[SONY_WWAN]) 1745 sony_nc_setup_rfkill(device, SONY_WWAN); 1746 1747 if (buffer[i] == 0x30 && !sony_rfkill_devices[SONY_WIMAX]) 1748 sony_nc_setup_rfkill(device, SONY_WIMAX); 1749 } 1750 return 0; 1751 } 1752 1753 /* Keyboard backlight feature */ 1754 struct kbd_backlight { 1755 unsigned int handle; 1756 unsigned int base; 1757 unsigned int mode; 1758 unsigned int timeout; 1759 unsigned int has_timeout; 1760 struct device_attribute mode_attr; 1761 struct device_attribute timeout_attr; 1762 }; 1763 1764 static struct kbd_backlight *kbdbl_ctl; 1765 1766 static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value) 1767 { 1768 int result; 1769 1770 if (value > 2) 1771 return -EINVAL; 1772 1773 if (sony_call_snc_handle(kbdbl_ctl->handle, 1774 (value << 0x10) | (kbdbl_ctl->base), &result)) 1775 return -EIO; 1776 1777 /* Try to turn the light on/off immediately */ 1778 if (value != 1) 1779 sony_call_snc_handle(kbdbl_ctl->handle, 1780 (value << 0x0f) | (kbdbl_ctl->base + 0x100), 1781 &result); 1782 1783 kbdbl_ctl->mode = value; 1784 1785 return 0; 1786 } 1787 1788 static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev, 1789 struct device_attribute *attr, 1790 const char *buffer, size_t count) 1791 { 1792 int ret = 0; 1793 unsigned long value; 1794 1795 if (count > 31) 1796 return -EINVAL; 1797 1798 if (kstrtoul(buffer, 10, &value)) 1799 return -EINVAL; 1800 1801 ret = __sony_nc_kbd_backlight_mode_set(value); 1802 if (ret < 0) 1803 return ret; 1804 1805 return count; 1806 } 1807 1808 static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev, 1809 struct device_attribute *attr, char *buffer) 1810 { 1811 return sysfs_emit(buffer, "%d\n", kbdbl_ctl->mode); 1812 } 1813 1814 static int __sony_nc_kbd_backlight_timeout_set(u8 value) 1815 { 1816 int result; 1817 1818 if (value > 3) 1819 return -EINVAL; 1820 1821 if (sony_call_snc_handle(kbdbl_ctl->handle, (value << 0x10) | 1822 (kbdbl_ctl->base + 0x200), &result)) 1823 return -EIO; 1824 1825 kbdbl_ctl->timeout = value; 1826 1827 return 0; 1828 } 1829 1830 static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev, 1831 struct device_attribute *attr, 1832 const char *buffer, size_t count) 1833 { 1834 int ret = 0; 1835 unsigned long value; 1836 1837 if (count > 31) 1838 return -EINVAL; 1839 1840 if (kstrtoul(buffer, 10, &value)) 1841 return -EINVAL; 1842 1843 ret = __sony_nc_kbd_backlight_timeout_set(value); 1844 if (ret < 0) 1845 return ret; 1846 1847 return count; 1848 } 1849 1850 static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev, 1851 struct device_attribute *attr, char *buffer) 1852 { 1853 return sysfs_emit(buffer, "%d\n", kbdbl_ctl->timeout); 1854 } 1855 1856 static int sony_nc_kbd_backlight_setup(struct platform_device *pd, 1857 unsigned int handle) 1858 { 1859 int result; 1860 int probe_base = 0; 1861 int ctl_base = 0; 1862 int ret = 0; 1863 1864 if (kbdbl_ctl) { 1865 pr_warn("handle 0x%.4x: keyboard backlight setup already done for 0x%.4x\n", 1866 handle, kbdbl_ctl->handle); 1867 return -EBUSY; 1868 } 1869 1870 /* verify the kbd backlight presence, some of these handles are not used 1871 * for keyboard backlight only 1872 */ 1873 switch (handle) { 1874 case 0x0153: 1875 probe_base = 0x0; 1876 ctl_base = 0x0; 1877 break; 1878 case 0x0137: 1879 probe_base = 0x0B00; 1880 ctl_base = 0x0C00; 1881 break; 1882 default: 1883 probe_base = 0x0100; 1884 ctl_base = 0x4000; 1885 break; 1886 } 1887 1888 /* 1889 * Only probe if there is a separate probe_base, otherwise the probe call 1890 * is equivalent to __sony_nc_kbd_backlight_mode_set(0), resulting in 1891 * the keyboard backlight being turned off. 1892 */ 1893 if (probe_base) { 1894 ret = sony_call_snc_handle(handle, probe_base, &result); 1895 if (ret) 1896 return ret; 1897 1898 if ((handle == 0x0137 && !(result & 0x02)) || 1899 !(result & 0x01)) { 1900 dprintk("no backlight keyboard found\n"); 1901 return 0; 1902 } 1903 } 1904 1905 kbdbl_ctl = kzalloc(sizeof(*kbdbl_ctl), GFP_KERNEL); 1906 if (!kbdbl_ctl) 1907 return -ENOMEM; 1908 1909 kbdbl_ctl->mode = kbd_backlight; 1910 kbdbl_ctl->timeout = kbd_backlight_timeout; 1911 kbdbl_ctl->handle = handle; 1912 kbdbl_ctl->base = ctl_base; 1913 /* Some models do not allow timeout control */ 1914 kbdbl_ctl->has_timeout = handle != 0x0153; 1915 1916 sysfs_attr_init(&kbdbl_ctl->mode_attr.attr); 1917 kbdbl_ctl->mode_attr.attr.name = "kbd_backlight"; 1918 kbdbl_ctl->mode_attr.attr.mode = S_IRUGO | S_IWUSR; 1919 kbdbl_ctl->mode_attr.show = sony_nc_kbd_backlight_mode_show; 1920 kbdbl_ctl->mode_attr.store = sony_nc_kbd_backlight_mode_store; 1921 1922 ret = device_create_file(&pd->dev, &kbdbl_ctl->mode_attr); 1923 if (ret) 1924 goto outkzalloc; 1925 1926 __sony_nc_kbd_backlight_mode_set(kbdbl_ctl->mode); 1927 1928 if (kbdbl_ctl->has_timeout) { 1929 sysfs_attr_init(&kbdbl_ctl->timeout_attr.attr); 1930 kbdbl_ctl->timeout_attr.attr.name = "kbd_backlight_timeout"; 1931 kbdbl_ctl->timeout_attr.attr.mode = S_IRUGO | S_IWUSR; 1932 kbdbl_ctl->timeout_attr.show = 1933 sony_nc_kbd_backlight_timeout_show; 1934 kbdbl_ctl->timeout_attr.store = 1935 sony_nc_kbd_backlight_timeout_store; 1936 1937 ret = device_create_file(&pd->dev, &kbdbl_ctl->timeout_attr); 1938 if (ret) 1939 goto outmode; 1940 1941 __sony_nc_kbd_backlight_timeout_set(kbdbl_ctl->timeout); 1942 } 1943 1944 1945 return 0; 1946 1947 outmode: 1948 device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr); 1949 outkzalloc: 1950 kfree(kbdbl_ctl); 1951 kbdbl_ctl = NULL; 1952 return ret; 1953 } 1954 1955 static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd, 1956 unsigned int handle) 1957 { 1958 if (kbdbl_ctl && handle == kbdbl_ctl->handle) { 1959 device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr); 1960 if (kbdbl_ctl->has_timeout) 1961 device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr); 1962 kfree(kbdbl_ctl); 1963 kbdbl_ctl = NULL; 1964 } 1965 } 1966 1967 struct battery_care_control { 1968 struct device_attribute attrs[2]; 1969 unsigned int handle; 1970 }; 1971 static struct battery_care_control *bcare_ctl; 1972 1973 static ssize_t sony_nc_battery_care_limit_store(struct device *dev, 1974 struct device_attribute *attr, 1975 const char *buffer, size_t count) 1976 { 1977 unsigned int result, cmd; 1978 unsigned long value; 1979 1980 if (count > 31) 1981 return -EINVAL; 1982 1983 if (kstrtoul(buffer, 10, &value)) 1984 return -EINVAL; 1985 1986 /* limit values (2 bits): 1987 * 00 - none 1988 * 01 - 80% 1989 * 10 - 50% 1990 * 11 - 100% 1991 * 1992 * bit 0: 0 disable BCL, 1 enable BCL 1993 * bit 1: 1 tell to store the battery limit (see bits 6,7) too 1994 * bits 2,3: reserved 1995 * bits 4,5: store the limit into the EC 1996 * bits 6,7: store the limit into the battery 1997 */ 1998 cmd = 0; 1999 2000 if (value > 0) { 2001 if (value <= 50) 2002 cmd = 0x20; 2003 2004 else if (value <= 80) 2005 cmd = 0x10; 2006 2007 else if (value <= 100) 2008 cmd = 0x30; 2009 2010 else 2011 return -EINVAL; 2012 2013 /* 2014 * handle 0x0115 should allow storing on battery too; 2015 * handle 0x0136 same as 0x0115 + health status; 2016 * handle 0x013f, same as 0x0136 but no storing on the battery 2017 */ 2018 if (bcare_ctl->handle != 0x013f) 2019 cmd = cmd | (cmd << 2); 2020 2021 cmd = (cmd | 0x1) << 0x10; 2022 } 2023 2024 if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result)) 2025 return -EIO; 2026 2027 return count; 2028 } 2029 2030 static ssize_t sony_nc_battery_care_limit_show(struct device *dev, 2031 struct device_attribute *attr, char *buffer) 2032 { 2033 unsigned int result, status; 2034 2035 if (sony_call_snc_handle(bcare_ctl->handle, 0x0000, &result)) 2036 return -EIO; 2037 2038 status = (result & 0x01) ? ((result & 0x30) >> 0x04) : 0; 2039 switch (status) { 2040 case 1: 2041 status = 80; 2042 break; 2043 case 2: 2044 status = 50; 2045 break; 2046 case 3: 2047 status = 100; 2048 break; 2049 default: 2050 status = 0; 2051 break; 2052 } 2053 2054 return sysfs_emit(buffer, "%d\n", status); 2055 } 2056 2057 static ssize_t sony_nc_battery_care_health_show(struct device *dev, 2058 struct device_attribute *attr, char *buffer) 2059 { 2060 unsigned int health; 2061 2062 if (sony_call_snc_handle(bcare_ctl->handle, 0x0200, &health)) 2063 return -EIO; 2064 2065 return sysfs_emit(buffer, "%d\n", health & 0xff); 2066 } 2067 2068 static int sony_nc_battery_care_setup(struct platform_device *pd, 2069 unsigned int handle) 2070 { 2071 int ret = 0; 2072 2073 bcare_ctl = kzalloc(sizeof(struct battery_care_control), GFP_KERNEL); 2074 if (!bcare_ctl) 2075 return -ENOMEM; 2076 2077 bcare_ctl->handle = handle; 2078 2079 sysfs_attr_init(&bcare_ctl->attrs[0].attr); 2080 bcare_ctl->attrs[0].attr.name = "battery_care_limiter"; 2081 bcare_ctl->attrs[0].attr.mode = S_IRUGO | S_IWUSR; 2082 bcare_ctl->attrs[0].show = sony_nc_battery_care_limit_show; 2083 bcare_ctl->attrs[0].store = sony_nc_battery_care_limit_store; 2084 2085 ret = device_create_file(&pd->dev, &bcare_ctl->attrs[0]); 2086 if (ret) 2087 goto outkzalloc; 2088 2089 /* 0x0115 is for models with no health reporting capability */ 2090 if (handle == 0x0115) 2091 return 0; 2092 2093 sysfs_attr_init(&bcare_ctl->attrs[1].attr); 2094 bcare_ctl->attrs[1].attr.name = "battery_care_health"; 2095 bcare_ctl->attrs[1].attr.mode = S_IRUGO; 2096 bcare_ctl->attrs[1].show = sony_nc_battery_care_health_show; 2097 2098 ret = device_create_file(&pd->dev, &bcare_ctl->attrs[1]); 2099 if (ret) 2100 goto outlimiter; 2101 2102 return 0; 2103 2104 outlimiter: 2105 device_remove_file(&pd->dev, &bcare_ctl->attrs[0]); 2106 2107 outkzalloc: 2108 kfree(bcare_ctl); 2109 bcare_ctl = NULL; 2110 2111 return ret; 2112 } 2113 2114 static void sony_nc_battery_care_cleanup(struct platform_device *pd) 2115 { 2116 if (bcare_ctl) { 2117 device_remove_file(&pd->dev, &bcare_ctl->attrs[0]); 2118 if (bcare_ctl->handle != 0x0115) 2119 device_remove_file(&pd->dev, &bcare_ctl->attrs[1]); 2120 2121 kfree(bcare_ctl); 2122 bcare_ctl = NULL; 2123 } 2124 } 2125 2126 struct snc_thermal_ctrl { 2127 unsigned int mode; 2128 unsigned int profiles; 2129 struct device_attribute mode_attr; 2130 struct device_attribute profiles_attr; 2131 }; 2132 static struct snc_thermal_ctrl *th_handle; 2133 2134 #define THM_PROFILE_MAX 3 2135 static const char * const snc_thermal_profiles[] = { 2136 "balanced", 2137 "silent", 2138 "performance" 2139 }; 2140 2141 static int sony_nc_thermal_mode_set(unsigned short mode) 2142 { 2143 unsigned int result; 2144 2145 /* the thermal profile seems to be a two bit bitmask: 2146 * lsb -> silent 2147 * msb -> performance 2148 * no bit set is the normal operation and is always valid 2149 * Some vaio models only have "balanced" and "performance" 2150 */ 2151 if ((mode && !(th_handle->profiles & mode)) || mode >= THM_PROFILE_MAX) 2152 return -EINVAL; 2153 2154 if (sony_call_snc_handle(0x0122, mode << 0x10 | 0x0200, &result)) 2155 return -EIO; 2156 2157 th_handle->mode = mode; 2158 2159 return 0; 2160 } 2161 2162 static int sony_nc_thermal_mode_get(void) 2163 { 2164 unsigned int result; 2165 2166 if (sony_call_snc_handle(0x0122, 0x0100, &result)) 2167 return -EIO; 2168 2169 return result & 0xff; 2170 } 2171 2172 static ssize_t sony_nc_thermal_profiles_show(struct device *dev, 2173 struct device_attribute *attr, char *buffer) 2174 { 2175 short cnt; 2176 size_t idx = 0; 2177 2178 for (cnt = 0; cnt < THM_PROFILE_MAX; cnt++) { 2179 if (!cnt || (th_handle->profiles & cnt)) 2180 idx += sysfs_emit_at(buffer, idx, "%s ", snc_thermal_profiles[cnt]); 2181 } 2182 idx += sysfs_emit_at(buffer, idx, "\n"); 2183 2184 return idx; 2185 } 2186 2187 static ssize_t sony_nc_thermal_mode_store(struct device *dev, 2188 struct device_attribute *attr, 2189 const char *buffer, size_t count) 2190 { 2191 unsigned short cmd; 2192 size_t len = count; 2193 2194 if (count == 0) 2195 return -EINVAL; 2196 2197 /* skip the newline if present */ 2198 if (buffer[len - 1] == '\n') 2199 len--; 2200 2201 for (cmd = 0; cmd < THM_PROFILE_MAX; cmd++) 2202 if (strncmp(buffer, snc_thermal_profiles[cmd], len) == 0) 2203 break; 2204 2205 if (sony_nc_thermal_mode_set(cmd)) 2206 return -EIO; 2207 2208 return count; 2209 } 2210 2211 static ssize_t sony_nc_thermal_mode_show(struct device *dev, 2212 struct device_attribute *attr, char *buffer) 2213 { 2214 int mode = sony_nc_thermal_mode_get(); 2215 2216 if (mode < 0) 2217 return mode; 2218 2219 return sysfs_emit(buffer, "%s\n", snc_thermal_profiles[mode]); 2220 } 2221 2222 static int sony_nc_thermal_setup(struct platform_device *pd) 2223 { 2224 int ret = 0; 2225 th_handle = kzalloc(sizeof(struct snc_thermal_ctrl), GFP_KERNEL); 2226 if (!th_handle) 2227 return -ENOMEM; 2228 2229 ret = sony_call_snc_handle(0x0122, 0x0000, &th_handle->profiles); 2230 if (ret) { 2231 pr_warn("couldn't to read the thermal profiles\n"); 2232 goto outkzalloc; 2233 } 2234 2235 ret = sony_nc_thermal_mode_get(); 2236 if (ret < 0) { 2237 pr_warn("couldn't to read the current thermal profile"); 2238 goto outkzalloc; 2239 } 2240 th_handle->mode = ret; 2241 2242 sysfs_attr_init(&th_handle->profiles_attr.attr); 2243 th_handle->profiles_attr.attr.name = "thermal_profiles"; 2244 th_handle->profiles_attr.attr.mode = S_IRUGO; 2245 th_handle->profiles_attr.show = sony_nc_thermal_profiles_show; 2246 2247 sysfs_attr_init(&th_handle->mode_attr.attr); 2248 th_handle->mode_attr.attr.name = "thermal_control"; 2249 th_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR; 2250 th_handle->mode_attr.show = sony_nc_thermal_mode_show; 2251 th_handle->mode_attr.store = sony_nc_thermal_mode_store; 2252 2253 ret = device_create_file(&pd->dev, &th_handle->profiles_attr); 2254 if (ret) 2255 goto outkzalloc; 2256 2257 ret = device_create_file(&pd->dev, &th_handle->mode_attr); 2258 if (ret) 2259 goto outprofiles; 2260 2261 return 0; 2262 2263 outprofiles: 2264 device_remove_file(&pd->dev, &th_handle->profiles_attr); 2265 outkzalloc: 2266 kfree(th_handle); 2267 th_handle = NULL; 2268 return ret; 2269 } 2270 2271 static void sony_nc_thermal_cleanup(struct platform_device *pd) 2272 { 2273 if (th_handle) { 2274 device_remove_file(&pd->dev, &th_handle->profiles_attr); 2275 device_remove_file(&pd->dev, &th_handle->mode_attr); 2276 kfree(th_handle); 2277 th_handle = NULL; 2278 } 2279 } 2280 2281 #ifdef CONFIG_PM_SLEEP 2282 static void sony_nc_thermal_resume(void) 2283 { 2284 int status; 2285 2286 if (!th_handle) 2287 return; 2288 2289 status = sony_nc_thermal_mode_get(); 2290 2291 if (status != th_handle->mode) 2292 sony_nc_thermal_mode_set(th_handle->mode); 2293 } 2294 #endif 2295 2296 /* resume on LID open */ 2297 #define LID_RESUME_S5 0 2298 #define LID_RESUME_S4 1 2299 #define LID_RESUME_S3 2 2300 #define LID_RESUME_MAX 3 2301 struct snc_lid_resume_control { 2302 struct device_attribute attrs[LID_RESUME_MAX]; 2303 unsigned int status; 2304 int handle; 2305 }; 2306 static struct snc_lid_resume_control *lid_ctl; 2307 2308 static ssize_t sony_nc_lid_resume_store(struct device *dev, 2309 struct device_attribute *attr, 2310 const char *buffer, size_t count) 2311 { 2312 unsigned int result; 2313 unsigned long value; 2314 unsigned int pos = LID_RESUME_S5; 2315 if (count > 31) 2316 return -EINVAL; 2317 2318 if (kstrtoul(buffer, 10, &value) || value > 1) 2319 return -EINVAL; 2320 2321 /* the value we have to write to SNC is a bitmask: 2322 * +--------------+ 2323 * | S3 | S4 | S5 | 2324 * +--------------+ 2325 * 2 1 0 2326 */ 2327 while (pos < LID_RESUME_MAX) { 2328 if (&lid_ctl->attrs[pos].attr == &attr->attr) 2329 break; 2330 pos++; 2331 } 2332 if (pos == LID_RESUME_MAX) 2333 return -EINVAL; 2334 2335 if (value) 2336 value = lid_ctl->status | (1 << pos); 2337 else 2338 value = lid_ctl->status & ~(1 << pos); 2339 2340 if (sony_call_snc_handle(lid_ctl->handle, value << 0x10 | 0x0100, 2341 &result)) 2342 return -EIO; 2343 2344 lid_ctl->status = value; 2345 2346 return count; 2347 } 2348 2349 static ssize_t sony_nc_lid_resume_show(struct device *dev, 2350 struct device_attribute *attr, 2351 char *buffer) 2352 { 2353 unsigned int pos = LID_RESUME_S5; 2354 2355 while (pos < LID_RESUME_MAX) { 2356 if (&lid_ctl->attrs[pos].attr == &attr->attr) 2357 return sysfs_emit(buffer, "%d\n", 2358 (lid_ctl->status >> pos) & 0x01); 2359 pos++; 2360 } 2361 return -EINVAL; 2362 } 2363 2364 static int sony_nc_lid_resume_setup(struct platform_device *pd, 2365 unsigned int handle) 2366 { 2367 unsigned int result; 2368 int i; 2369 2370 if (sony_call_snc_handle(handle, 0x0000, &result)) 2371 return -EIO; 2372 2373 lid_ctl = kzalloc(sizeof(struct snc_lid_resume_control), GFP_KERNEL); 2374 if (!lid_ctl) 2375 return -ENOMEM; 2376 2377 lid_ctl->status = result & 0x7; 2378 lid_ctl->handle = handle; 2379 2380 sysfs_attr_init(&lid_ctl->attrs[0].attr); 2381 lid_ctl->attrs[LID_RESUME_S5].attr.name = "lid_resume_S5"; 2382 lid_ctl->attrs[LID_RESUME_S5].attr.mode = S_IRUGO | S_IWUSR; 2383 lid_ctl->attrs[LID_RESUME_S5].show = sony_nc_lid_resume_show; 2384 lid_ctl->attrs[LID_RESUME_S5].store = sony_nc_lid_resume_store; 2385 2386 if (handle == 0x0119) { 2387 sysfs_attr_init(&lid_ctl->attrs[1].attr); 2388 lid_ctl->attrs[LID_RESUME_S4].attr.name = "lid_resume_S4"; 2389 lid_ctl->attrs[LID_RESUME_S4].attr.mode = S_IRUGO | S_IWUSR; 2390 lid_ctl->attrs[LID_RESUME_S4].show = sony_nc_lid_resume_show; 2391 lid_ctl->attrs[LID_RESUME_S4].store = sony_nc_lid_resume_store; 2392 2393 sysfs_attr_init(&lid_ctl->attrs[2].attr); 2394 lid_ctl->attrs[LID_RESUME_S3].attr.name = "lid_resume_S3"; 2395 lid_ctl->attrs[LID_RESUME_S3].attr.mode = S_IRUGO | S_IWUSR; 2396 lid_ctl->attrs[LID_RESUME_S3].show = sony_nc_lid_resume_show; 2397 lid_ctl->attrs[LID_RESUME_S3].store = sony_nc_lid_resume_store; 2398 } 2399 for (i = 0; i < LID_RESUME_MAX && 2400 lid_ctl->attrs[i].attr.name; i++) { 2401 result = device_create_file(&pd->dev, &lid_ctl->attrs[i]); 2402 if (result) 2403 goto liderror; 2404 } 2405 2406 return 0; 2407 2408 liderror: 2409 for (i--; i >= 0; i--) 2410 device_remove_file(&pd->dev, &lid_ctl->attrs[i]); 2411 2412 kfree(lid_ctl); 2413 lid_ctl = NULL; 2414 2415 return result; 2416 } 2417 2418 static void sony_nc_lid_resume_cleanup(struct platform_device *pd) 2419 { 2420 int i; 2421 2422 if (lid_ctl) { 2423 for (i = 0; i < LID_RESUME_MAX; i++) { 2424 if (!lid_ctl->attrs[i].attr.name) 2425 break; 2426 2427 device_remove_file(&pd->dev, &lid_ctl->attrs[i]); 2428 } 2429 2430 kfree(lid_ctl); 2431 lid_ctl = NULL; 2432 } 2433 } 2434 2435 /* GFX Switch position */ 2436 enum gfx_switch { 2437 SPEED, 2438 STAMINA, 2439 AUTO 2440 }; 2441 struct snc_gfx_switch_control { 2442 struct device_attribute attr; 2443 unsigned int handle; 2444 }; 2445 static struct snc_gfx_switch_control *gfxs_ctl; 2446 2447 /* returns 0 for speed, 1 for stamina */ 2448 static int __sony_nc_gfx_switch_status_get(void) 2449 { 2450 unsigned int result; 2451 2452 if (sony_call_snc_handle(gfxs_ctl->handle, 2453 gfxs_ctl->handle == 0x015B ? 0x0000 : 0x0100, 2454 &result)) 2455 return -EIO; 2456 2457 switch (gfxs_ctl->handle) { 2458 case 0x0146: 2459 /* 1: discrete GFX (speed) 2460 * 0: integrated GFX (stamina) 2461 */ 2462 return result & 0x1 ? SPEED : STAMINA; 2463 case 0x015B: 2464 /* 0: discrete GFX (speed) 2465 * 1: integrated GFX (stamina) 2466 */ 2467 return result & 0x1 ? STAMINA : SPEED; 2468 case 0x0128: 2469 /* it's a more elaborated bitmask, for now: 2470 * 2: integrated GFX (stamina) 2471 * 0: discrete GFX (speed) 2472 */ 2473 dprintk("GFX Status: 0x%x\n", result); 2474 return result & 0x80 ? AUTO : 2475 result & 0x02 ? STAMINA : SPEED; 2476 } 2477 return -EINVAL; 2478 } 2479 2480 static ssize_t sony_nc_gfx_switch_status_show(struct device *dev, 2481 struct device_attribute *attr, 2482 char *buffer) 2483 { 2484 int pos = __sony_nc_gfx_switch_status_get(); 2485 2486 if (pos < 0) 2487 return pos; 2488 2489 return sysfs_emit(buffer, "%s\n", 2490 pos == SPEED ? "speed" : 2491 pos == STAMINA ? "stamina" : 2492 pos == AUTO ? "auto" : "unknown"); 2493 } 2494 2495 static int sony_nc_gfx_switch_setup(struct platform_device *pd, 2496 unsigned int handle) 2497 { 2498 unsigned int result; 2499 2500 gfxs_ctl = kzalloc(sizeof(struct snc_gfx_switch_control), GFP_KERNEL); 2501 if (!gfxs_ctl) 2502 return -ENOMEM; 2503 2504 gfxs_ctl->handle = handle; 2505 2506 sysfs_attr_init(&gfxs_ctl->attr.attr); 2507 gfxs_ctl->attr.attr.name = "gfx_switch_status"; 2508 gfxs_ctl->attr.attr.mode = S_IRUGO; 2509 gfxs_ctl->attr.show = sony_nc_gfx_switch_status_show; 2510 2511 result = device_create_file(&pd->dev, &gfxs_ctl->attr); 2512 if (result) 2513 goto gfxerror; 2514 2515 return 0; 2516 2517 gfxerror: 2518 kfree(gfxs_ctl); 2519 gfxs_ctl = NULL; 2520 2521 return result; 2522 } 2523 2524 static void sony_nc_gfx_switch_cleanup(struct platform_device *pd) 2525 { 2526 if (gfxs_ctl) { 2527 device_remove_file(&pd->dev, &gfxs_ctl->attr); 2528 2529 kfree(gfxs_ctl); 2530 gfxs_ctl = NULL; 2531 } 2532 } 2533 2534 /* High speed charging function */ 2535 static struct device_attribute *hsc_handle; 2536 2537 static ssize_t sony_nc_highspeed_charging_store(struct device *dev, 2538 struct device_attribute *attr, 2539 const char *buffer, size_t count) 2540 { 2541 unsigned int result; 2542 unsigned long value; 2543 2544 if (count > 31) 2545 return -EINVAL; 2546 2547 if (kstrtoul(buffer, 10, &value) || value > 1) 2548 return -EINVAL; 2549 2550 if (sony_call_snc_handle(0x0131, value << 0x10 | 0x0200, &result)) 2551 return -EIO; 2552 2553 return count; 2554 } 2555 2556 static ssize_t sony_nc_highspeed_charging_show(struct device *dev, 2557 struct device_attribute *attr, char *buffer) 2558 { 2559 unsigned int result; 2560 2561 if (sony_call_snc_handle(0x0131, 0x0100, &result)) 2562 return -EIO; 2563 2564 return sysfs_emit(buffer, "%d\n", result & 0x01); 2565 } 2566 2567 static int sony_nc_highspeed_charging_setup(struct platform_device *pd) 2568 { 2569 unsigned int result; 2570 2571 if (sony_call_snc_handle(0x0131, 0x0000, &result) || !(result & 0x01)) { 2572 /* some models advertise the handle but have no implementation 2573 * for it 2574 */ 2575 pr_info("No High Speed Charging capability found\n"); 2576 return 0; 2577 } 2578 2579 hsc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2580 if (!hsc_handle) 2581 return -ENOMEM; 2582 2583 sysfs_attr_init(&hsc_handle->attr); 2584 hsc_handle->attr.name = "battery_highspeed_charging"; 2585 hsc_handle->attr.mode = S_IRUGO | S_IWUSR; 2586 hsc_handle->show = sony_nc_highspeed_charging_show; 2587 hsc_handle->store = sony_nc_highspeed_charging_store; 2588 2589 result = device_create_file(&pd->dev, hsc_handle); 2590 if (result) { 2591 kfree(hsc_handle); 2592 hsc_handle = NULL; 2593 return result; 2594 } 2595 2596 return 0; 2597 } 2598 2599 static void sony_nc_highspeed_charging_cleanup(struct platform_device *pd) 2600 { 2601 if (hsc_handle) { 2602 device_remove_file(&pd->dev, hsc_handle); 2603 kfree(hsc_handle); 2604 hsc_handle = NULL; 2605 } 2606 } 2607 2608 /* low battery function */ 2609 static struct device_attribute *lowbatt_handle; 2610 2611 static ssize_t sony_nc_lowbatt_store(struct device *dev, 2612 struct device_attribute *attr, 2613 const char *buffer, size_t count) 2614 { 2615 unsigned int result; 2616 unsigned long value; 2617 2618 if (count > 31) 2619 return -EINVAL; 2620 2621 if (kstrtoul(buffer, 10, &value) || value > 1) 2622 return -EINVAL; 2623 2624 if (sony_call_snc_handle(0x0121, value << 8, &result)) 2625 return -EIO; 2626 2627 return count; 2628 } 2629 2630 static ssize_t sony_nc_lowbatt_show(struct device *dev, 2631 struct device_attribute *attr, char *buffer) 2632 { 2633 unsigned int result; 2634 2635 if (sony_call_snc_handle(0x0121, 0x0200, &result)) 2636 return -EIO; 2637 2638 return sysfs_emit(buffer, "%d\n", result & 1); 2639 } 2640 2641 static int sony_nc_lowbatt_setup(struct platform_device *pd) 2642 { 2643 unsigned int result; 2644 2645 lowbatt_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2646 if (!lowbatt_handle) 2647 return -ENOMEM; 2648 2649 sysfs_attr_init(&lowbatt_handle->attr); 2650 lowbatt_handle->attr.name = "lowbatt_hibernate"; 2651 lowbatt_handle->attr.mode = S_IRUGO | S_IWUSR; 2652 lowbatt_handle->show = sony_nc_lowbatt_show; 2653 lowbatt_handle->store = sony_nc_lowbatt_store; 2654 2655 result = device_create_file(&pd->dev, lowbatt_handle); 2656 if (result) { 2657 kfree(lowbatt_handle); 2658 lowbatt_handle = NULL; 2659 return result; 2660 } 2661 2662 return 0; 2663 } 2664 2665 static void sony_nc_lowbatt_cleanup(struct platform_device *pd) 2666 { 2667 if (lowbatt_handle) { 2668 device_remove_file(&pd->dev, lowbatt_handle); 2669 kfree(lowbatt_handle); 2670 lowbatt_handle = NULL; 2671 } 2672 } 2673 2674 /* fan speed function */ 2675 static struct device_attribute *fan_handle, *hsf_handle; 2676 2677 static ssize_t sony_nc_hsfan_store(struct device *dev, 2678 struct device_attribute *attr, 2679 const char *buffer, size_t count) 2680 { 2681 unsigned int result; 2682 unsigned long value; 2683 2684 if (count > 31) 2685 return -EINVAL; 2686 2687 if (kstrtoul(buffer, 10, &value) || value > 1) 2688 return -EINVAL; 2689 2690 if (sony_call_snc_handle(0x0149, value << 0x10 | 0x0200, &result)) 2691 return -EIO; 2692 2693 return count; 2694 } 2695 2696 static ssize_t sony_nc_hsfan_show(struct device *dev, 2697 struct device_attribute *attr, char *buffer) 2698 { 2699 unsigned int result; 2700 2701 if (sony_call_snc_handle(0x0149, 0x0100, &result)) 2702 return -EIO; 2703 2704 return sysfs_emit(buffer, "%d\n", result & 0x01); 2705 } 2706 2707 static ssize_t sony_nc_fanspeed_show(struct device *dev, 2708 struct device_attribute *attr, char *buffer) 2709 { 2710 unsigned int result; 2711 2712 if (sony_call_snc_handle(0x0149, 0x0300, &result)) 2713 return -EIO; 2714 2715 return sysfs_emit(buffer, "%d\n", result & 0xff); 2716 } 2717 2718 static int sony_nc_fanspeed_setup(struct platform_device *pd) 2719 { 2720 unsigned int result; 2721 2722 fan_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2723 if (!fan_handle) 2724 return -ENOMEM; 2725 2726 hsf_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2727 if (!hsf_handle) { 2728 result = -ENOMEM; 2729 goto out_hsf_handle_alloc; 2730 } 2731 2732 sysfs_attr_init(&fan_handle->attr); 2733 fan_handle->attr.name = "fanspeed"; 2734 fan_handle->attr.mode = S_IRUGO; 2735 fan_handle->show = sony_nc_fanspeed_show; 2736 fan_handle->store = NULL; 2737 2738 sysfs_attr_init(&hsf_handle->attr); 2739 hsf_handle->attr.name = "fan_forced"; 2740 hsf_handle->attr.mode = S_IRUGO | S_IWUSR; 2741 hsf_handle->show = sony_nc_hsfan_show; 2742 hsf_handle->store = sony_nc_hsfan_store; 2743 2744 result = device_create_file(&pd->dev, fan_handle); 2745 if (result) 2746 goto out_fan_handle; 2747 2748 result = device_create_file(&pd->dev, hsf_handle); 2749 if (result) 2750 goto out_hsf_handle; 2751 2752 return 0; 2753 2754 out_hsf_handle: 2755 device_remove_file(&pd->dev, fan_handle); 2756 2757 out_fan_handle: 2758 kfree(hsf_handle); 2759 hsf_handle = NULL; 2760 2761 out_hsf_handle_alloc: 2762 kfree(fan_handle); 2763 fan_handle = NULL; 2764 return result; 2765 } 2766 2767 static void sony_nc_fanspeed_cleanup(struct platform_device *pd) 2768 { 2769 if (fan_handle) { 2770 device_remove_file(&pd->dev, fan_handle); 2771 kfree(fan_handle); 2772 fan_handle = NULL; 2773 } 2774 if (hsf_handle) { 2775 device_remove_file(&pd->dev, hsf_handle); 2776 kfree(hsf_handle); 2777 hsf_handle = NULL; 2778 } 2779 } 2780 2781 /* USB charge function */ 2782 static struct device_attribute *uc_handle; 2783 2784 static ssize_t sony_nc_usb_charge_store(struct device *dev, 2785 struct device_attribute *attr, 2786 const char *buffer, size_t count) 2787 { 2788 unsigned int result; 2789 unsigned long value; 2790 2791 if (count > 31) 2792 return -EINVAL; 2793 2794 if (kstrtoul(buffer, 10, &value) || value > 1) 2795 return -EINVAL; 2796 2797 if (sony_call_snc_handle(0x0155, value << 0x10 | 0x0100, &result)) 2798 return -EIO; 2799 2800 return count; 2801 } 2802 2803 static ssize_t sony_nc_usb_charge_show(struct device *dev, 2804 struct device_attribute *attr, char *buffer) 2805 { 2806 unsigned int result; 2807 2808 if (sony_call_snc_handle(0x0155, 0x0000, &result)) 2809 return -EIO; 2810 2811 return sysfs_emit(buffer, "%d\n", result & 0x01); 2812 } 2813 2814 static int sony_nc_usb_charge_setup(struct platform_device *pd) 2815 { 2816 unsigned int result; 2817 2818 if (sony_call_snc_handle(0x0155, 0x0000, &result) || !(result & 0x01)) { 2819 /* some models advertise the handle but have no implementation 2820 * for it 2821 */ 2822 pr_info("No USB Charge capability found\n"); 2823 return 0; 2824 } 2825 2826 uc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2827 if (!uc_handle) 2828 return -ENOMEM; 2829 2830 sysfs_attr_init(&uc_handle->attr); 2831 uc_handle->attr.name = "usb_charge"; 2832 uc_handle->attr.mode = S_IRUGO | S_IWUSR; 2833 uc_handle->show = sony_nc_usb_charge_show; 2834 uc_handle->store = sony_nc_usb_charge_store; 2835 2836 result = device_create_file(&pd->dev, uc_handle); 2837 if (result) { 2838 kfree(uc_handle); 2839 uc_handle = NULL; 2840 return result; 2841 } 2842 2843 return 0; 2844 } 2845 2846 static void sony_nc_usb_charge_cleanup(struct platform_device *pd) 2847 { 2848 if (uc_handle) { 2849 device_remove_file(&pd->dev, uc_handle); 2850 kfree(uc_handle); 2851 uc_handle = NULL; 2852 } 2853 } 2854 2855 /* Panel ID function */ 2856 static struct device_attribute *panel_handle; 2857 2858 static ssize_t sony_nc_panelid_show(struct device *dev, 2859 struct device_attribute *attr, char *buffer) 2860 { 2861 unsigned int result; 2862 2863 if (sony_call_snc_handle(0x011D, 0x0000, &result)) 2864 return -EIO; 2865 2866 return sysfs_emit(buffer, "%d\n", result); 2867 } 2868 2869 static int sony_nc_panelid_setup(struct platform_device *pd) 2870 { 2871 unsigned int result; 2872 2873 panel_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2874 if (!panel_handle) 2875 return -ENOMEM; 2876 2877 sysfs_attr_init(&panel_handle->attr); 2878 panel_handle->attr.name = "panel_id"; 2879 panel_handle->attr.mode = S_IRUGO; 2880 panel_handle->show = sony_nc_panelid_show; 2881 panel_handle->store = NULL; 2882 2883 result = device_create_file(&pd->dev, panel_handle); 2884 if (result) { 2885 kfree(panel_handle); 2886 panel_handle = NULL; 2887 return result; 2888 } 2889 2890 return 0; 2891 } 2892 2893 static void sony_nc_panelid_cleanup(struct platform_device *pd) 2894 { 2895 if (panel_handle) { 2896 device_remove_file(&pd->dev, panel_handle); 2897 kfree(panel_handle); 2898 panel_handle = NULL; 2899 } 2900 } 2901 2902 /* smart connect function */ 2903 static struct device_attribute *sc_handle; 2904 2905 static ssize_t sony_nc_smart_conn_store(struct device *dev, 2906 struct device_attribute *attr, 2907 const char *buffer, size_t count) 2908 { 2909 unsigned int result; 2910 unsigned long value; 2911 2912 if (count > 31) 2913 return -EINVAL; 2914 2915 if (kstrtoul(buffer, 10, &value) || value > 1) 2916 return -EINVAL; 2917 2918 if (sony_call_snc_handle(0x0168, value << 0x10, &result)) 2919 return -EIO; 2920 2921 return count; 2922 } 2923 2924 static int sony_nc_smart_conn_setup(struct platform_device *pd) 2925 { 2926 unsigned int result; 2927 2928 sc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); 2929 if (!sc_handle) 2930 return -ENOMEM; 2931 2932 sysfs_attr_init(&sc_handle->attr); 2933 sc_handle->attr.name = "smart_connect"; 2934 sc_handle->attr.mode = S_IWUSR; 2935 sc_handle->show = NULL; 2936 sc_handle->store = sony_nc_smart_conn_store; 2937 2938 result = device_create_file(&pd->dev, sc_handle); 2939 if (result) { 2940 kfree(sc_handle); 2941 sc_handle = NULL; 2942 return result; 2943 } 2944 2945 return 0; 2946 } 2947 2948 static void sony_nc_smart_conn_cleanup(struct platform_device *pd) 2949 { 2950 if (sc_handle) { 2951 device_remove_file(&pd->dev, sc_handle); 2952 kfree(sc_handle); 2953 sc_handle = NULL; 2954 } 2955 } 2956 2957 /* Touchpad enable/disable */ 2958 struct touchpad_control { 2959 struct device_attribute attr; 2960 int handle; 2961 }; 2962 static struct touchpad_control *tp_ctl; 2963 2964 static ssize_t sony_nc_touchpad_store(struct device *dev, 2965 struct device_attribute *attr, const char *buffer, size_t count) 2966 { 2967 unsigned int result; 2968 unsigned long value; 2969 2970 if (count > 31) 2971 return -EINVAL; 2972 2973 if (kstrtoul(buffer, 10, &value) || value > 1) 2974 return -EINVAL; 2975 2976 /* sysfs: 0 disabled, 1 enabled 2977 * EC: 0 enabled, 1 disabled 2978 */ 2979 if (sony_call_snc_handle(tp_ctl->handle, 2980 (!value << 0x10) | 0x100, &result)) 2981 return -EIO; 2982 2983 return count; 2984 } 2985 2986 static ssize_t sony_nc_touchpad_show(struct device *dev, 2987 struct device_attribute *attr, char *buffer) 2988 { 2989 unsigned int result; 2990 2991 if (sony_call_snc_handle(tp_ctl->handle, 0x000, &result)) 2992 return -EINVAL; 2993 2994 return sysfs_emit(buffer, "%d\n", !(result & 0x01)); 2995 } 2996 2997 static int sony_nc_touchpad_setup(struct platform_device *pd, 2998 unsigned int handle) 2999 { 3000 int ret = 0; 3001 3002 tp_ctl = kzalloc(sizeof(struct touchpad_control), GFP_KERNEL); 3003 if (!tp_ctl) 3004 return -ENOMEM; 3005 3006 tp_ctl->handle = handle; 3007 3008 sysfs_attr_init(&tp_ctl->attr.attr); 3009 tp_ctl->attr.attr.name = "touchpad"; 3010 tp_ctl->attr.attr.mode = S_IRUGO | S_IWUSR; 3011 tp_ctl->attr.show = sony_nc_touchpad_show; 3012 tp_ctl->attr.store = sony_nc_touchpad_store; 3013 3014 ret = device_create_file(&pd->dev, &tp_ctl->attr); 3015 if (ret) { 3016 kfree(tp_ctl); 3017 tp_ctl = NULL; 3018 } 3019 3020 return ret; 3021 } 3022 3023 static void sony_nc_touchpad_cleanup(struct platform_device *pd) 3024 { 3025 if (tp_ctl) { 3026 device_remove_file(&pd->dev, &tp_ctl->attr); 3027 kfree(tp_ctl); 3028 tp_ctl = NULL; 3029 } 3030 } 3031 3032 static void sony_nc_backlight_ng_read_limits(int handle, 3033 struct sony_backlight_props *props) 3034 { 3035 u64 offset; 3036 int i; 3037 int lvl_table_len = 0; 3038 u8 min = 0xff, max = 0x00; 3039 unsigned char buffer[32] = { 0 }; 3040 3041 props->handle = handle; 3042 props->offset = 0; 3043 props->maxlvl = 0xff; 3044 3045 offset = sony_find_snc_handle(handle); 3046 3047 /* try to read the boundaries from ACPI tables, if we fail the above 3048 * defaults should be reasonable 3049 */ 3050 i = sony_nc_buffer_call(sony_nc_acpi_handle, "SN06", &offset, buffer, 3051 32); 3052 if (i < 0) 3053 return; 3054 3055 switch (handle) { 3056 case 0x012f: 3057 case 0x0137: 3058 lvl_table_len = 9; 3059 break; 3060 case 0x143: 3061 case 0x14b: 3062 case 0x14c: 3063 lvl_table_len = 16; 3064 break; 3065 } 3066 3067 /* the buffer lists brightness levels available, brightness levels are 3068 * from position 0 to 8 in the array, other values are used by ALS 3069 * control. 3070 */ 3071 for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) { 3072 3073 dprintk("Brightness level: %d\n", buffer[i]); 3074 3075 if (!buffer[i]) 3076 break; 3077 3078 if (buffer[i] > max) 3079 max = buffer[i]; 3080 if (buffer[i] < min) 3081 min = buffer[i]; 3082 } 3083 props->offset = min; 3084 props->maxlvl = max; 3085 dprintk("Brightness levels: min=%d max=%d\n", props->offset, 3086 props->maxlvl); 3087 } 3088 3089 static void sony_nc_backlight_setup(void) 3090 { 3091 int max_brightness = 0; 3092 const struct backlight_ops *ops = NULL; 3093 struct backlight_properties props; 3094 3095 if (sony_find_snc_handle(0x12f) >= 0) { 3096 ops = &sony_backlight_ng_ops; 3097 sony_bl_props.cmd_base = 0x0100; 3098 sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); 3099 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 3100 3101 } else if (sony_find_snc_handle(0x137) >= 0) { 3102 ops = &sony_backlight_ng_ops; 3103 sony_bl_props.cmd_base = 0x0100; 3104 sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); 3105 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 3106 3107 } else if (sony_find_snc_handle(0x143) >= 0) { 3108 ops = &sony_backlight_ng_ops; 3109 sony_bl_props.cmd_base = 0x3000; 3110 sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props); 3111 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 3112 3113 } else if (sony_find_snc_handle(0x14b) >= 0) { 3114 ops = &sony_backlight_ng_ops; 3115 sony_bl_props.cmd_base = 0x3000; 3116 sony_nc_backlight_ng_read_limits(0x14b, &sony_bl_props); 3117 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 3118 3119 } else if (sony_find_snc_handle(0x14c) >= 0) { 3120 ops = &sony_backlight_ng_ops; 3121 sony_bl_props.cmd_base = 0x3000; 3122 sony_nc_backlight_ng_read_limits(0x14c, &sony_bl_props); 3123 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 3124 3125 } else if (acpi_has_method(sony_nc_acpi_handle, "GBRT")) { 3126 ops = &sony_backlight_ops; 3127 max_brightness = SONY_MAX_BRIGHTNESS - 1; 3128 3129 } else 3130 return; 3131 3132 memset(&props, 0, sizeof(struct backlight_properties)); 3133 props.type = BACKLIGHT_PLATFORM; 3134 props.max_brightness = max_brightness; 3135 sony_bl_props.dev = backlight_device_register("sony", NULL, 3136 &sony_bl_props, 3137 ops, &props); 3138 3139 if (IS_ERR(sony_bl_props.dev)) { 3140 pr_warn("unable to register backlight device\n"); 3141 sony_bl_props.dev = NULL; 3142 } else 3143 sony_bl_props.dev->props.brightness = 3144 ops->get_brightness(sony_bl_props.dev); 3145 } 3146 3147 static void sony_nc_backlight_cleanup(void) 3148 { 3149 backlight_device_unregister(sony_bl_props.dev); 3150 } 3151 3152 static int sony_nc_add(struct acpi_device *device) 3153 { 3154 acpi_status status; 3155 int result = 0; 3156 struct sony_nc_value *item; 3157 3158 sony_nc_acpi_device = device; 3159 strscpy(acpi_device_class(device), "sony/hotkey"); 3160 3161 sony_nc_acpi_handle = device->handle; 3162 3163 /* read device status */ 3164 result = acpi_bus_get_status(device); 3165 /* bail IFF the above call was successful and the device is not present */ 3166 if (!result && !device->status.present) { 3167 dprintk("Device not present\n"); 3168 result = -ENODEV; 3169 goto outwalk; 3170 } 3171 3172 result = sony_pf_add(); 3173 if (result) 3174 goto outpresent; 3175 3176 if (debug) { 3177 status = acpi_walk_namespace(ACPI_TYPE_METHOD, 3178 sony_nc_acpi_handle, 1, sony_walk_callback, 3179 NULL, NULL, NULL); 3180 if (ACPI_FAILURE(status)) { 3181 pr_warn("unable to walk acpi resources\n"); 3182 result = -ENODEV; 3183 goto outpresent; 3184 } 3185 } 3186 3187 result = sony_laptop_setup_input(device); 3188 if (result) { 3189 pr_err("Unable to create input devices\n"); 3190 goto outplatform; 3191 } 3192 3193 if (acpi_has_method(sony_nc_acpi_handle, "ECON")) { 3194 int arg = 1; 3195 if (sony_nc_int_call(sony_nc_acpi_handle, "ECON", &arg, NULL)) 3196 dprintk("ECON Method failed\n"); 3197 } 3198 3199 if (acpi_has_method(sony_nc_acpi_handle, "SN00")) { 3200 dprintk("Doing SNC setup\n"); 3201 /* retrieve the available handles */ 3202 result = sony_nc_handles_setup(sony_pf_device); 3203 if (!result) 3204 sony_nc_function_setup(device, sony_pf_device); 3205 } 3206 3207 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) 3208 sony_nc_backlight_setup(); 3209 3210 /* create sony_pf sysfs attributes related to the SNC device */ 3211 for (item = sony_nc_values; item->name; ++item) { 3212 3213 if (!debug && item->debug) 3214 continue; 3215 3216 /* find the available acpiget as described in the DSDT */ 3217 for (; item->acpiget && *item->acpiget; ++item->acpiget) { 3218 if (acpi_has_method(sony_nc_acpi_handle, 3219 *item->acpiget)) { 3220 dprintk("Found %s getter: %s\n", 3221 item->name, *item->acpiget); 3222 item->devattr.attr.mode |= S_IRUGO; 3223 break; 3224 } 3225 } 3226 3227 /* find the available acpiset as described in the DSDT */ 3228 for (; item->acpiset && *item->acpiset; ++item->acpiset) { 3229 if (acpi_has_method(sony_nc_acpi_handle, 3230 *item->acpiset)) { 3231 dprintk("Found %s setter: %s\n", 3232 item->name, *item->acpiset); 3233 item->devattr.attr.mode |= S_IWUSR; 3234 break; 3235 } 3236 } 3237 3238 if (item->devattr.attr.mode != 0) { 3239 result = 3240 device_create_file(&sony_pf_device->dev, 3241 &item->devattr); 3242 if (result) 3243 goto out_sysfs; 3244 } 3245 } 3246 3247 pr_info("SNC setup done.\n"); 3248 return 0; 3249 3250 out_sysfs: 3251 for (item = sony_nc_values; item->name; ++item) { 3252 device_remove_file(&sony_pf_device->dev, &item->devattr); 3253 } 3254 sony_nc_backlight_cleanup(); 3255 sony_nc_function_cleanup(sony_pf_device); 3256 sony_nc_handles_cleanup(sony_pf_device); 3257 3258 outplatform: 3259 sony_laptop_remove_input(); 3260 3261 outpresent: 3262 sony_pf_remove(); 3263 3264 outwalk: 3265 sony_nc_rfkill_cleanup(); 3266 return result; 3267 } 3268 3269 static void sony_nc_remove(struct acpi_device *device) 3270 { 3271 struct sony_nc_value *item; 3272 3273 sony_nc_backlight_cleanup(); 3274 3275 sony_nc_acpi_device = NULL; 3276 3277 for (item = sony_nc_values; item->name; ++item) { 3278 device_remove_file(&sony_pf_device->dev, &item->devattr); 3279 } 3280 3281 sony_nc_function_cleanup(sony_pf_device); 3282 sony_nc_handles_cleanup(sony_pf_device); 3283 sony_pf_remove(); 3284 sony_laptop_remove_input(); 3285 dprintk(SONY_NC_DRIVER_NAME " removed.\n"); 3286 } 3287 3288 static const struct acpi_device_id sony_device_ids[] __maybe_unused = { 3289 {SONY_NC_HID, 0}, 3290 {SONY_PIC_HID, 0}, 3291 {"", 0}, 3292 }; 3293 MODULE_DEVICE_TABLE(acpi, sony_device_ids); 3294 3295 static const struct acpi_device_id sony_nc_device_ids[] = { 3296 {SONY_NC_HID, 0}, 3297 {"", 0}, 3298 }; 3299 3300 static struct acpi_driver sony_nc_driver = { 3301 .name = SONY_NC_DRIVER_NAME, 3302 .class = SONY_NC_CLASS, 3303 .ids = sony_nc_device_ids, 3304 .ops = { 3305 .add = sony_nc_add, 3306 .remove = sony_nc_remove, 3307 .notify = sony_nc_notify, 3308 }, 3309 .drv.pm = &sony_nc_pm, 3310 }; 3311 3312 /*********** SPIC (SNY6001) Device ***********/ 3313 3314 #define SONYPI_DEVICE_TYPE1 0x00000001 3315 #define SONYPI_DEVICE_TYPE2 0x00000002 3316 #define SONYPI_DEVICE_TYPE3 0x00000004 3317 3318 #define SONYPI_TYPE1_OFFSET 0x04 3319 #define SONYPI_TYPE2_OFFSET 0x12 3320 #define SONYPI_TYPE3_OFFSET 0x12 3321 3322 struct sony_pic_ioport { 3323 struct acpi_resource_io io1; 3324 struct acpi_resource_io io2; 3325 struct list_head list; 3326 }; 3327 3328 struct sony_pic_irq { 3329 struct list_head list; 3330 3331 /* Must be last --ends in a flexible-array member. */ 3332 struct acpi_resource_irq irq; 3333 }; 3334 3335 struct sonypi_eventtypes { 3336 u8 data; 3337 unsigned long mask; 3338 struct sonypi_event *events; 3339 }; 3340 3341 struct sony_pic_dev { 3342 struct acpi_device *acpi_dev; 3343 struct sony_pic_irq *cur_irq; 3344 struct sony_pic_ioport *cur_ioport; 3345 struct list_head interrupts; 3346 struct list_head ioports; 3347 struct mutex lock; 3348 struct sonypi_eventtypes *event_types; 3349 int (*handle_irq)(const u8, const u8); 3350 int model; 3351 u16 evport_offset; 3352 u8 camera_power; 3353 u8 bluetooth_power; 3354 u8 wwan_power; 3355 }; 3356 3357 static struct sony_pic_dev spic_dev = { 3358 .interrupts = LIST_HEAD_INIT(spic_dev.interrupts), 3359 .ioports = LIST_HEAD_INIT(spic_dev.ioports), 3360 }; 3361 3362 static int spic_drv_registered; 3363 3364 /* Event masks */ 3365 #define SONYPI_JOGGER_MASK 0x00000001 3366 #define SONYPI_CAPTURE_MASK 0x00000002 3367 #define SONYPI_FNKEY_MASK 0x00000004 3368 #define SONYPI_BLUETOOTH_MASK 0x00000008 3369 #define SONYPI_PKEY_MASK 0x00000010 3370 #define SONYPI_BACK_MASK 0x00000020 3371 #define SONYPI_HELP_MASK 0x00000040 3372 #define SONYPI_LID_MASK 0x00000080 3373 #define SONYPI_ZOOM_MASK 0x00000100 3374 #define SONYPI_THUMBPHRASE_MASK 0x00000200 3375 #define SONYPI_MEYE_MASK 0x00000400 3376 #define SONYPI_MEMORYSTICK_MASK 0x00000800 3377 #define SONYPI_BATTERY_MASK 0x00001000 3378 #define SONYPI_WIRELESS_MASK 0x00002000 3379 3380 struct sonypi_event { 3381 u8 data; 3382 u8 event; 3383 }; 3384 3385 /* The set of possible button release events */ 3386 static struct sonypi_event sonypi_releaseev[] = { 3387 { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED }, 3388 { 0, 0 } 3389 }; 3390 3391 /* The set of possible jogger events */ 3392 static struct sonypi_event sonypi_joggerev[] = { 3393 { 0x1f, SONYPI_EVENT_JOGDIAL_UP }, 3394 { 0x01, SONYPI_EVENT_JOGDIAL_DOWN }, 3395 { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED }, 3396 { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED }, 3397 { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP }, 3398 { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN }, 3399 { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED }, 3400 { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED }, 3401 { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP }, 3402 { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN }, 3403 { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED }, 3404 { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, 3405 { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED }, 3406 { 0, 0 } 3407 }; 3408 3409 /* The set of possible capture button events */ 3410 static struct sonypi_event sonypi_captureev[] = { 3411 { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED }, 3412 { 0x07, SONYPI_EVENT_CAPTURE_PRESSED }, 3413 { 0x40, SONYPI_EVENT_CAPTURE_PRESSED }, 3414 { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, 3415 { 0, 0 } 3416 }; 3417 3418 /* The set of possible fnkeys events */ 3419 static struct sonypi_event sonypi_fnkeyev[] = { 3420 { 0x10, SONYPI_EVENT_FNKEY_ESC }, 3421 { 0x11, SONYPI_EVENT_FNKEY_F1 }, 3422 { 0x12, SONYPI_EVENT_FNKEY_F2 }, 3423 { 0x13, SONYPI_EVENT_FNKEY_F3 }, 3424 { 0x14, SONYPI_EVENT_FNKEY_F4 }, 3425 { 0x15, SONYPI_EVENT_FNKEY_F5 }, 3426 { 0x16, SONYPI_EVENT_FNKEY_F6 }, 3427 { 0x17, SONYPI_EVENT_FNKEY_F7 }, 3428 { 0x18, SONYPI_EVENT_FNKEY_F8 }, 3429 { 0x19, SONYPI_EVENT_FNKEY_F9 }, 3430 { 0x1a, SONYPI_EVENT_FNKEY_F10 }, 3431 { 0x1b, SONYPI_EVENT_FNKEY_F11 }, 3432 { 0x1c, SONYPI_EVENT_FNKEY_F12 }, 3433 { 0x1f, SONYPI_EVENT_FNKEY_RELEASED }, 3434 { 0x21, SONYPI_EVENT_FNKEY_1 }, 3435 { 0x22, SONYPI_EVENT_FNKEY_2 }, 3436 { 0x31, SONYPI_EVENT_FNKEY_D }, 3437 { 0x32, SONYPI_EVENT_FNKEY_E }, 3438 { 0x33, SONYPI_EVENT_FNKEY_F }, 3439 { 0x34, SONYPI_EVENT_FNKEY_S }, 3440 { 0x35, SONYPI_EVENT_FNKEY_B }, 3441 { 0x36, SONYPI_EVENT_FNKEY_ONLY }, 3442 { 0, 0 } 3443 }; 3444 3445 /* The set of possible program key events */ 3446 static struct sonypi_event sonypi_pkeyev[] = { 3447 { 0x01, SONYPI_EVENT_PKEY_P1 }, 3448 { 0x02, SONYPI_EVENT_PKEY_P2 }, 3449 { 0x04, SONYPI_EVENT_PKEY_P3 }, 3450 { 0x20, SONYPI_EVENT_PKEY_P1 }, 3451 { 0, 0 } 3452 }; 3453 3454 /* The set of possible bluetooth events */ 3455 static struct sonypi_event sonypi_blueev[] = { 3456 { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED }, 3457 { 0x59, SONYPI_EVENT_BLUETOOTH_ON }, 3458 { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF }, 3459 { 0, 0 } 3460 }; 3461 3462 /* The set of possible wireless events */ 3463 static struct sonypi_event sonypi_wlessev[] = { 3464 { 0x59, SONYPI_EVENT_IGNORE }, 3465 { 0x5a, SONYPI_EVENT_IGNORE }, 3466 { 0, 0 } 3467 }; 3468 3469 /* The set of possible back button events */ 3470 static struct sonypi_event sonypi_backev[] = { 3471 { 0x20, SONYPI_EVENT_BACK_PRESSED }, 3472 { 0, 0 } 3473 }; 3474 3475 /* The set of possible help button events */ 3476 static struct sonypi_event sonypi_helpev[] = { 3477 { 0x3b, SONYPI_EVENT_HELP_PRESSED }, 3478 { 0, 0 } 3479 }; 3480 3481 3482 /* The set of possible lid events */ 3483 static struct sonypi_event sonypi_lidev[] = { 3484 { 0x51, SONYPI_EVENT_LID_CLOSED }, 3485 { 0x50, SONYPI_EVENT_LID_OPENED }, 3486 { 0, 0 } 3487 }; 3488 3489 /* The set of possible zoom events */ 3490 static struct sonypi_event sonypi_zoomev[] = { 3491 { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, 3492 { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED }, 3493 { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED }, 3494 { 0x04, SONYPI_EVENT_ZOOM_PRESSED }, 3495 { 0, 0 } 3496 }; 3497 3498 /* The set of possible thumbphrase events */ 3499 static struct sonypi_event sonypi_thumbphraseev[] = { 3500 { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED }, 3501 { 0, 0 } 3502 }; 3503 3504 /* The set of possible motioneye camera events */ 3505 static struct sonypi_event sonypi_meyeev[] = { 3506 { 0x00, SONYPI_EVENT_MEYE_FACE }, 3507 { 0x01, SONYPI_EVENT_MEYE_OPPOSITE }, 3508 { 0, 0 } 3509 }; 3510 3511 /* The set of possible memorystick events */ 3512 static struct sonypi_event sonypi_memorystickev[] = { 3513 { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT }, 3514 { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT }, 3515 { 0, 0 } 3516 }; 3517 3518 /* The set of possible battery events */ 3519 static struct sonypi_event sonypi_batteryev[] = { 3520 { 0x20, SONYPI_EVENT_BATTERY_INSERT }, 3521 { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, 3522 { 0, 0 } 3523 }; 3524 3525 /* The set of possible volume events */ 3526 static struct sonypi_event sonypi_volumeev[] = { 3527 { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED }, 3528 { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED }, 3529 { 0, 0 } 3530 }; 3531 3532 /* The set of possible brightness events */ 3533 static struct sonypi_event sonypi_brightnessev[] = { 3534 { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED }, 3535 { 0, 0 } 3536 }; 3537 3538 static struct sonypi_eventtypes type1_events[] = { 3539 { 0, 0xffffffff, sonypi_releaseev }, 3540 { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, 3541 { 0x30, SONYPI_LID_MASK, sonypi_lidev }, 3542 { 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev }, 3543 { 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev }, 3544 { 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 3545 { 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 3546 { 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, 3547 { 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 3548 { 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, 3549 { 0 }, 3550 }; 3551 static struct sonypi_eventtypes type2_events[] = { 3552 { 0, 0xffffffff, sonypi_releaseev }, 3553 { 0x38, SONYPI_LID_MASK, sonypi_lidev }, 3554 { 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, 3555 { 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, 3556 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 3557 { 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 3558 { 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, 3559 { 0x11, SONYPI_BACK_MASK, sonypi_backev }, 3560 { 0x21, SONYPI_HELP_MASK, sonypi_helpev }, 3561 { 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, 3562 { 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, 3563 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 3564 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 3565 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 3566 { 0 }, 3567 }; 3568 static struct sonypi_eventtypes type3_events[] = { 3569 { 0, 0xffffffff, sonypi_releaseev }, 3570 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 3571 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, 3572 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 3573 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 3574 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 3575 { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev }, 3576 { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev }, 3577 { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev }, 3578 { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev }, 3579 { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev }, 3580 { 0 }, 3581 }; 3582 3583 /* low level spic calls */ 3584 #define ITERATIONS_LONG 10000 3585 #define ITERATIONS_SHORT 10 3586 #define wait_on_command(command, iterations) { \ 3587 unsigned int n = iterations; \ 3588 while (--n && (command)) \ 3589 udelay(1); \ 3590 if (!n) \ 3591 dprintk("command failed at %s : %s (line %d)\n", \ 3592 __FILE__, __func__, __LINE__); \ 3593 } 3594 3595 static u8 sony_pic_call1(u8 dev) 3596 { 3597 u8 v1, v2; 3598 3599 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 3600 ITERATIONS_LONG); 3601 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 3602 v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); 3603 v2 = inb_p(spic_dev.cur_ioport->io1.minimum); 3604 dprintk("sony_pic_call1(0x%.2x): 0x%.4x\n", dev, (v2 << 8) | v1); 3605 return v2; 3606 } 3607 3608 static u8 sony_pic_call2(u8 dev, u8 fn) 3609 { 3610 u8 v1; 3611 3612 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 3613 ITERATIONS_LONG); 3614 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 3615 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 3616 ITERATIONS_LONG); 3617 outb(fn, spic_dev.cur_ioport->io1.minimum); 3618 v1 = inb_p(spic_dev.cur_ioport->io1.minimum); 3619 dprintk("sony_pic_call2(0x%.2x - 0x%.2x): 0x%.4x\n", dev, fn, v1); 3620 return v1; 3621 } 3622 3623 /* 3624 * minidrivers for SPIC models 3625 */ 3626 static int type3_handle_irq(const u8 data_mask, const u8 ev) 3627 { 3628 /* 3629 * 0x31 could mean we have to take some extra action and wait for 3630 * the next irq for some Type3 models, it will generate a new 3631 * irq and we can read new data from the device: 3632 * - 0x5c and 0x5f requires 0xA0 3633 * - 0x61 requires 0xB3 3634 */ 3635 if (data_mask == 0x31) { 3636 if (ev == 0x5c || ev == 0x5f) 3637 sony_pic_call1(0xA0); 3638 else if (ev == 0x61) 3639 sony_pic_call1(0xB3); 3640 return 0; 3641 } 3642 return 1; 3643 } 3644 3645 static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 3646 { 3647 struct pci_dev *pcidev; 3648 3649 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 3650 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 3651 if (pcidev) { 3652 dev->model = SONYPI_DEVICE_TYPE1; 3653 dev->evport_offset = SONYPI_TYPE1_OFFSET; 3654 dev->event_types = type1_events; 3655 goto out; 3656 } 3657 3658 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 3659 PCI_DEVICE_ID_INTEL_ICH6_1, NULL); 3660 if (pcidev) { 3661 dev->model = SONYPI_DEVICE_TYPE2; 3662 dev->evport_offset = SONYPI_TYPE2_OFFSET; 3663 dev->event_types = type2_events; 3664 goto out; 3665 } 3666 3667 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 3668 PCI_DEVICE_ID_INTEL_ICH7_1, NULL); 3669 if (pcidev) { 3670 dev->model = SONYPI_DEVICE_TYPE3; 3671 dev->handle_irq = type3_handle_irq; 3672 dev->evport_offset = SONYPI_TYPE3_OFFSET; 3673 dev->event_types = type3_events; 3674 goto out; 3675 } 3676 3677 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 3678 PCI_DEVICE_ID_INTEL_ICH8_4, NULL); 3679 if (pcidev) { 3680 dev->model = SONYPI_DEVICE_TYPE3; 3681 dev->handle_irq = type3_handle_irq; 3682 dev->evport_offset = SONYPI_TYPE3_OFFSET; 3683 dev->event_types = type3_events; 3684 goto out; 3685 } 3686 3687 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 3688 PCI_DEVICE_ID_INTEL_ICH9_1, NULL); 3689 if (pcidev) { 3690 dev->model = SONYPI_DEVICE_TYPE3; 3691 dev->handle_irq = type3_handle_irq; 3692 dev->evport_offset = SONYPI_TYPE3_OFFSET; 3693 dev->event_types = type3_events; 3694 goto out; 3695 } 3696 3697 /* default */ 3698 dev->model = SONYPI_DEVICE_TYPE2; 3699 dev->evport_offset = SONYPI_TYPE2_OFFSET; 3700 dev->event_types = type2_events; 3701 3702 out: 3703 pci_dev_put(pcidev); 3704 3705 pr_info("detected Type%d model\n", 3706 dev->model == SONYPI_DEVICE_TYPE1 ? 1 : 3707 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); 3708 } 3709 3710 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */ 3711 static void __sony_pic_set_wwanpower(u8 state) 3712 { 3713 state = !!state; 3714 if (spic_dev.wwan_power == state) 3715 return; 3716 sony_pic_call2(0xB0, state); 3717 sony_pic_call1(0x82); 3718 spic_dev.wwan_power = state; 3719 } 3720 3721 static ssize_t sony_pic_wwanpower_store(struct device *dev, 3722 struct device_attribute *attr, 3723 const char *buffer, size_t count) 3724 { 3725 unsigned long value; 3726 if (count > 31) 3727 return -EINVAL; 3728 3729 if (kstrtoul(buffer, 10, &value)) 3730 return -EINVAL; 3731 3732 mutex_lock(&spic_dev.lock); 3733 __sony_pic_set_wwanpower(value); 3734 mutex_unlock(&spic_dev.lock); 3735 3736 return count; 3737 } 3738 3739 static ssize_t sony_pic_wwanpower_show(struct device *dev, 3740 struct device_attribute *attr, char *buffer) 3741 { 3742 ssize_t count; 3743 mutex_lock(&spic_dev.lock); 3744 count = sysfs_emit(buffer, "%d\n", spic_dev.wwan_power); 3745 mutex_unlock(&spic_dev.lock); 3746 return count; 3747 } 3748 3749 /* bluetooth subsystem power state */ 3750 static void __sony_pic_set_bluetoothpower(u8 state) 3751 { 3752 state = !!state; 3753 if (spic_dev.bluetooth_power == state) 3754 return; 3755 sony_pic_call2(0x96, state); 3756 sony_pic_call1(0x82); 3757 spic_dev.bluetooth_power = state; 3758 } 3759 3760 static ssize_t sony_pic_bluetoothpower_store(struct device *dev, 3761 struct device_attribute *attr, 3762 const char *buffer, size_t count) 3763 { 3764 unsigned long value; 3765 if (count > 31) 3766 return -EINVAL; 3767 3768 if (kstrtoul(buffer, 10, &value)) 3769 return -EINVAL; 3770 3771 mutex_lock(&spic_dev.lock); 3772 __sony_pic_set_bluetoothpower(value); 3773 mutex_unlock(&spic_dev.lock); 3774 3775 return count; 3776 } 3777 3778 static ssize_t sony_pic_bluetoothpower_show(struct device *dev, 3779 struct device_attribute *attr, char *buffer) 3780 { 3781 ssize_t count = 0; 3782 mutex_lock(&spic_dev.lock); 3783 count = sysfs_emit(buffer, "%d\n", spic_dev.bluetooth_power); 3784 mutex_unlock(&spic_dev.lock); 3785 return count; 3786 } 3787 3788 /* fan speed */ 3789 /* FAN0 information (reverse engineered from ACPI tables) */ 3790 #define SONY_PIC_FAN0_STATUS 0x93 3791 static int sony_pic_set_fanspeed(unsigned long value) 3792 { 3793 return ec_write(SONY_PIC_FAN0_STATUS, value); 3794 } 3795 3796 static int sony_pic_get_fanspeed(u8 *value) 3797 { 3798 return ec_read(SONY_PIC_FAN0_STATUS, value); 3799 } 3800 3801 static ssize_t sony_pic_fanspeed_store(struct device *dev, 3802 struct device_attribute *attr, 3803 const char *buffer, size_t count) 3804 { 3805 unsigned long value; 3806 if (count > 31) 3807 return -EINVAL; 3808 3809 if (kstrtoul(buffer, 10, &value)) 3810 return -EINVAL; 3811 3812 if (sony_pic_set_fanspeed(value)) 3813 return -EIO; 3814 3815 return count; 3816 } 3817 3818 static ssize_t sony_pic_fanspeed_show(struct device *dev, 3819 struct device_attribute *attr, char *buffer) 3820 { 3821 u8 value = 0; 3822 if (sony_pic_get_fanspeed(&value)) 3823 return -EIO; 3824 3825 return sysfs_emit(buffer, "%d\n", value); 3826 } 3827 3828 #define SPIC_ATTR(_name, _mode) \ 3829 struct device_attribute spic_attr_##_name = __ATTR(_name, \ 3830 _mode, sony_pic_## _name ##_show, \ 3831 sony_pic_## _name ##_store) 3832 3833 static SPIC_ATTR(bluetoothpower, 0644); 3834 static SPIC_ATTR(wwanpower, 0644); 3835 static SPIC_ATTR(fanspeed, 0644); 3836 3837 static struct attribute *spic_attributes[] = { 3838 &spic_attr_bluetoothpower.attr, 3839 &spic_attr_wwanpower.attr, 3840 &spic_attr_fanspeed.attr, 3841 NULL 3842 }; 3843 3844 static const struct attribute_group spic_attribute_group = { 3845 .attrs = spic_attributes 3846 }; 3847 3848 /******** SONYPI compatibility **********/ 3849 #ifdef CONFIG_SONYPI_COMPAT 3850 3851 /* battery / brightness / temperature addresses */ 3852 #define SONYPI_BAT_FLAGS 0x81 3853 #define SONYPI_LCD_LIGHT 0x96 3854 #define SONYPI_BAT1_PCTRM 0xa0 3855 #define SONYPI_BAT1_LEFT 0xa2 3856 #define SONYPI_BAT1_MAXRT 0xa4 3857 #define SONYPI_BAT2_PCTRM 0xa8 3858 #define SONYPI_BAT2_LEFT 0xaa 3859 #define SONYPI_BAT2_MAXRT 0xac 3860 #define SONYPI_BAT1_MAXTK 0xb0 3861 #define SONYPI_BAT1_FULL 0xb2 3862 #define SONYPI_BAT2_MAXTK 0xb8 3863 #define SONYPI_BAT2_FULL 0xba 3864 #define SONYPI_TEMP_STATUS 0xC1 3865 3866 struct sonypi_compat_s { 3867 struct fasync_struct *fifo_async; 3868 struct kfifo fifo; 3869 spinlock_t fifo_lock; 3870 wait_queue_head_t fifo_proc_list; 3871 atomic_t open_count; 3872 }; 3873 static struct sonypi_compat_s sonypi_compat = { 3874 .open_count = ATOMIC_INIT(0), 3875 }; 3876 3877 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 3878 { 3879 return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async); 3880 } 3881 3882 static int sonypi_misc_release(struct inode *inode, struct file *file) 3883 { 3884 atomic_dec(&sonypi_compat.open_count); 3885 return 0; 3886 } 3887 3888 static int sonypi_misc_open(struct inode *inode, struct file *file) 3889 { 3890 /* Flush input queue on first open */ 3891 unsigned long flags; 3892 3893 spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); 3894 3895 if (atomic_inc_return(&sonypi_compat.open_count) == 1) 3896 kfifo_reset(&sonypi_compat.fifo); 3897 3898 spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); 3899 3900 return 0; 3901 } 3902 3903 static ssize_t sonypi_misc_read(struct file *file, char __user *buf, 3904 size_t count, loff_t *pos) 3905 { 3906 ssize_t ret; 3907 unsigned char c; 3908 3909 if ((kfifo_len(&sonypi_compat.fifo) == 0) && 3910 (file->f_flags & O_NONBLOCK)) 3911 return -EAGAIN; 3912 3913 ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, 3914 kfifo_len(&sonypi_compat.fifo) != 0); 3915 if (ret) 3916 return ret; 3917 3918 while (ret < count && 3919 (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c), 3920 &sonypi_compat.fifo_lock) == sizeof(c))) { 3921 if (put_user(c, buf++)) 3922 return -EFAULT; 3923 ret++; 3924 } 3925 3926 if (ret > 0) { 3927 struct inode *inode = file_inode(file); 3928 inode_set_atime_to_ts(inode, current_time(inode)); 3929 } 3930 3931 return ret; 3932 } 3933 3934 static __poll_t sonypi_misc_poll(struct file *file, poll_table *wait) 3935 { 3936 poll_wait(file, &sonypi_compat.fifo_proc_list, wait); 3937 if (kfifo_len(&sonypi_compat.fifo)) 3938 return EPOLLIN | EPOLLRDNORM; 3939 return 0; 3940 } 3941 3942 static int ec_read16(u8 addr, u16 *value) 3943 { 3944 u8 val_lb, val_hb; 3945 if (ec_read(addr, &val_lb)) 3946 return -1; 3947 if (ec_read(addr + 1, &val_hb)) 3948 return -1; 3949 *value = val_lb | (val_hb << 8); 3950 return 0; 3951 } 3952 3953 static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, 3954 unsigned long arg) 3955 { 3956 int ret = 0; 3957 void __user *argp = (void __user *)arg; 3958 u8 val8; 3959 u16 val16; 3960 int value; 3961 3962 mutex_lock(&spic_dev.lock); 3963 switch (cmd) { 3964 case SONYPI_IOCGBRT: 3965 if (sony_bl_props.dev == NULL) { 3966 ret = -EIO; 3967 break; 3968 } 3969 if (sony_nc_int_call(sony_nc_acpi_handle, "GBRT", NULL, 3970 &value)) { 3971 ret = -EIO; 3972 break; 3973 } 3974 val8 = ((value & 0xff) - 1) << 5; 3975 if (copy_to_user(argp, &val8, sizeof(val8))) 3976 ret = -EFAULT; 3977 break; 3978 case SONYPI_IOCSBRT: 3979 if (sony_bl_props.dev == NULL) { 3980 ret = -EIO; 3981 break; 3982 } 3983 if (copy_from_user(&val8, argp, sizeof(val8))) { 3984 ret = -EFAULT; 3985 break; 3986 } 3987 value = (val8 >> 5) + 1; 3988 if (sony_nc_int_call(sony_nc_acpi_handle, "SBRT", &value, 3989 NULL)) { 3990 ret = -EIO; 3991 break; 3992 } 3993 /* sync the backlight device status */ 3994 sony_bl_props.dev->props.brightness = 3995 sony_backlight_get_brightness(sony_bl_props.dev); 3996 break; 3997 case SONYPI_IOCGBAT1CAP: 3998 if (ec_read16(SONYPI_BAT1_FULL, &val16)) { 3999 ret = -EIO; 4000 break; 4001 } 4002 if (copy_to_user(argp, &val16, sizeof(val16))) 4003 ret = -EFAULT; 4004 break; 4005 case SONYPI_IOCGBAT1REM: 4006 if (ec_read16(SONYPI_BAT1_LEFT, &val16)) { 4007 ret = -EIO; 4008 break; 4009 } 4010 if (copy_to_user(argp, &val16, sizeof(val16))) 4011 ret = -EFAULT; 4012 break; 4013 case SONYPI_IOCGBAT2CAP: 4014 if (ec_read16(SONYPI_BAT2_FULL, &val16)) { 4015 ret = -EIO; 4016 break; 4017 } 4018 if (copy_to_user(argp, &val16, sizeof(val16))) 4019 ret = -EFAULT; 4020 break; 4021 case SONYPI_IOCGBAT2REM: 4022 if (ec_read16(SONYPI_BAT2_LEFT, &val16)) { 4023 ret = -EIO; 4024 break; 4025 } 4026 if (copy_to_user(argp, &val16, sizeof(val16))) 4027 ret = -EFAULT; 4028 break; 4029 case SONYPI_IOCGBATFLAGS: 4030 if (ec_read(SONYPI_BAT_FLAGS, &val8)) { 4031 ret = -EIO; 4032 break; 4033 } 4034 val8 &= 0x07; 4035 if (copy_to_user(argp, &val8, sizeof(val8))) 4036 ret = -EFAULT; 4037 break; 4038 case SONYPI_IOCGBLUE: 4039 val8 = spic_dev.bluetooth_power; 4040 if (copy_to_user(argp, &val8, sizeof(val8))) 4041 ret = -EFAULT; 4042 break; 4043 case SONYPI_IOCSBLUE: 4044 if (copy_from_user(&val8, argp, sizeof(val8))) { 4045 ret = -EFAULT; 4046 break; 4047 } 4048 __sony_pic_set_bluetoothpower(val8); 4049 break; 4050 /* FAN Controls */ 4051 case SONYPI_IOCGFAN: 4052 if (sony_pic_get_fanspeed(&val8)) { 4053 ret = -EIO; 4054 break; 4055 } 4056 if (copy_to_user(argp, &val8, sizeof(val8))) 4057 ret = -EFAULT; 4058 break; 4059 case SONYPI_IOCSFAN: 4060 if (copy_from_user(&val8, argp, sizeof(val8))) { 4061 ret = -EFAULT; 4062 break; 4063 } 4064 if (sony_pic_set_fanspeed(val8)) 4065 ret = -EIO; 4066 break; 4067 /* GET Temperature (useful under APM) */ 4068 case SONYPI_IOCGTEMP: 4069 if (ec_read(SONYPI_TEMP_STATUS, &val8)) { 4070 ret = -EIO; 4071 break; 4072 } 4073 if (copy_to_user(argp, &val8, sizeof(val8))) 4074 ret = -EFAULT; 4075 break; 4076 default: 4077 ret = -EINVAL; 4078 } 4079 mutex_unlock(&spic_dev.lock); 4080 return ret; 4081 } 4082 4083 static const struct file_operations sonypi_misc_fops = { 4084 .owner = THIS_MODULE, 4085 .read = sonypi_misc_read, 4086 .poll = sonypi_misc_poll, 4087 .open = sonypi_misc_open, 4088 .release = sonypi_misc_release, 4089 .fasync = sonypi_misc_fasync, 4090 .unlocked_ioctl = sonypi_misc_ioctl, 4091 .llseek = noop_llseek, 4092 }; 4093 4094 static struct miscdevice sonypi_misc_device = { 4095 .minor = MISC_DYNAMIC_MINOR, 4096 .name = "sonypi", 4097 .fops = &sonypi_misc_fops, 4098 }; 4099 4100 static void sonypi_compat_report_event(u8 event) 4101 { 4102 kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event, 4103 sizeof(event), &sonypi_compat.fifo_lock); 4104 kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); 4105 wake_up_interruptible(&sonypi_compat.fifo_proc_list); 4106 } 4107 4108 static int sonypi_compat_init(void) 4109 { 4110 int error; 4111 4112 spin_lock_init(&sonypi_compat.fifo_lock); 4113 error = 4114 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 4115 if (error) { 4116 pr_err("kfifo_alloc failed\n"); 4117 return error; 4118 } 4119 4120 init_waitqueue_head(&sonypi_compat.fifo_proc_list); 4121 4122 if (minor != -1) 4123 sonypi_misc_device.minor = minor; 4124 error = misc_register(&sonypi_misc_device); 4125 if (error) { 4126 pr_err("misc_register failed\n"); 4127 goto err_free_kfifo; 4128 } 4129 if (minor == -1) 4130 pr_info("device allocated minor is %d\n", 4131 sonypi_misc_device.minor); 4132 4133 return 0; 4134 4135 err_free_kfifo: 4136 kfifo_free(&sonypi_compat.fifo); 4137 return error; 4138 } 4139 4140 static void sonypi_compat_exit(void) 4141 { 4142 misc_deregister(&sonypi_misc_device); 4143 kfifo_free(&sonypi_compat.fifo); 4144 } 4145 #else 4146 static int sonypi_compat_init(void) { return 0; } 4147 static void sonypi_compat_exit(void) { } 4148 static void sonypi_compat_report_event(u8 event) { } 4149 #endif /* CONFIG_SONYPI_COMPAT */ 4150 4151 /* 4152 * ACPI callbacks 4153 */ 4154 static acpi_status 4155 sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) 4156 { 4157 u32 i; 4158 struct sony_pic_dev *dev = (struct sony_pic_dev *)context; 4159 4160 switch (resource->type) { 4161 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 4162 { 4163 /* start IO enumeration */ 4164 struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); 4165 if (!ioport) 4166 return AE_ERROR; 4167 4168 list_add(&ioport->list, &dev->ioports); 4169 return AE_OK; 4170 } 4171 4172 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 4173 /* end IO enumeration */ 4174 return AE_OK; 4175 4176 case ACPI_RESOURCE_TYPE_IRQ: 4177 { 4178 struct acpi_resource_irq *p = &resource->data.irq; 4179 struct sony_pic_irq *interrupt = NULL; 4180 if (!p->interrupt_count) { 4181 /* 4182 * IRQ descriptors may have no IRQ# bits set, 4183 * particularly those those w/ _STA disabled 4184 */ 4185 dprintk("Blank IRQ resource\n"); 4186 return AE_OK; 4187 } 4188 for (i = 0; i < p->interrupt_count; i++) { 4189 if (!p->interrupts[i]) { 4190 pr_warn("Invalid IRQ %d\n", 4191 p->interrupts[i]); 4192 continue; 4193 } 4194 interrupt = kzalloc(sizeof(*interrupt), 4195 GFP_KERNEL); 4196 if (!interrupt) 4197 return AE_ERROR; 4198 4199 list_add(&interrupt->list, &dev->interrupts); 4200 interrupt->irq.triggering = p->triggering; 4201 interrupt->irq.polarity = p->polarity; 4202 interrupt->irq.shareable = p->shareable; 4203 interrupt->irq.interrupt_count = 1; 4204 interrupt->irq.interrupts[0] = p->interrupts[i]; 4205 } 4206 return AE_OK; 4207 } 4208 case ACPI_RESOURCE_TYPE_IO: 4209 { 4210 struct acpi_resource_io *io = &resource->data.io; 4211 struct sony_pic_ioport *ioport = 4212 list_first_entry(&dev->ioports, struct sony_pic_ioport, list); 4213 if (!ioport->io1.minimum) { 4214 memcpy(&ioport->io1, io, sizeof(*io)); 4215 dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, 4216 ioport->io1.address_length); 4217 } 4218 else if (!ioport->io2.minimum) { 4219 memcpy(&ioport->io2, io, sizeof(*io)); 4220 dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, 4221 ioport->io2.address_length); 4222 } 4223 else { 4224 pr_err("Unknown SPIC Type, more than 2 IO Ports\n"); 4225 return AE_ERROR; 4226 } 4227 return AE_OK; 4228 } 4229 4230 case ACPI_RESOURCE_TYPE_END_TAG: 4231 return AE_OK; 4232 4233 default: 4234 dprintk("Resource %d isn't an IRQ nor an IO port\n", 4235 resource->type); 4236 return AE_CTRL_TERMINATE; 4237 4238 } 4239 } 4240 4241 static int sony_pic_possible_resources(struct acpi_device *device) 4242 { 4243 int result = 0; 4244 acpi_status status = AE_OK; 4245 4246 if (!device) 4247 return -EINVAL; 4248 4249 /* get device status */ 4250 /* see acpi_pci_link_get_current acpi_pci_link_get_possible */ 4251 dprintk("Evaluating _STA\n"); 4252 result = acpi_bus_get_status(device); 4253 if (result) { 4254 pr_warn("Unable to read status\n"); 4255 goto end; 4256 } 4257 4258 if (!device->status.enabled) 4259 dprintk("Device disabled\n"); 4260 else 4261 dprintk("Device enabled\n"); 4262 4263 /* 4264 * Query and parse 'method' 4265 */ 4266 dprintk("Evaluating %s\n", METHOD_NAME__PRS); 4267 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, 4268 sony_pic_read_possible_resource, &spic_dev); 4269 if (ACPI_FAILURE(status)) { 4270 pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS); 4271 result = -ENODEV; 4272 } 4273 end: 4274 return result; 4275 } 4276 4277 /* 4278 * Disable the spic device by calling its _DIS method 4279 */ 4280 static int sony_pic_disable(struct acpi_device *device) 4281 { 4282 acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL, 4283 NULL); 4284 4285 if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND) 4286 return -ENXIO; 4287 4288 dprintk("Device disabled\n"); 4289 return 0; 4290 } 4291 4292 4293 /* 4294 * Based on drivers/acpi/pci_link.c:acpi_pci_link_set 4295 * 4296 * Call _SRS to set current resources 4297 */ 4298 static int sony_pic_enable(struct acpi_device *device, 4299 struct sony_pic_ioport *ioport, struct sony_pic_irq *irq) 4300 { 4301 acpi_status status; 4302 int result = 0; 4303 /* Type 1 resource layout is: 4304 * IO 4305 * IO 4306 * IRQNoFlags 4307 * End 4308 * 4309 * Type 2 and 3 resource layout is: 4310 * IO 4311 * IRQNoFlags 4312 * End 4313 */ 4314 struct { 4315 struct acpi_resource res1; 4316 struct acpi_resource res2; 4317 struct acpi_resource res3; 4318 struct acpi_resource res4; 4319 } *resource; 4320 struct acpi_buffer buffer = { 0, NULL }; 4321 4322 if (!ioport || !irq) 4323 return -EINVAL; 4324 4325 /* init acpi_buffer */ 4326 resource = kzalloc(sizeof(*resource) + 1, GFP_KERNEL); 4327 if (!resource) 4328 return -ENOMEM; 4329 4330 buffer.length = sizeof(*resource) + 1; 4331 buffer.pointer = resource; 4332 4333 /* setup Type 1 resources */ 4334 if (spic_dev.model == SONYPI_DEVICE_TYPE1) { 4335 4336 /* setup io resources */ 4337 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 4338 resource->res1.length = sizeof(struct acpi_resource); 4339 memcpy(&resource->res1.data.io, &ioport->io1, 4340 sizeof(struct acpi_resource_io)); 4341 4342 resource->res2.type = ACPI_RESOURCE_TYPE_IO; 4343 resource->res2.length = sizeof(struct acpi_resource); 4344 memcpy(&resource->res2.data.io, &ioport->io2, 4345 sizeof(struct acpi_resource_io)); 4346 4347 /* setup irq resource */ 4348 resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; 4349 resource->res3.length = sizeof(struct acpi_resource); 4350 memcpy(&resource->res3.data.irq, &irq->irq, 4351 sizeof(struct acpi_resource_irq)); 4352 /* we requested a shared irq */ 4353 resource->res3.data.irq.shareable = ACPI_SHARED; 4354 4355 resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; 4356 resource->res4.length = sizeof(struct acpi_resource); 4357 } 4358 /* setup Type 2/3 resources */ 4359 else { 4360 /* setup io resource */ 4361 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 4362 resource->res1.length = sizeof(struct acpi_resource); 4363 memcpy(&resource->res1.data.io, &ioport->io1, 4364 sizeof(struct acpi_resource_io)); 4365 4366 /* setup irq resource */ 4367 resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; 4368 resource->res2.length = sizeof(struct acpi_resource); 4369 memcpy(&resource->res2.data.irq, &irq->irq, 4370 sizeof(struct acpi_resource_irq)); 4371 /* we requested a shared irq */ 4372 resource->res2.data.irq.shareable = ACPI_SHARED; 4373 4374 resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; 4375 resource->res3.length = sizeof(struct acpi_resource); 4376 } 4377 4378 /* Attempt to set the resource */ 4379 dprintk("Evaluating _SRS\n"); 4380 status = acpi_set_current_resources(device->handle, &buffer); 4381 4382 /* check for total failure */ 4383 if (ACPI_FAILURE(status)) { 4384 pr_err("Error evaluating _SRS\n"); 4385 result = -ENODEV; 4386 goto end; 4387 } 4388 4389 /* Necessary device initializations calls (from sonypi) */ 4390 sony_pic_call1(0x82); 4391 sony_pic_call2(0x81, 0xff); 4392 sony_pic_call1(compat ? 0x92 : 0x82); 4393 4394 end: 4395 kfree(resource); 4396 return result; 4397 } 4398 4399 /***************** 4400 * 4401 * ISR: some event is available 4402 * 4403 *****************/ 4404 static irqreturn_t sony_pic_irq(int irq, void *dev_id) 4405 { 4406 int i, j; 4407 u8 ev = 0; 4408 u8 data_mask = 0; 4409 u8 device_event = 0; 4410 4411 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; 4412 4413 ev = inb_p(dev->cur_ioport->io1.minimum); 4414 if (dev->cur_ioport->io2.minimum) 4415 data_mask = inb_p(dev->cur_ioport->io2.minimum); 4416 else 4417 data_mask = inb_p(dev->cur_ioport->io1.minimum + 4418 dev->evport_offset); 4419 4420 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 4421 ev, data_mask, dev->cur_ioport->io1.minimum, 4422 dev->evport_offset); 4423 4424 if (ev == 0x00 || ev == 0xff) 4425 return IRQ_HANDLED; 4426 4427 for (i = 0; dev->event_types[i].mask; i++) { 4428 4429 if ((data_mask & dev->event_types[i].data) != 4430 dev->event_types[i].data) 4431 continue; 4432 4433 if (!(mask & dev->event_types[i].mask)) 4434 continue; 4435 4436 for (j = 0; dev->event_types[i].events[j].event; j++) { 4437 if (ev == dev->event_types[i].events[j].data) { 4438 device_event = 4439 dev->event_types[i].events[j].event; 4440 /* some events may require ignoring */ 4441 if (!device_event) 4442 return IRQ_HANDLED; 4443 goto found; 4444 } 4445 } 4446 } 4447 /* Still not able to decode the event try to pass 4448 * it over to the minidriver 4449 */ 4450 if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0) 4451 return IRQ_HANDLED; 4452 4453 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 4454 ev, data_mask, dev->cur_ioport->io1.minimum, 4455 dev->evport_offset); 4456 return IRQ_HANDLED; 4457 4458 found: 4459 sony_laptop_report_input_event(device_event); 4460 sonypi_compat_report_event(device_event); 4461 return IRQ_HANDLED; 4462 } 4463 4464 /***************** 4465 * 4466 * ACPI driver 4467 * 4468 *****************/ 4469 static void sony_pic_remove(struct acpi_device *device) 4470 { 4471 struct sony_pic_ioport *io, *tmp_io; 4472 struct sony_pic_irq *irq, *tmp_irq; 4473 4474 if (sony_pic_disable(device)) { 4475 pr_err("Couldn't disable device\n"); 4476 return; 4477 } 4478 4479 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 4480 release_region(spic_dev.cur_ioport->io1.minimum, 4481 spic_dev.cur_ioport->io1.address_length); 4482 if (spic_dev.cur_ioport->io2.minimum) 4483 release_region(spic_dev.cur_ioport->io2.minimum, 4484 spic_dev.cur_ioport->io2.address_length); 4485 4486 sonypi_compat_exit(); 4487 4488 sony_laptop_remove_input(); 4489 4490 /* pf attrs */ 4491 sysfs_remove_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 4492 sony_pf_remove(); 4493 4494 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 4495 list_del(&io->list); 4496 kfree(io); 4497 } 4498 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 4499 list_del(&irq->list); 4500 kfree(irq); 4501 } 4502 spic_dev.cur_ioport = NULL; 4503 spic_dev.cur_irq = NULL; 4504 4505 dprintk(SONY_PIC_DRIVER_NAME " removed.\n"); 4506 } 4507 4508 static int sony_pic_add(struct acpi_device *device) 4509 { 4510 int result; 4511 struct sony_pic_ioport *io, *tmp_io; 4512 struct sony_pic_irq *irq, *tmp_irq; 4513 4514 spic_dev.acpi_dev = device; 4515 strscpy(acpi_device_class(device), "sony/hotkey"); 4516 sony_pic_detect_device_type(&spic_dev); 4517 mutex_init(&spic_dev.lock); 4518 4519 /* read _PRS resources */ 4520 result = sony_pic_possible_resources(device); 4521 if (result) { 4522 pr_err("Unable to read possible resources\n"); 4523 goto err_free_resources; 4524 } 4525 4526 /* setup input devices and helper fifo */ 4527 result = sony_laptop_setup_input(device); 4528 if (result) { 4529 pr_err("Unable to create input devices\n"); 4530 goto err_free_resources; 4531 } 4532 4533 result = sonypi_compat_init(); 4534 if (result) 4535 goto err_remove_input; 4536 4537 /* request io port */ 4538 list_for_each_entry_reverse(io, &spic_dev.ioports, list) { 4539 if (request_region(io->io1.minimum, io->io1.address_length, 4540 "Sony Programmable I/O Device")) { 4541 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", 4542 io->io1.minimum, io->io1.maximum, 4543 io->io1.address_length); 4544 /* Type 1 have 2 ioports */ 4545 if (io->io2.minimum) { 4546 if (request_region(io->io2.minimum, 4547 io->io2.address_length, 4548 "Sony Programmable I/O Device")) { 4549 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", 4550 io->io2.minimum, io->io2.maximum, 4551 io->io2.address_length); 4552 spic_dev.cur_ioport = io; 4553 break; 4554 } 4555 else { 4556 dprintk("Unable to get I/O port2: " 4557 "0x%.4x (0x%.4x) + 0x%.2x\n", 4558 io->io2.minimum, io->io2.maximum, 4559 io->io2.address_length); 4560 release_region(io->io1.minimum, 4561 io->io1.address_length); 4562 } 4563 } 4564 else { 4565 spic_dev.cur_ioport = io; 4566 break; 4567 } 4568 } 4569 } 4570 if (!spic_dev.cur_ioport) { 4571 pr_err("Failed to request_region\n"); 4572 result = -ENODEV; 4573 goto err_remove_compat; 4574 } 4575 4576 /* request IRQ */ 4577 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { 4578 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, 4579 0, "sony-laptop", &spic_dev)) { 4580 dprintk("IRQ: %d - triggering: %d - " 4581 "polarity: %d - shr: %d\n", 4582 irq->irq.interrupts[0], 4583 irq->irq.triggering, 4584 irq->irq.polarity, 4585 irq->irq.shareable); 4586 spic_dev.cur_irq = irq; 4587 break; 4588 } 4589 } 4590 if (!spic_dev.cur_irq) { 4591 pr_err("Failed to request_irq\n"); 4592 result = -ENODEV; 4593 goto err_release_region; 4594 } 4595 4596 /* set resource status _SRS */ 4597 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 4598 if (result) { 4599 pr_err("Couldn't enable device\n"); 4600 goto err_free_irq; 4601 } 4602 4603 spic_dev.bluetooth_power = -1; 4604 /* create device attributes */ 4605 result = sony_pf_add(); 4606 if (result) 4607 goto err_disable_device; 4608 4609 result = sysfs_create_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 4610 if (result) 4611 goto err_remove_pf; 4612 4613 pr_info("SPIC setup done.\n"); 4614 return 0; 4615 4616 err_remove_pf: 4617 sony_pf_remove(); 4618 4619 err_disable_device: 4620 sony_pic_disable(device); 4621 4622 err_free_irq: 4623 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 4624 4625 err_release_region: 4626 release_region(spic_dev.cur_ioport->io1.minimum, 4627 spic_dev.cur_ioport->io1.address_length); 4628 if (spic_dev.cur_ioport->io2.minimum) 4629 release_region(spic_dev.cur_ioport->io2.minimum, 4630 spic_dev.cur_ioport->io2.address_length); 4631 4632 err_remove_compat: 4633 sonypi_compat_exit(); 4634 4635 err_remove_input: 4636 sony_laptop_remove_input(); 4637 4638 err_free_resources: 4639 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 4640 list_del(&io->list); 4641 kfree(io); 4642 } 4643 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 4644 list_del(&irq->list); 4645 kfree(irq); 4646 } 4647 spic_dev.cur_ioport = NULL; 4648 spic_dev.cur_irq = NULL; 4649 4650 return result; 4651 } 4652 4653 #ifdef CONFIG_PM_SLEEP 4654 static int sony_pic_suspend(struct device *dev) 4655 { 4656 if (sony_pic_disable(to_acpi_device(dev))) 4657 return -ENXIO; 4658 return 0; 4659 } 4660 4661 static int sony_pic_resume(struct device *dev) 4662 { 4663 sony_pic_enable(to_acpi_device(dev), 4664 spic_dev.cur_ioport, spic_dev.cur_irq); 4665 return 0; 4666 } 4667 #endif 4668 4669 static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); 4670 4671 static const struct acpi_device_id sony_pic_device_ids[] = { 4672 {SONY_PIC_HID, 0}, 4673 {"", 0}, 4674 }; 4675 4676 static struct acpi_driver sony_pic_driver = { 4677 .name = SONY_PIC_DRIVER_NAME, 4678 .class = SONY_PIC_CLASS, 4679 .ids = sony_pic_device_ids, 4680 .ops = { 4681 .add = sony_pic_add, 4682 .remove = sony_pic_remove, 4683 }, 4684 .drv.pm = &sony_pic_pm, 4685 }; 4686 4687 static const struct dmi_system_id sonypi_dmi_table[] __initconst = { 4688 { 4689 .ident = "Sony Vaio", 4690 .matches = { 4691 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 4692 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"), 4693 }, 4694 }, 4695 { 4696 .ident = "Sony Vaio", 4697 .matches = { 4698 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 4699 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"), 4700 }, 4701 }, 4702 { } 4703 }; 4704 4705 static int __init sony_laptop_init(void) 4706 { 4707 int result; 4708 4709 if (!no_spic && dmi_check_system(sonypi_dmi_table)) { 4710 result = acpi_bus_register_driver(&sony_pic_driver); 4711 if (result) { 4712 pr_err("Unable to register SPIC driver\n"); 4713 goto out; 4714 } 4715 spic_drv_registered = 1; 4716 } 4717 4718 result = acpi_bus_register_driver(&sony_nc_driver); 4719 if (result) { 4720 pr_err("Unable to register SNC driver\n"); 4721 goto out_unregister_pic; 4722 } 4723 4724 return 0; 4725 4726 out_unregister_pic: 4727 if (spic_drv_registered) 4728 acpi_bus_unregister_driver(&sony_pic_driver); 4729 out: 4730 return result; 4731 } 4732 4733 static void __exit sony_laptop_exit(void) 4734 { 4735 acpi_bus_unregister_driver(&sony_nc_driver); 4736 if (spic_drv_registered) 4737 acpi_bus_unregister_driver(&sony_pic_driver); 4738 } 4739 4740 module_init(sony_laptop_init); 4741 module_exit(sony_laptop_exit); 4742