1 /* 2 * Asus PC WMI hotkey driver 3 * 4 * Copyright(C) 2010 Intel Corporation. 5 * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com> 6 * 7 * Portions based on wistron_btns.c: 8 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> 9 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> 10 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28 29 #include <linux/kernel.h> 30 #include <linux/module.h> 31 #include <linux/init.h> 32 #include <linux/types.h> 33 #include <linux/slab.h> 34 #include <linux/input.h> 35 #include <linux/input/sparse-keymap.h> 36 #include <linux/fb.h> 37 #include <linux/backlight.h> 38 #include <linux/leds.h> 39 #include <linux/rfkill.h> 40 #include <linux/pci.h> 41 #include <linux/pci_hotplug.h> 42 #include <linux/hwmon.h> 43 #include <linux/hwmon-sysfs.h> 44 #include <linux/debugfs.h> 45 #include <linux/seq_file.h> 46 #include <linux/platform_device.h> 47 #include <linux/thermal.h> 48 #include <acpi/acpi_bus.h> 49 #include <acpi/acpi_drivers.h> 50 51 #include "asus-wmi.h" 52 53 MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, " 54 "Yong Wang <yong.y.wang@intel.com>"); 55 MODULE_DESCRIPTION("Asus Generic WMI Driver"); 56 MODULE_LICENSE("GPL"); 57 58 #define to_platform_driver(drv) \ 59 (container_of((drv), struct platform_driver, driver)) 60 61 #define to_asus_wmi_driver(pdrv) \ 62 (container_of((pdrv), struct asus_wmi_driver, platform_driver)) 63 64 #define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" 65 66 #define NOTIFY_BRNUP_MIN 0x11 67 #define NOTIFY_BRNUP_MAX 0x1f 68 #define NOTIFY_BRNDOWN_MIN 0x20 69 #define NOTIFY_BRNDOWN_MAX 0x2e 70 #define NOTIFY_KBD_BRTUP 0xc4 71 #define NOTIFY_KBD_BRTDWN 0xc5 72 73 /* WMI Methods */ 74 #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ 75 #define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */ 76 #define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */ 77 #define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */ 78 #define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */ 79 #define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */ 80 #define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */ 81 #define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */ 82 #define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */ 83 #define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */ 84 #define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */ 85 #define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */ 86 #define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/ 87 #define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */ 88 #define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */ 89 #define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */ 90 #define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */ 91 #define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */ 92 #define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */ 93 94 #define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE 95 96 /* Wireless */ 97 #define ASUS_WMI_DEVID_HW_SWITCH 0x00010001 98 #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 99 #define ASUS_WMI_DEVID_CWAP 0x00010003 100 #define ASUS_WMI_DEVID_WLAN 0x00010011 101 #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 102 #define ASUS_WMI_DEVID_GPS 0x00010015 103 #define ASUS_WMI_DEVID_WIMAX 0x00010017 104 #define ASUS_WMI_DEVID_WWAN3G 0x00010019 105 #define ASUS_WMI_DEVID_UWB 0x00010021 106 107 /* Leds */ 108 /* 0x000200XX and 0x000400XX */ 109 #define ASUS_WMI_DEVID_LED1 0x00020011 110 #define ASUS_WMI_DEVID_LED2 0x00020012 111 #define ASUS_WMI_DEVID_LED3 0x00020013 112 #define ASUS_WMI_DEVID_LED4 0x00020014 113 #define ASUS_WMI_DEVID_LED5 0x00020015 114 #define ASUS_WMI_DEVID_LED6 0x00020016 115 116 /* Backlight and Brightness */ 117 #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011 118 #define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012 119 #define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021 120 #define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */ 121 122 /* Misc */ 123 #define ASUS_WMI_DEVID_CAMERA 0x00060013 124 125 /* Storage */ 126 #define ASUS_WMI_DEVID_CARDREADER 0x00080013 127 128 /* Input */ 129 #define ASUS_WMI_DEVID_TOUCHPAD 0x00100011 130 #define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012 131 132 /* Fan, Thermal */ 133 #define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 134 #define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 135 136 /* Power */ 137 #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 138 139 /* DSTS masks */ 140 #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 141 #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 142 #define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000 143 #define ASUS_WMI_DSTS_USER_BIT 0x00020000 144 #define ASUS_WMI_DSTS_BIOS_BIT 0x00040000 145 #define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF 146 #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00 147 148 struct bios_args { 149 u32 arg0; 150 u32 arg1; 151 } __packed; 152 153 /* 154 * <platform>/ - debugfs root directory 155 * dev_id - current dev_id 156 * ctrl_param - current ctrl_param 157 * method_id - current method_id 158 * devs - call DEVS(dev_id, ctrl_param) and print result 159 * dsts - call DSTS(dev_id) and print result 160 * call - call method_id(dev_id, ctrl_param) and print result 161 */ 162 struct asus_wmi_debug { 163 struct dentry *root; 164 u32 method_id; 165 u32 dev_id; 166 u32 ctrl_param; 167 }; 168 169 struct asus_rfkill { 170 struct asus_wmi *asus; 171 struct rfkill *rfkill; 172 u32 dev_id; 173 }; 174 175 struct asus_wmi { 176 int dsts_id; 177 int spec; 178 int sfun; 179 180 struct input_dev *inputdev; 181 struct backlight_device *backlight_device; 182 struct device *hwmon_device; 183 struct platform_device *platform_device; 184 185 struct led_classdev tpd_led; 186 int tpd_led_wk; 187 struct led_classdev kbd_led; 188 int kbd_led_wk; 189 struct workqueue_struct *led_workqueue; 190 struct work_struct tpd_led_work; 191 struct work_struct kbd_led_work; 192 193 struct asus_rfkill wlan; 194 struct asus_rfkill bluetooth; 195 struct asus_rfkill wimax; 196 struct asus_rfkill wwan3g; 197 struct asus_rfkill gps; 198 struct asus_rfkill uwb; 199 200 struct hotplug_slot *hotplug_slot; 201 struct mutex hotplug_lock; 202 struct mutex wmi_lock; 203 struct workqueue_struct *hotplug_workqueue; 204 struct work_struct hotplug_work; 205 206 struct asus_wmi_debug debug; 207 208 struct asus_wmi_driver *driver; 209 }; 210 211 static int asus_wmi_input_init(struct asus_wmi *asus) 212 { 213 int err; 214 215 asus->inputdev = input_allocate_device(); 216 if (!asus->inputdev) 217 return -ENOMEM; 218 219 asus->inputdev->name = asus->driver->input_name; 220 asus->inputdev->phys = asus->driver->input_phys; 221 asus->inputdev->id.bustype = BUS_HOST; 222 asus->inputdev->dev.parent = &asus->platform_device->dev; 223 set_bit(EV_REP, asus->inputdev->evbit); 224 225 err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL); 226 if (err) 227 goto err_free_dev; 228 229 err = input_register_device(asus->inputdev); 230 if (err) 231 goto err_free_keymap; 232 233 return 0; 234 235 err_free_keymap: 236 sparse_keymap_free(asus->inputdev); 237 err_free_dev: 238 input_free_device(asus->inputdev); 239 return err; 240 } 241 242 static void asus_wmi_input_exit(struct asus_wmi *asus) 243 { 244 if (asus->inputdev) { 245 sparse_keymap_free(asus->inputdev); 246 input_unregister_device(asus->inputdev); 247 } 248 249 asus->inputdev = NULL; 250 } 251 252 static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, 253 u32 *retval) 254 { 255 struct bios_args args = { 256 .arg0 = arg0, 257 .arg1 = arg1, 258 }; 259 struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; 260 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 261 acpi_status status; 262 union acpi_object *obj; 263 u32 tmp; 264 265 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id, 266 &input, &output); 267 268 if (ACPI_FAILURE(status)) 269 goto exit; 270 271 obj = (union acpi_object *)output.pointer; 272 if (obj && obj->type == ACPI_TYPE_INTEGER) 273 tmp = (u32) obj->integer.value; 274 else 275 tmp = 0; 276 277 if (retval) 278 *retval = tmp; 279 280 kfree(obj); 281 282 exit: 283 if (ACPI_FAILURE(status)) 284 return -EIO; 285 286 if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) 287 return -ENODEV; 288 289 return 0; 290 } 291 292 static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval) 293 { 294 return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval); 295 } 296 297 static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, 298 u32 *retval) 299 { 300 return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id, 301 ctrl_param, retval); 302 } 303 304 /* Helper for special devices with magic return codes */ 305 static int asus_wmi_get_devstate_bits(struct asus_wmi *asus, 306 u32 dev_id, u32 mask) 307 { 308 u32 retval = 0; 309 int err; 310 311 err = asus_wmi_get_devstate(asus, dev_id, &retval); 312 313 if (err < 0) 314 return err; 315 316 if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT)) 317 return -ENODEV; 318 319 if (mask == ASUS_WMI_DSTS_STATUS_BIT) { 320 if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT) 321 return -ENODEV; 322 } 323 324 return retval & mask; 325 } 326 327 static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id) 328 { 329 return asus_wmi_get_devstate_bits(asus, dev_id, 330 ASUS_WMI_DSTS_STATUS_BIT); 331 } 332 333 /* 334 * LEDs 335 */ 336 /* 337 * These functions actually update the LED's, and are called from a 338 * workqueue. By doing this as separate work rather than when the LED 339 * subsystem asks, we avoid messing with the Asus ACPI stuff during a 340 * potentially bad time, such as a timer interrupt. 341 */ 342 static void tpd_led_update(struct work_struct *work) 343 { 344 int ctrl_param; 345 struct asus_wmi *asus; 346 347 asus = container_of(work, struct asus_wmi, tpd_led_work); 348 349 ctrl_param = asus->tpd_led_wk; 350 asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL); 351 } 352 353 static void tpd_led_set(struct led_classdev *led_cdev, 354 enum led_brightness value) 355 { 356 struct asus_wmi *asus; 357 358 asus = container_of(led_cdev, struct asus_wmi, tpd_led); 359 360 asus->tpd_led_wk = !!value; 361 queue_work(asus->led_workqueue, &asus->tpd_led_work); 362 } 363 364 static int read_tpd_led_state(struct asus_wmi *asus) 365 { 366 return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED); 367 } 368 369 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev) 370 { 371 struct asus_wmi *asus; 372 373 asus = container_of(led_cdev, struct asus_wmi, tpd_led); 374 375 return read_tpd_led_state(asus); 376 } 377 378 static void kbd_led_update(struct work_struct *work) 379 { 380 int ctrl_param = 0; 381 struct asus_wmi *asus; 382 383 asus = container_of(work, struct asus_wmi, kbd_led_work); 384 385 /* 386 * bits 0-2: level 387 * bit 7: light on/off 388 */ 389 if (asus->kbd_led_wk > 0) 390 ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); 391 392 asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL); 393 } 394 395 static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) 396 { 397 int retval; 398 399 /* 400 * bits 0-2: level 401 * bit 7: light on/off 402 * bit 8-10: environment (0: dark, 1: normal, 2: light) 403 * bit 17: status unknown 404 */ 405 retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT, 406 0xFFFF); 407 408 /* Unknown status is considered as off */ 409 if (retval == 0x8000) 410 retval = 0; 411 412 if (retval >= 0) { 413 if (level) 414 *level = retval & 0x80 ? retval & 0x7F : 0; 415 if (env) 416 *env = (retval >> 8) & 0x7F; 417 retval = 0; 418 } 419 420 return retval; 421 } 422 423 static void kbd_led_set(struct led_classdev *led_cdev, 424 enum led_brightness value) 425 { 426 struct asus_wmi *asus; 427 428 asus = container_of(led_cdev, struct asus_wmi, kbd_led); 429 430 if (value > asus->kbd_led.max_brightness) 431 value = asus->kbd_led.max_brightness; 432 else if (value < 0) 433 value = 0; 434 435 asus->kbd_led_wk = value; 436 queue_work(asus->led_workqueue, &asus->kbd_led_work); 437 } 438 439 static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) 440 { 441 struct asus_wmi *asus; 442 int retval, value; 443 444 asus = container_of(led_cdev, struct asus_wmi, kbd_led); 445 446 retval = kbd_led_read(asus, &value, NULL); 447 448 if (retval < 0) 449 return retval; 450 451 return value; 452 } 453 454 static void asus_wmi_led_exit(struct asus_wmi *asus) 455 { 456 if (!IS_ERR_OR_NULL(asus->kbd_led.dev)) 457 led_classdev_unregister(&asus->kbd_led); 458 if (!IS_ERR_OR_NULL(asus->tpd_led.dev)) 459 led_classdev_unregister(&asus->tpd_led); 460 if (asus->led_workqueue) 461 destroy_workqueue(asus->led_workqueue); 462 } 463 464 static int asus_wmi_led_init(struct asus_wmi *asus) 465 { 466 int rv = 0; 467 468 asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); 469 if (!asus->led_workqueue) 470 return -ENOMEM; 471 472 if (read_tpd_led_state(asus) >= 0) { 473 INIT_WORK(&asus->tpd_led_work, tpd_led_update); 474 475 asus->tpd_led.name = "asus::touchpad"; 476 asus->tpd_led.brightness_set = tpd_led_set; 477 asus->tpd_led.brightness_get = tpd_led_get; 478 asus->tpd_led.max_brightness = 1; 479 480 rv = led_classdev_register(&asus->platform_device->dev, 481 &asus->tpd_led); 482 if (rv) 483 goto error; 484 } 485 486 if (kbd_led_read(asus, NULL, NULL) >= 0) { 487 INIT_WORK(&asus->kbd_led_work, kbd_led_update); 488 489 asus->kbd_led.name = "asus::kbd_backlight"; 490 asus->kbd_led.brightness_set = kbd_led_set; 491 asus->kbd_led.brightness_get = kbd_led_get; 492 asus->kbd_led.max_brightness = 3; 493 494 rv = led_classdev_register(&asus->platform_device->dev, 495 &asus->kbd_led); 496 } 497 498 error: 499 if (rv) 500 asus_wmi_led_exit(asus); 501 502 return rv; 503 } 504 505 506 /* 507 * PCI hotplug (for wlan rfkill) 508 */ 509 static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus) 510 { 511 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); 512 513 if (result < 0) 514 return false; 515 return !result; 516 } 517 518 static void asus_rfkill_hotplug(struct asus_wmi *asus) 519 { 520 struct pci_dev *dev; 521 struct pci_bus *bus; 522 bool blocked; 523 bool absent; 524 u32 l; 525 526 mutex_lock(&asus->wmi_lock); 527 blocked = asus_wlan_rfkill_blocked(asus); 528 mutex_unlock(&asus->wmi_lock); 529 530 mutex_lock(&asus->hotplug_lock); 531 532 if (asus->wlan.rfkill) 533 rfkill_set_sw_state(asus->wlan.rfkill, blocked); 534 535 if (asus->hotplug_slot) { 536 bus = pci_find_bus(0, 1); 537 if (!bus) { 538 pr_warn("Unable to find PCI bus 1?\n"); 539 goto out_unlock; 540 } 541 542 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { 543 pr_err("Unable to read PCI config space?\n"); 544 goto out_unlock; 545 } 546 absent = (l == 0xffffffff); 547 548 if (blocked != absent) { 549 pr_warn("BIOS says wireless lan is %s, " 550 "but the pci device is %s\n", 551 blocked ? "blocked" : "unblocked", 552 absent ? "absent" : "present"); 553 pr_warn("skipped wireless hotplug as probably " 554 "inappropriate for this model\n"); 555 goto out_unlock; 556 } 557 558 if (!blocked) { 559 dev = pci_get_slot(bus, 0); 560 if (dev) { 561 /* Device already present */ 562 pci_dev_put(dev); 563 goto out_unlock; 564 } 565 dev = pci_scan_single_device(bus, 0); 566 if (dev) { 567 pci_bus_assign_resources(bus); 568 if (pci_bus_add_device(dev)) 569 pr_err("Unable to hotplug wifi\n"); 570 } 571 } else { 572 dev = pci_get_slot(bus, 0); 573 if (dev) { 574 pci_remove_bus_device(dev); 575 pci_dev_put(dev); 576 } 577 } 578 } 579 580 out_unlock: 581 mutex_unlock(&asus->hotplug_lock); 582 } 583 584 static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data) 585 { 586 struct asus_wmi *asus = data; 587 588 if (event != ACPI_NOTIFY_BUS_CHECK) 589 return; 590 591 /* 592 * We can't call directly asus_rfkill_hotplug because most 593 * of the time WMBC is still being executed and not reetrant. 594 * There is currently no way to tell ACPICA that we want this 595 * method to be serialized, we schedule a asus_rfkill_hotplug 596 * call later, in a safer context. 597 */ 598 queue_work(asus->hotplug_workqueue, &asus->hotplug_work); 599 } 600 601 static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node) 602 { 603 acpi_status status; 604 acpi_handle handle; 605 606 status = acpi_get_handle(NULL, node, &handle); 607 608 if (ACPI_SUCCESS(status)) { 609 status = acpi_install_notify_handler(handle, 610 ACPI_SYSTEM_NOTIFY, 611 asus_rfkill_notify, asus); 612 if (ACPI_FAILURE(status)) 613 pr_warn("Failed to register notify on %s\n", node); 614 } else 615 return -ENODEV; 616 617 return 0; 618 } 619 620 static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node) 621 { 622 acpi_status status = AE_OK; 623 acpi_handle handle; 624 625 status = acpi_get_handle(NULL, node, &handle); 626 627 if (ACPI_SUCCESS(status)) { 628 status = acpi_remove_notify_handler(handle, 629 ACPI_SYSTEM_NOTIFY, 630 asus_rfkill_notify); 631 if (ACPI_FAILURE(status)) 632 pr_err("Error removing rfkill notify handler %s\n", 633 node); 634 } 635 } 636 637 static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, 638 u8 *value) 639 { 640 struct asus_wmi *asus = hotplug_slot->private; 641 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); 642 643 if (result < 0) 644 return result; 645 646 *value = !!result; 647 return 0; 648 } 649 650 static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) 651 { 652 kfree(hotplug_slot->info); 653 kfree(hotplug_slot); 654 } 655 656 static struct hotplug_slot_ops asus_hotplug_slot_ops = { 657 .owner = THIS_MODULE, 658 .get_adapter_status = asus_get_adapter_status, 659 .get_power_status = asus_get_adapter_status, 660 }; 661 662 static void asus_hotplug_work(struct work_struct *work) 663 { 664 struct asus_wmi *asus; 665 666 asus = container_of(work, struct asus_wmi, hotplug_work); 667 asus_rfkill_hotplug(asus); 668 } 669 670 static int asus_setup_pci_hotplug(struct asus_wmi *asus) 671 { 672 int ret = -ENOMEM; 673 struct pci_bus *bus = pci_find_bus(0, 1); 674 675 if (!bus) { 676 pr_err("Unable to find wifi PCI bus\n"); 677 return -ENODEV; 678 } 679 680 asus->hotplug_workqueue = 681 create_singlethread_workqueue("hotplug_workqueue"); 682 if (!asus->hotplug_workqueue) 683 goto error_workqueue; 684 685 INIT_WORK(&asus->hotplug_work, asus_hotplug_work); 686 687 asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); 688 if (!asus->hotplug_slot) 689 goto error_slot; 690 691 asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), 692 GFP_KERNEL); 693 if (!asus->hotplug_slot->info) 694 goto error_info; 695 696 asus->hotplug_slot->private = asus; 697 asus->hotplug_slot->release = &asus_cleanup_pci_hotplug; 698 asus->hotplug_slot->ops = &asus_hotplug_slot_ops; 699 asus_get_adapter_status(asus->hotplug_slot, 700 &asus->hotplug_slot->info->adapter_status); 701 702 ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi"); 703 if (ret) { 704 pr_err("Unable to register hotplug slot - %d\n", ret); 705 goto error_register; 706 } 707 708 return 0; 709 710 error_register: 711 kfree(asus->hotplug_slot->info); 712 error_info: 713 kfree(asus->hotplug_slot); 714 asus->hotplug_slot = NULL; 715 error_slot: 716 destroy_workqueue(asus->hotplug_workqueue); 717 error_workqueue: 718 return ret; 719 } 720 721 /* 722 * Rfkill devices 723 */ 724 static int asus_rfkill_set(void *data, bool blocked) 725 { 726 struct asus_rfkill *priv = data; 727 u32 ctrl_param = !blocked; 728 729 return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL); 730 } 731 732 static void asus_rfkill_query(struct rfkill *rfkill, void *data) 733 { 734 struct asus_rfkill *priv = data; 735 int result; 736 737 result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id); 738 739 if (result < 0) 740 return; 741 742 rfkill_set_sw_state(priv->rfkill, !result); 743 } 744 745 static int asus_rfkill_wlan_set(void *data, bool blocked) 746 { 747 struct asus_rfkill *priv = data; 748 struct asus_wmi *asus = priv->asus; 749 int ret; 750 751 /* 752 * This handler is enabled only if hotplug is enabled. 753 * In this case, the asus_wmi_set_devstate() will 754 * trigger a wmi notification and we need to wait 755 * this call to finish before being able to call 756 * any wmi method 757 */ 758 mutex_lock(&asus->wmi_lock); 759 ret = asus_rfkill_set(data, blocked); 760 mutex_unlock(&asus->wmi_lock); 761 return ret; 762 } 763 764 static const struct rfkill_ops asus_rfkill_wlan_ops = { 765 .set_block = asus_rfkill_wlan_set, 766 .query = asus_rfkill_query, 767 }; 768 769 static const struct rfkill_ops asus_rfkill_ops = { 770 .set_block = asus_rfkill_set, 771 .query = asus_rfkill_query, 772 }; 773 774 static int asus_new_rfkill(struct asus_wmi *asus, 775 struct asus_rfkill *arfkill, 776 const char *name, enum rfkill_type type, int dev_id) 777 { 778 int result = asus_wmi_get_devstate_simple(asus, dev_id); 779 struct rfkill **rfkill = &arfkill->rfkill; 780 781 if (result < 0) 782 return result; 783 784 arfkill->dev_id = dev_id; 785 arfkill->asus = asus; 786 787 if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless) 788 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type, 789 &asus_rfkill_wlan_ops, arfkill); 790 else 791 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type, 792 &asus_rfkill_ops, arfkill); 793 794 if (!*rfkill) 795 return -EINVAL; 796 797 rfkill_init_sw_state(*rfkill, !result); 798 result = rfkill_register(*rfkill); 799 if (result) { 800 rfkill_destroy(*rfkill); 801 *rfkill = NULL; 802 return result; 803 } 804 return 0; 805 } 806 807 static void asus_wmi_rfkill_exit(struct asus_wmi *asus) 808 { 809 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5"); 810 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6"); 811 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7"); 812 if (asus->wlan.rfkill) { 813 rfkill_unregister(asus->wlan.rfkill); 814 rfkill_destroy(asus->wlan.rfkill); 815 asus->wlan.rfkill = NULL; 816 } 817 /* 818 * Refresh pci hotplug in case the rfkill state was changed after 819 * asus_unregister_rfkill_notifier() 820 */ 821 asus_rfkill_hotplug(asus); 822 if (asus->hotplug_slot) 823 pci_hp_deregister(asus->hotplug_slot); 824 if (asus->hotplug_workqueue) 825 destroy_workqueue(asus->hotplug_workqueue); 826 827 if (asus->bluetooth.rfkill) { 828 rfkill_unregister(asus->bluetooth.rfkill); 829 rfkill_destroy(asus->bluetooth.rfkill); 830 asus->bluetooth.rfkill = NULL; 831 } 832 if (asus->wimax.rfkill) { 833 rfkill_unregister(asus->wimax.rfkill); 834 rfkill_destroy(asus->wimax.rfkill); 835 asus->wimax.rfkill = NULL; 836 } 837 if (asus->wwan3g.rfkill) { 838 rfkill_unregister(asus->wwan3g.rfkill); 839 rfkill_destroy(asus->wwan3g.rfkill); 840 asus->wwan3g.rfkill = NULL; 841 } 842 if (asus->gps.rfkill) { 843 rfkill_unregister(asus->gps.rfkill); 844 rfkill_destroy(asus->gps.rfkill); 845 asus->gps.rfkill = NULL; 846 } 847 if (asus->uwb.rfkill) { 848 rfkill_unregister(asus->uwb.rfkill); 849 rfkill_destroy(asus->uwb.rfkill); 850 asus->uwb.rfkill = NULL; 851 } 852 } 853 854 static int asus_wmi_rfkill_init(struct asus_wmi *asus) 855 { 856 int result = 0; 857 858 mutex_init(&asus->hotplug_lock); 859 mutex_init(&asus->wmi_lock); 860 861 result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan", 862 RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN); 863 864 if (result && result != -ENODEV) 865 goto exit; 866 867 result = asus_new_rfkill(asus, &asus->bluetooth, 868 "asus-bluetooth", RFKILL_TYPE_BLUETOOTH, 869 ASUS_WMI_DEVID_BLUETOOTH); 870 871 if (result && result != -ENODEV) 872 goto exit; 873 874 result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax", 875 RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX); 876 877 if (result && result != -ENODEV) 878 goto exit; 879 880 result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g", 881 RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G); 882 883 if (result && result != -ENODEV) 884 goto exit; 885 886 result = asus_new_rfkill(asus, &asus->gps, "asus-gps", 887 RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS); 888 889 if (result && result != -ENODEV) 890 goto exit; 891 892 result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb", 893 RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB); 894 895 if (result && result != -ENODEV) 896 goto exit; 897 898 if (!asus->driver->hotplug_wireless) 899 goto exit; 900 901 result = asus_setup_pci_hotplug(asus); 902 /* 903 * If we get -EBUSY then something else is handling the PCI hotplug - 904 * don't fail in this case 905 */ 906 if (result == -EBUSY) 907 result = 0; 908 909 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5"); 910 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6"); 911 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7"); 912 /* 913 * Refresh pci hotplug in case the rfkill state was changed during 914 * setup. 915 */ 916 asus_rfkill_hotplug(asus); 917 918 exit: 919 if (result && result != -ENODEV) 920 asus_wmi_rfkill_exit(asus); 921 922 if (result == -ENODEV) 923 result = 0; 924 925 return result; 926 } 927 928 /* 929 * Hwmon device 930 */ 931 static ssize_t asus_hwmon_pwm1(struct device *dev, 932 struct device_attribute *attr, 933 char *buf) 934 { 935 struct asus_wmi *asus = dev_get_drvdata(dev); 936 u32 value; 937 int err; 938 939 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value); 940 941 if (err < 0) 942 return err; 943 944 value &= 0xFF; 945 946 if (value == 1) /* Low Speed */ 947 value = 85; 948 else if (value == 2) 949 value = 170; 950 else if (value == 3) 951 value = 255; 952 else if (value != 0) { 953 pr_err("Unknown fan speed %#x", value); 954 value = -1; 955 } 956 957 return sprintf(buf, "%d\n", value); 958 } 959 960 static ssize_t asus_hwmon_temp1(struct device *dev, 961 struct device_attribute *attr, 962 char *buf) 963 { 964 struct asus_wmi *asus = dev_get_drvdata(dev); 965 u32 value; 966 int err; 967 968 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value); 969 970 if (err < 0) 971 return err; 972 973 value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000; 974 975 return sprintf(buf, "%d\n", value); 976 } 977 978 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0); 979 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0); 980 981 static ssize_t 982 show_name(struct device *dev, struct device_attribute *attr, char *buf) 983 { 984 return sprintf(buf, "asus\n"); 985 } 986 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); 987 988 static struct attribute *hwmon_attributes[] = { 989 &sensor_dev_attr_pwm1.dev_attr.attr, 990 &sensor_dev_attr_temp1_input.dev_attr.attr, 991 &sensor_dev_attr_name.dev_attr.attr, 992 NULL 993 }; 994 995 static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, 996 struct attribute *attr, int idx) 997 { 998 struct device *dev = container_of(kobj, struct device, kobj); 999 struct platform_device *pdev = to_platform_device(dev->parent); 1000 struct asus_wmi *asus = platform_get_drvdata(pdev); 1001 bool ok = true; 1002 int dev_id = -1; 1003 u32 value = ASUS_WMI_UNSUPPORTED_METHOD; 1004 1005 if (attr == &sensor_dev_attr_pwm1.dev_attr.attr) 1006 dev_id = ASUS_WMI_DEVID_FAN_CTRL; 1007 else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr) 1008 dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; 1009 1010 if (dev_id != -1) { 1011 int err = asus_wmi_get_devstate(asus, dev_id, &value); 1012 1013 if (err < 0) 1014 return 0; /* can't return negative here */ 1015 } 1016 1017 if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) { 1018 /* 1019 * We need to find a better way, probably using sfun, 1020 * bits or spec ... 1021 * Currently we disable it if: 1022 * - ASUS_WMI_UNSUPPORTED_METHOD is returned 1023 * - reverved bits are non-zero 1024 * - sfun and presence bit are not set 1025 */ 1026 if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 1027 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) 1028 ok = false; 1029 } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) { 1030 /* If value is zero, something is clearly wrong */ 1031 if (value == 0) 1032 ok = false; 1033 } 1034 1035 return ok ? attr->mode : 0; 1036 } 1037 1038 static struct attribute_group hwmon_attribute_group = { 1039 .is_visible = asus_hwmon_sysfs_is_visible, 1040 .attrs = hwmon_attributes 1041 }; 1042 1043 static void asus_wmi_hwmon_exit(struct asus_wmi *asus) 1044 { 1045 struct device *hwmon; 1046 1047 hwmon = asus->hwmon_device; 1048 if (!hwmon) 1049 return; 1050 sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group); 1051 hwmon_device_unregister(hwmon); 1052 asus->hwmon_device = NULL; 1053 } 1054 1055 static int asus_wmi_hwmon_init(struct asus_wmi *asus) 1056 { 1057 struct device *hwmon; 1058 int result; 1059 1060 hwmon = hwmon_device_register(&asus->platform_device->dev); 1061 if (IS_ERR(hwmon)) { 1062 pr_err("Could not register asus hwmon device\n"); 1063 return PTR_ERR(hwmon); 1064 } 1065 dev_set_drvdata(hwmon, asus); 1066 asus->hwmon_device = hwmon; 1067 result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); 1068 if (result) 1069 asus_wmi_hwmon_exit(asus); 1070 return result; 1071 } 1072 1073 /* 1074 * Backlight 1075 */ 1076 static int read_backlight_power(struct asus_wmi *asus) 1077 { 1078 int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT); 1079 1080 if (ret < 0) 1081 return ret; 1082 1083 return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 1084 } 1085 1086 static int read_brightness_max(struct asus_wmi *asus) 1087 { 1088 u32 retval; 1089 int err; 1090 1091 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); 1092 1093 if (err < 0) 1094 return err; 1095 1096 retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK; 1097 retval >>= 8; 1098 1099 if (!retval) 1100 return -ENODEV; 1101 1102 return retval; 1103 } 1104 1105 static int read_brightness(struct backlight_device *bd) 1106 { 1107 struct asus_wmi *asus = bl_get_data(bd); 1108 u32 retval; 1109 int err; 1110 1111 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); 1112 1113 if (err < 0) 1114 return err; 1115 1116 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK; 1117 } 1118 1119 static int update_bl_status(struct backlight_device *bd) 1120 { 1121 struct asus_wmi *asus = bl_get_data(bd); 1122 u32 ctrl_param; 1123 int power, err; 1124 1125 ctrl_param = bd->props.brightness; 1126 1127 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS, 1128 ctrl_param, NULL); 1129 1130 if (err < 0) 1131 return err; 1132 1133 power = read_backlight_power(asus); 1134 if (power != -ENODEV && bd->props.power != power) { 1135 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK); 1136 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 1137 ctrl_param, NULL); 1138 } 1139 return err; 1140 } 1141 1142 static const struct backlight_ops asus_wmi_bl_ops = { 1143 .get_brightness = read_brightness, 1144 .update_status = update_bl_status, 1145 }; 1146 1147 static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code) 1148 { 1149 struct backlight_device *bd = asus->backlight_device; 1150 int old = bd->props.brightness; 1151 int new = old; 1152 1153 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) 1154 new = code - NOTIFY_BRNUP_MIN + 1; 1155 else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) 1156 new = code - NOTIFY_BRNDOWN_MIN; 1157 1158 bd->props.brightness = new; 1159 backlight_update_status(bd); 1160 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); 1161 1162 return old; 1163 } 1164 1165 static int asus_wmi_backlight_init(struct asus_wmi *asus) 1166 { 1167 struct backlight_device *bd; 1168 struct backlight_properties props; 1169 int max; 1170 int power; 1171 1172 max = read_brightness_max(asus); 1173 1174 if (max == -ENODEV) 1175 max = 0; 1176 else if (max < 0) 1177 return max; 1178 1179 power = read_backlight_power(asus); 1180 1181 if (power == -ENODEV) 1182 power = FB_BLANK_UNBLANK; 1183 else if (power < 0) 1184 return power; 1185 1186 memset(&props, 0, sizeof(struct backlight_properties)); 1187 props.type = BACKLIGHT_PLATFORM; 1188 props.max_brightness = max; 1189 bd = backlight_device_register(asus->driver->name, 1190 &asus->platform_device->dev, asus, 1191 &asus_wmi_bl_ops, &props); 1192 if (IS_ERR(bd)) { 1193 pr_err("Could not register backlight device\n"); 1194 return PTR_ERR(bd); 1195 } 1196 1197 asus->backlight_device = bd; 1198 1199 bd->props.brightness = read_brightness(bd); 1200 bd->props.power = power; 1201 backlight_update_status(bd); 1202 1203 return 0; 1204 } 1205 1206 static void asus_wmi_backlight_exit(struct asus_wmi *asus) 1207 { 1208 if (asus->backlight_device) 1209 backlight_device_unregister(asus->backlight_device); 1210 1211 asus->backlight_device = NULL; 1212 } 1213 1214 static void asus_wmi_notify(u32 value, void *context) 1215 { 1216 struct asus_wmi *asus = context; 1217 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 1218 union acpi_object *obj; 1219 acpi_status status; 1220 int code; 1221 int orig_code; 1222 unsigned int key_value = 1; 1223 bool autorelease = 1; 1224 1225 status = wmi_get_event_data(value, &response); 1226 if (status != AE_OK) { 1227 pr_err("bad event status 0x%x\n", status); 1228 return; 1229 } 1230 1231 obj = (union acpi_object *)response.pointer; 1232 1233 if (!obj || obj->type != ACPI_TYPE_INTEGER) 1234 goto exit; 1235 1236 code = obj->integer.value; 1237 orig_code = code; 1238 1239 if (asus->driver->key_filter) { 1240 asus->driver->key_filter(asus->driver, &code, &key_value, 1241 &autorelease); 1242 if (code == ASUS_WMI_KEY_IGNORE) 1243 goto exit; 1244 } 1245 1246 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) 1247 code = NOTIFY_BRNUP_MIN; 1248 else if (code >= NOTIFY_BRNDOWN_MIN && 1249 code <= NOTIFY_BRNDOWN_MAX) 1250 code = NOTIFY_BRNDOWN_MIN; 1251 1252 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { 1253 if (!acpi_video_backlight_support()) 1254 asus_wmi_backlight_notify(asus, orig_code); 1255 } else if (!sparse_keymap_report_event(asus->inputdev, code, 1256 key_value, autorelease)) 1257 pr_info("Unknown key %x pressed\n", code); 1258 1259 exit: 1260 kfree(obj); 1261 } 1262 1263 /* 1264 * Sys helpers 1265 */ 1266 static int parse_arg(const char *buf, unsigned long count, int *val) 1267 { 1268 if (!count) 1269 return 0; 1270 if (sscanf(buf, "%i", val) != 1) 1271 return -EINVAL; 1272 return count; 1273 } 1274 1275 static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid, 1276 const char *buf, size_t count) 1277 { 1278 u32 retval; 1279 int rv, err, value; 1280 1281 value = asus_wmi_get_devstate_simple(asus, devid); 1282 if (value == -ENODEV) /* Check device presence */ 1283 return value; 1284 1285 rv = parse_arg(buf, count, &value); 1286 err = asus_wmi_set_devstate(devid, value, &retval); 1287 1288 if (err < 0) 1289 return err; 1290 1291 return rv; 1292 } 1293 1294 static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf) 1295 { 1296 int value = asus_wmi_get_devstate_simple(asus, devid); 1297 1298 if (value < 0) 1299 return value; 1300 1301 return sprintf(buf, "%d\n", value); 1302 } 1303 1304 #define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \ 1305 static ssize_t show_##_name(struct device *dev, \ 1306 struct device_attribute *attr, \ 1307 char *buf) \ 1308 { \ 1309 struct asus_wmi *asus = dev_get_drvdata(dev); \ 1310 \ 1311 return show_sys_wmi(asus, _cm, buf); \ 1312 } \ 1313 static ssize_t store_##_name(struct device *dev, \ 1314 struct device_attribute *attr, \ 1315 const char *buf, size_t count) \ 1316 { \ 1317 struct asus_wmi *asus = dev_get_drvdata(dev); \ 1318 \ 1319 return store_sys_wmi(asus, _cm, buf, count); \ 1320 } \ 1321 static struct device_attribute dev_attr_##_name = { \ 1322 .attr = { \ 1323 .name = __stringify(_name), \ 1324 .mode = _mode }, \ 1325 .show = show_##_name, \ 1326 .store = store_##_name, \ 1327 } 1328 1329 ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD); 1330 ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA); 1331 ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); 1332 1333 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, 1334 const char *buf, size_t count) 1335 { 1336 int value, rv; 1337 1338 if (!count || sscanf(buf, "%i", &value) != 1) 1339 return -EINVAL; 1340 if (value < 0 || value > 2) 1341 return -EINVAL; 1342 1343 rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); 1344 if (rv < 0) 1345 return rv; 1346 1347 return count; 1348 } 1349 1350 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); 1351 1352 static struct attribute *platform_attributes[] = { 1353 &dev_attr_cpufv.attr, 1354 &dev_attr_camera.attr, 1355 &dev_attr_cardr.attr, 1356 &dev_attr_touchpad.attr, 1357 NULL 1358 }; 1359 1360 static umode_t asus_sysfs_is_visible(struct kobject *kobj, 1361 struct attribute *attr, int idx) 1362 { 1363 struct device *dev = container_of(kobj, struct device, kobj); 1364 struct platform_device *pdev = to_platform_device(dev); 1365 struct asus_wmi *asus = platform_get_drvdata(pdev); 1366 bool ok = true; 1367 int devid = -1; 1368 1369 if (attr == &dev_attr_camera.attr) 1370 devid = ASUS_WMI_DEVID_CAMERA; 1371 else if (attr == &dev_attr_cardr.attr) 1372 devid = ASUS_WMI_DEVID_CARDREADER; 1373 else if (attr == &dev_attr_touchpad.attr) 1374 devid = ASUS_WMI_DEVID_TOUCHPAD; 1375 1376 if (devid != -1) 1377 ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); 1378 1379 return ok ? attr->mode : 0; 1380 } 1381 1382 static struct attribute_group platform_attribute_group = { 1383 .is_visible = asus_sysfs_is_visible, 1384 .attrs = platform_attributes 1385 }; 1386 1387 static void asus_wmi_sysfs_exit(struct platform_device *device) 1388 { 1389 sysfs_remove_group(&device->dev.kobj, &platform_attribute_group); 1390 } 1391 1392 static int asus_wmi_sysfs_init(struct platform_device *device) 1393 { 1394 return sysfs_create_group(&device->dev.kobj, &platform_attribute_group); 1395 } 1396 1397 /* 1398 * Platform device 1399 */ 1400 static int asus_wmi_platform_init(struct asus_wmi *asus) 1401 { 1402 int rv; 1403 1404 /* INIT enable hotkeys on some models */ 1405 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv)) 1406 pr_info("Initialization: %#x", rv); 1407 1408 /* We don't know yet what to do with this version... */ 1409 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { 1410 pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); 1411 asus->spec = rv; 1412 } 1413 1414 /* 1415 * The SFUN method probably allows the original driver to get the list 1416 * of features supported by a given model. For now, 0x0100 or 0x0800 1417 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. 1418 * The significance of others is yet to be found. 1419 */ 1420 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) { 1421 pr_info("SFUN value: %#x", rv); 1422 asus->sfun = rv; 1423 } 1424 1425 /* 1426 * Eee PC and Notebooks seems to have different method_id for DSTS, 1427 * but it may also be related to the BIOS's SPEC. 1428 * Note, on most Eeepc, there is no way to check if a method exist 1429 * or note, while on notebooks, they returns 0xFFFFFFFE on failure, 1430 * but once again, SPEC may probably be used for that kind of things. 1431 */ 1432 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL)) 1433 asus->dsts_id = ASUS_WMI_METHODID_DSTS; 1434 else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL)) 1435 asus->dsts_id = ASUS_WMI_METHODID_DSTS2; 1436 1437 if (!asus->dsts_id) { 1438 pr_err("Can't find DSTS"); 1439 return -ENODEV; 1440 } 1441 1442 /* CWAP allow to define the behavior of the Fn+F2 key, 1443 * this method doesn't seems to be present on Eee PCs */ 1444 if (asus->driver->wapf >= 0) 1445 asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP, 1446 asus->driver->wapf, NULL); 1447 1448 return asus_wmi_sysfs_init(asus->platform_device); 1449 } 1450 1451 static void asus_wmi_platform_exit(struct asus_wmi *asus) 1452 { 1453 asus_wmi_sysfs_exit(asus->platform_device); 1454 } 1455 1456 /* 1457 * debugfs 1458 */ 1459 struct asus_wmi_debugfs_node { 1460 struct asus_wmi *asus; 1461 char *name; 1462 int (*show) (struct seq_file *m, void *data); 1463 }; 1464 1465 static int show_dsts(struct seq_file *m, void *data) 1466 { 1467 struct asus_wmi *asus = m->private; 1468 int err; 1469 u32 retval = -1; 1470 1471 err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); 1472 1473 if (err < 0) 1474 return err; 1475 1476 seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval); 1477 1478 return 0; 1479 } 1480 1481 static int show_devs(struct seq_file *m, void *data) 1482 { 1483 struct asus_wmi *asus = m->private; 1484 int err; 1485 u32 retval = -1; 1486 1487 err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, 1488 &retval); 1489 1490 if (err < 0) 1491 return err; 1492 1493 seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id, 1494 asus->debug.ctrl_param, retval); 1495 1496 return 0; 1497 } 1498 1499 static int show_call(struct seq_file *m, void *data) 1500 { 1501 struct asus_wmi *asus = m->private; 1502 struct bios_args args = { 1503 .arg0 = asus->debug.dev_id, 1504 .arg1 = asus->debug.ctrl_param, 1505 }; 1506 struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; 1507 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1508 union acpi_object *obj; 1509 acpi_status status; 1510 1511 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1512 1, asus->debug.method_id, 1513 &input, &output); 1514 1515 if (ACPI_FAILURE(status)) 1516 return -EIO; 1517 1518 obj = (union acpi_object *)output.pointer; 1519 if (obj && obj->type == ACPI_TYPE_INTEGER) 1520 seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id, 1521 asus->debug.dev_id, asus->debug.ctrl_param, 1522 (u32) obj->integer.value); 1523 else 1524 seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id, 1525 asus->debug.dev_id, asus->debug.ctrl_param, 1526 obj ? obj->type : -1); 1527 1528 kfree(obj); 1529 1530 return 0; 1531 } 1532 1533 static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = { 1534 {NULL, "devs", show_devs}, 1535 {NULL, "dsts", show_dsts}, 1536 {NULL, "call", show_call}, 1537 }; 1538 1539 static int asus_wmi_debugfs_open(struct inode *inode, struct file *file) 1540 { 1541 struct asus_wmi_debugfs_node *node = inode->i_private; 1542 1543 return single_open(file, node->show, node->asus); 1544 } 1545 1546 static const struct file_operations asus_wmi_debugfs_io_ops = { 1547 .owner = THIS_MODULE, 1548 .open = asus_wmi_debugfs_open, 1549 .read = seq_read, 1550 .llseek = seq_lseek, 1551 .release = single_release, 1552 }; 1553 1554 static void asus_wmi_debugfs_exit(struct asus_wmi *asus) 1555 { 1556 debugfs_remove_recursive(asus->debug.root); 1557 } 1558 1559 static int asus_wmi_debugfs_init(struct asus_wmi *asus) 1560 { 1561 struct dentry *dent; 1562 int i; 1563 1564 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL); 1565 if (!asus->debug.root) { 1566 pr_err("failed to create debugfs directory"); 1567 goto error_debugfs; 1568 } 1569 1570 dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR, 1571 asus->debug.root, &asus->debug.method_id); 1572 if (!dent) 1573 goto error_debugfs; 1574 1575 dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR, 1576 asus->debug.root, &asus->debug.dev_id); 1577 if (!dent) 1578 goto error_debugfs; 1579 1580 dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR, 1581 asus->debug.root, &asus->debug.ctrl_param); 1582 if (!dent) 1583 goto error_debugfs; 1584 1585 for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) { 1586 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i]; 1587 1588 node->asus = asus; 1589 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO, 1590 asus->debug.root, node, 1591 &asus_wmi_debugfs_io_ops); 1592 if (!dent) { 1593 pr_err("failed to create debug file: %s\n", node->name); 1594 goto error_debugfs; 1595 } 1596 } 1597 1598 return 0; 1599 1600 error_debugfs: 1601 asus_wmi_debugfs_exit(asus); 1602 return -ENOMEM; 1603 } 1604 1605 /* 1606 * WMI Driver 1607 */ 1608 static int asus_wmi_add(struct platform_device *pdev) 1609 { 1610 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); 1611 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); 1612 struct asus_wmi *asus; 1613 acpi_status status; 1614 int err; 1615 1616 asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); 1617 if (!asus) 1618 return -ENOMEM; 1619 1620 asus->driver = wdrv; 1621 asus->platform_device = pdev; 1622 wdrv->platform_device = pdev; 1623 platform_set_drvdata(asus->platform_device, asus); 1624 1625 if (wdrv->quirks) 1626 wdrv->quirks(asus->driver); 1627 1628 err = asus_wmi_platform_init(asus); 1629 if (err) 1630 goto fail_platform; 1631 1632 err = asus_wmi_input_init(asus); 1633 if (err) 1634 goto fail_input; 1635 1636 err = asus_wmi_hwmon_init(asus); 1637 if (err) 1638 goto fail_hwmon; 1639 1640 err = asus_wmi_led_init(asus); 1641 if (err) 1642 goto fail_leds; 1643 1644 err = asus_wmi_rfkill_init(asus); 1645 if (err) 1646 goto fail_rfkill; 1647 1648 if (!acpi_video_backlight_support()) { 1649 err = asus_wmi_backlight_init(asus); 1650 if (err && err != -ENODEV) 1651 goto fail_backlight; 1652 } else 1653 pr_info("Backlight controlled by ACPI video driver\n"); 1654 1655 status = wmi_install_notify_handler(asus->driver->event_guid, 1656 asus_wmi_notify, asus); 1657 if (ACPI_FAILURE(status)) { 1658 pr_err("Unable to register notify handler - %d\n", status); 1659 err = -ENODEV; 1660 goto fail_wmi_handler; 1661 } 1662 1663 err = asus_wmi_debugfs_init(asus); 1664 if (err) 1665 goto fail_debugfs; 1666 1667 return 0; 1668 1669 fail_debugfs: 1670 wmi_remove_notify_handler(asus->driver->event_guid); 1671 fail_wmi_handler: 1672 asus_wmi_backlight_exit(asus); 1673 fail_backlight: 1674 asus_wmi_rfkill_exit(asus); 1675 fail_rfkill: 1676 asus_wmi_led_exit(asus); 1677 fail_leds: 1678 asus_wmi_hwmon_exit(asus); 1679 fail_hwmon: 1680 asus_wmi_input_exit(asus); 1681 fail_input: 1682 asus_wmi_platform_exit(asus); 1683 fail_platform: 1684 kfree(asus); 1685 return err; 1686 } 1687 1688 static int asus_wmi_remove(struct platform_device *device) 1689 { 1690 struct asus_wmi *asus; 1691 1692 asus = platform_get_drvdata(device); 1693 wmi_remove_notify_handler(asus->driver->event_guid); 1694 asus_wmi_backlight_exit(asus); 1695 asus_wmi_input_exit(asus); 1696 asus_wmi_hwmon_exit(asus); 1697 asus_wmi_led_exit(asus); 1698 asus_wmi_rfkill_exit(asus); 1699 asus_wmi_debugfs_exit(asus); 1700 asus_wmi_platform_exit(asus); 1701 1702 kfree(asus); 1703 return 0; 1704 } 1705 1706 /* 1707 * Platform driver - hibernate/resume callbacks 1708 */ 1709 static int asus_hotk_thaw(struct device *device) 1710 { 1711 struct asus_wmi *asus = dev_get_drvdata(device); 1712 1713 if (asus->wlan.rfkill) { 1714 bool wlan; 1715 1716 /* 1717 * Work around bios bug - acpi _PTS turns off the wireless led 1718 * during suspend. Normally it restores it on resume, but 1719 * we should kick it ourselves in case hibernation is aborted. 1720 */ 1721 wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); 1722 asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL); 1723 } 1724 1725 return 0; 1726 } 1727 1728 static int asus_hotk_restore(struct device *device) 1729 { 1730 struct asus_wmi *asus = dev_get_drvdata(device); 1731 int bl; 1732 1733 /* Refresh both wlan rfkill state and pci hotplug */ 1734 if (asus->wlan.rfkill) 1735 asus_rfkill_hotplug(asus); 1736 1737 if (asus->bluetooth.rfkill) { 1738 bl = !asus_wmi_get_devstate_simple(asus, 1739 ASUS_WMI_DEVID_BLUETOOTH); 1740 rfkill_set_sw_state(asus->bluetooth.rfkill, bl); 1741 } 1742 if (asus->wimax.rfkill) { 1743 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX); 1744 rfkill_set_sw_state(asus->wimax.rfkill, bl); 1745 } 1746 if (asus->wwan3g.rfkill) { 1747 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G); 1748 rfkill_set_sw_state(asus->wwan3g.rfkill, bl); 1749 } 1750 if (asus->gps.rfkill) { 1751 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS); 1752 rfkill_set_sw_state(asus->gps.rfkill, bl); 1753 } 1754 if (asus->uwb.rfkill) { 1755 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB); 1756 rfkill_set_sw_state(asus->uwb.rfkill, bl); 1757 } 1758 1759 return 0; 1760 } 1761 1762 static const struct dev_pm_ops asus_pm_ops = { 1763 .thaw = asus_hotk_thaw, 1764 .restore = asus_hotk_restore, 1765 }; 1766 1767 static int asus_wmi_probe(struct platform_device *pdev) 1768 { 1769 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); 1770 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); 1771 int ret; 1772 1773 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { 1774 pr_warn("Management GUID not found\n"); 1775 return -ENODEV; 1776 } 1777 1778 if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { 1779 pr_warn("Event GUID not found\n"); 1780 return -ENODEV; 1781 } 1782 1783 if (wdrv->probe) { 1784 ret = wdrv->probe(pdev); 1785 if (ret) 1786 return ret; 1787 } 1788 1789 return asus_wmi_add(pdev); 1790 } 1791 1792 static bool used; 1793 1794 int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver) 1795 { 1796 struct platform_driver *platform_driver; 1797 struct platform_device *platform_device; 1798 1799 if (used) 1800 return -EBUSY; 1801 1802 platform_driver = &driver->platform_driver; 1803 platform_driver->remove = asus_wmi_remove; 1804 platform_driver->driver.owner = driver->owner; 1805 platform_driver->driver.name = driver->name; 1806 platform_driver->driver.pm = &asus_pm_ops; 1807 1808 platform_device = platform_create_bundle(platform_driver, 1809 asus_wmi_probe, 1810 NULL, 0, NULL, 0); 1811 if (IS_ERR(platform_device)) 1812 return PTR_ERR(platform_device); 1813 1814 used = true; 1815 return 0; 1816 } 1817 EXPORT_SYMBOL_GPL(asus_wmi_register_driver); 1818 1819 void asus_wmi_unregister_driver(struct asus_wmi_driver *driver) 1820 { 1821 platform_device_unregister(driver->platform_device); 1822 platform_driver_unregister(&driver->platform_driver); 1823 used = false; 1824 } 1825 EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver); 1826 1827 static int __init asus_wmi_init(void) 1828 { 1829 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { 1830 pr_info("Asus Management GUID not found"); 1831 return -ENODEV; 1832 } 1833 1834 pr_info("ASUS WMI generic driver loaded"); 1835 return 0; 1836 } 1837 1838 static void __exit asus_wmi_exit(void) 1839 { 1840 pr_info("ASUS WMI generic driver unloaded"); 1841 } 1842 1843 module_init(asus_wmi_init); 1844 module_exit(asus_wmi_exit); 1845