Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86: (38 commits)
acer-wmi: support Lenovo ideapad S205 wifi switch
acerhdf.c: spaces in aliased changed to *
platform-drivers-x86: ideapad-laptop: add missing ideapad_input_exit in ideapad_acpi_add error path
x86 driver: fix typo in TDP override enabling
Platform: fix samsung-laptop DMI identification for N150/N210/220/N230
dell-wmi: Add keys for Dell XPS L502X
platform-drivers-x86: samsung-q10: make dmi_check_callback return 1
Platform: Samsung Q10 backlight driver
platform-drivers-x86: intel_scu_ipc: convert to DEFINE_PCI_DEVICE_TABLE
platform-drivers-x86: intel_rar_register: convert to DEFINE_PCI_DEVICE_TABLE
platform-drivers-x86: intel_menlow: add missing return AE_OK for intel_menlow_register_sensor()
platform-drivers-x86: intel_mid_thermal: fix memory leak
platform-drivers-x86: msi-wmi: add missing sparse_keymap_free in msi_wmi_init error path
Samsung Laptop platform driver: support N510
asus-wmi: add uwb rfkill support
asus-wmi: add gps rfkill support
asus-wmi: add CWAP support and clarify the meaning of WAPF bits
asus-wmi: return proper value in store_cpufv()
asus-wmi: check for temp1 presence
asus-wmi: add thermal sensor
...

+799 -84
+17
Documentation/ABI/testing/sysfs-platform-ideapad-laptop
··· 4 4 Contact: "Ike Panhc <ike.pan@canonical.com>" 5 5 Description: 6 6 Control the power of camera module. 1 means on, 0 means off. 7 + 8 + What: /sys/devices/platform/ideapad/cfg 9 + Date: Jun 2011 10 + KernelVersion: 3.1 11 + Contact: "Ike Panhc <ike.pan@canonical.com>" 12 + Description: 13 + Ideapad capability bits. 14 + Bit 8-10: 1 - Intel graphic only 15 + 2 - ATI graphic only 16 + 3 - Nvidia graphic only 17 + 4 - Intel and ATI graphic 18 + 5 - Intel and Nvidia graphic 19 + Bit 16: Bluetooth exist (1 for exist) 20 + Bit 17: 3G exist (1 for exist) 21 + Bit 18: Wifi exist (1 for exist) 22 + Bit 19: Camera exist (1 for exist) 23 +
+11
Documentation/feature-removal-schedule.txt
··· 581 581 Who: Alan Stern <stern@rowland.harvard.edu> 582 582 583 583 ---------------------------- 584 + 585 + What: threeg and interface sysfs files in /sys/devices/platform/acer-wmi 586 + When: 2012 587 + Why: In 3.0, we can now autodetect internal 3G device and already have 588 + the threeg rfkill device. So, we plan to remove threeg sysfs support 589 + for it's no longer necessary. 590 + 591 + We also plan to remove interface sysfs file that exposed which ACPI-WMI 592 + interface that was used by acer-wmi driver. It will replaced by 593 + information log when acer-wmi initial. 594 + Who: Lee, Chun-Yi <jlee@novell.com>
+8
drivers/platform/x86/Kconfig
··· 769 769 enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y 770 770 here; it will only load on supported platforms. 771 771 772 + config SAMSUNG_Q10 773 + tristate "Samsung Q10 Extras" 774 + depends on SERIO_I8042 775 + select BACKLIGHT_CLASS_DEVICE 776 + ---help--- 777 + This driver provides support for backlight control on Samsung Q10 778 + and related laptops, including Dell Latitude X200. 779 + 772 780 endif # X86_PLATFORM_DEVICES
+1
drivers/platform/x86/Makefile
··· 44 44 obj-$(CONFIG_MXM_WMI) += mxm-wmi.o 45 45 obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o 46 46 obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o 47 + obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
+36 -4
drivers/platform/x86/acer-wmi.c
··· 99 99 static const struct key_entry acer_wmi_keymap[] = { 100 100 {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ 101 101 {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ 102 + {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ 102 103 {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ 103 104 {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ 104 105 {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ ··· 305 304 .wireless = 2, 306 305 }; 307 306 307 + static struct quirk_entry quirk_lenovo_ideapad_s205 = { 308 + .wireless = 3, 309 + }; 310 + 308 311 /* The Aspire One has a dummy ACPI-WMI interface - disable it */ 309 312 static struct dmi_system_id __devinitdata acer_blacklist[] = { 310 313 { ··· 455 450 }, 456 451 .driver_data = &quirk_medion_md_98300, 457 452 }, 453 + { 454 + .callback = dmi_matched, 455 + .ident = "Lenovo Ideapad S205", 456 + .matches = { 457 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 458 + DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), 459 + }, 460 + .driver_data = &quirk_lenovo_ideapad_s205, 461 + }, 458 462 {} 459 463 }; 460 464 ··· 552 538 return AE_OK; 553 539 case 2: 554 540 err = ec_read(0x71, &result); 541 + if (err) 542 + return AE_ERROR; 543 + *value = result & 0x1; 544 + return AE_OK; 545 + case 3: 546 + err = ec_read(0x78, &result); 555 547 if (err) 556 548 return AE_ERROR; 557 549 *value = result & 0x1; ··· 1286 1266 acpi_status status; 1287 1267 1288 1268 status = get_u32(&state, ACER_CAP_WIRELESS); 1289 - if (ACPI_SUCCESS(status)) 1290 - rfkill_set_sw_state(wireless_rfkill, !state); 1269 + if (ACPI_SUCCESS(status)) { 1270 + if (quirks->wireless == 3) { 1271 + rfkill_set_hw_state(wireless_rfkill, !state); 1272 + } else { 1273 + rfkill_set_sw_state(wireless_rfkill, !state); 1274 + } 1275 + } 1291 1276 1292 1277 if (has_cap(ACER_CAP_BLUETOOTH)) { 1293 1278 status = get_u32(&state, ACER_CAP_BLUETOOTH); ··· 1425 1400 { 1426 1401 u32 result; \ 1427 1402 acpi_status status; 1403 + 1404 + pr_info("This threeg sysfs will be removed in 2012" 1405 + " - used by: %s\n", current->comm); 1428 1406 if (wmi_has_guid(WMID_GUID3)) 1429 1407 status = wmid3_get_device_status(&result, 1430 1408 ACER_WMID3_GDS_THREEG); ··· 1443 1415 { 1444 1416 u32 tmp = simple_strtoul(buf, NULL, 10); 1445 1417 acpi_status status = set_u32(tmp, ACER_CAP_THREEG); 1446 - if (ACPI_FAILURE(status)) 1447 - return -EINVAL; 1418 + pr_info("This threeg sysfs will be removed in 2012" 1419 + " - used by: %s\n", current->comm); 1420 + if (ACPI_FAILURE(status)) 1421 + return -EINVAL; 1448 1422 return count; 1449 1423 } 1450 1424 static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, ··· 1455 1425 static ssize_t show_interface(struct device *dev, struct device_attribute *attr, 1456 1426 char *buf) 1457 1427 { 1428 + pr_info("This interface sysfs will be removed in 2012" 1429 + " - used by: %s\n", current->comm); 1458 1430 switch (interface->type) { 1459 1431 case ACER_AMW0: 1460 1432 return sprintf(buf, "AMW0\n");
+7 -6
drivers/platform/x86/acerhdf.c
··· 182 182 {"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, 183 183 {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, 184 184 {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, 185 + {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, 185 186 /* Acer 531 */ 186 187 {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, 187 188 /* Gateway */ ··· 704 703 MODULE_AUTHOR("Peter Feuerer"); 705 704 MODULE_DESCRIPTION("Aspire One temperature and fan driver"); 706 705 MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); 707 - MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); 708 - MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); 706 + MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:"); 707 + MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); 709 708 MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); 710 709 MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); 711 710 MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); 712 - MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); 713 - MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); 714 - MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); 715 - MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMA*:"); 711 + MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:"); 712 + MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:"); 713 + MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); 714 + MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); 716 715 717 716 module_init(acerhdf_init); 718 717 module_exit(acerhdf_exit);
+4 -5
drivers/platform/x86/asus-laptop.c
··· 70 70 * WAPF defines the behavior of the Fn+Fx wlan key 71 71 * The significance of values is yet to be found, but 72 72 * most of the time: 73 - * 0x0 will do nothing 74 - * 0x1 will allow to control the device with Fn+Fx key. 75 - * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key 76 - * 0x5 like 0x1 or 0x4 77 - * So, if something doesn't work as you want, just try other values =) 73 + * Bit | Bluetooth | WLAN 74 + * 0 | Hardware | Hardware 75 + * 1 | Hardware | Software 76 + * 4 | Software | Software 78 77 */ 79 78 static uint wapf = 1; 80 79 module_param(wapf, uint, 0444);
+23 -4
drivers/platform/x86/asus-nb-wmi.c
··· 38 38 39 39 MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); 40 40 41 + /* 42 + * WAPF defines the behavior of the Fn+Fx wlan key 43 + * The significance of values is yet to be found, but 44 + * most of the time: 45 + * Bit | Bluetooth | WLAN 46 + * 0 | Hardware | Hardware 47 + * 1 | Hardware | Software 48 + * 4 | Software | Software 49 + */ 50 + static uint wapf; 51 + module_param(wapf, uint, 0444); 52 + MODULE_PARM_DESC(wapf, "WAPF value"); 53 + 54 + static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) 55 + { 56 + driver->wapf = wapf; 57 + } 58 + 41 59 static const struct key_entry asus_nb_wmi_keymap[] = { 42 60 { KE_KEY, 0x30, { KEY_VOLUMEUP } }, 43 61 { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, ··· 71 53 { KE_KEY, 0x51, { KEY_WWW } }, 72 54 { KE_KEY, 0x55, { KEY_CALC } }, 73 55 { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ 74 - { KE_KEY, 0x5D, { KEY_WLAN } }, 75 - { KE_KEY, 0x5E, { KEY_WLAN } }, 76 - { KE_KEY, 0x5F, { KEY_WLAN } }, 56 + { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ 57 + { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ 58 + { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ 77 59 { KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } }, 78 60 { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, 79 61 { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, 80 62 { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, 81 63 { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, 82 - { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, 83 64 { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, 65 + { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, 84 66 { KE_KEY, 0x82, { KEY_CAMERA } }, 85 67 { KE_KEY, 0x88, { KEY_RFKILL } }, 86 68 { KE_KEY, 0x8A, { KEY_PROG1 } }, ··· 99 81 .keymap = asus_nb_wmi_keymap, 100 82 .input_name = "Asus WMI hotkeys", 101 83 .input_phys = ASUS_NB_WMI_FILE "/input0", 84 + .quirks = asus_nb_wmi_quirks, 102 85 }; 103 86 104 87
+212 -27
drivers/platform/x86/asus-wmi.c
··· 44 44 #include <linux/debugfs.h> 45 45 #include <linux/seq_file.h> 46 46 #include <linux/platform_device.h> 47 + #include <linux/thermal.h> 47 48 #include <acpi/acpi_bus.h> 48 49 #include <acpi/acpi_drivers.h> 49 50 ··· 67 66 #define NOTIFY_BRNUP_MAX 0x1f 68 67 #define NOTIFY_BRNDOWN_MIN 0x20 69 68 #define NOTIFY_BRNDOWN_MAX 0x2e 69 + #define NOTIFY_KBD_BRTUP 0xc4 70 + #define NOTIFY_KBD_BRTDWN 0xc5 70 71 71 72 /* WMI Methods */ 72 73 #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ ··· 96 93 /* Wireless */ 97 94 #define ASUS_WMI_DEVID_HW_SWITCH 0x00010001 98 95 #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 96 + #define ASUS_WMI_DEVID_CWAP 0x00010003 99 97 #define ASUS_WMI_DEVID_WLAN 0x00010011 100 98 #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 101 99 #define ASUS_WMI_DEVID_GPS 0x00010015 ··· 106 102 107 103 /* Leds */ 108 104 /* 0x000200XX and 0x000400XX */ 105 + #define ASUS_WMI_DEVID_LED1 0x00020011 106 + #define ASUS_WMI_DEVID_LED2 0x00020012 107 + #define ASUS_WMI_DEVID_LED3 0x00020013 108 + #define ASUS_WMI_DEVID_LED4 0x00020014 109 + #define ASUS_WMI_DEVID_LED5 0x00020015 110 + #define ASUS_WMI_DEVID_LED6 0x00020016 109 111 110 112 /* Backlight and Brightness */ 111 113 #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011 ··· 184 174 185 175 struct led_classdev tpd_led; 186 176 int tpd_led_wk; 177 + struct led_classdev kbd_led; 178 + int kbd_led_wk; 187 179 struct workqueue_struct *led_workqueue; 188 180 struct work_struct tpd_led_work; 181 + struct work_struct kbd_led_work; 189 182 190 183 struct asus_rfkill wlan; 191 184 struct asus_rfkill bluetooth; 192 185 struct asus_rfkill wimax; 193 186 struct asus_rfkill wwan3g; 187 + struct asus_rfkill gps; 188 + struct asus_rfkill uwb; 194 189 195 190 struct hotplug_slot *hotplug_slot; 196 191 struct mutex hotplug_lock; ··· 220 205 asus->inputdev->phys = asus->driver->input_phys; 221 206 asus->inputdev->id.bustype = BUS_HOST; 222 207 asus->inputdev->dev.parent = &asus->platform_device->dev; 208 + set_bit(EV_REP, asus->inputdev->evbit); 223 209 224 210 err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL); 225 211 if (err) ··· 375 359 return read_tpd_led_state(asus); 376 360 } 377 361 378 - static int asus_wmi_led_init(struct asus_wmi *asus) 362 + static void kbd_led_update(struct work_struct *work) 379 363 { 380 - int rv; 364 + int ctrl_param = 0; 365 + struct asus_wmi *asus; 381 366 382 - if (read_tpd_led_state(asus) < 0) 383 - return 0; 367 + asus = container_of(work, struct asus_wmi, kbd_led_work); 384 368 385 - asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); 386 - if (!asus->led_workqueue) 387 - return -ENOMEM; 388 - INIT_WORK(&asus->tpd_led_work, tpd_led_update); 369 + /* 370 + * bits 0-2: level 371 + * bit 7: light on/off 372 + */ 373 + if (asus->kbd_led_wk > 0) 374 + ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); 389 375 390 - asus->tpd_led.name = "asus::touchpad"; 391 - asus->tpd_led.brightness_set = tpd_led_set; 392 - asus->tpd_led.brightness_get = tpd_led_get; 393 - asus->tpd_led.max_brightness = 1; 376 + asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL); 377 + } 394 378 395 - rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led); 396 - if (rv) { 397 - destroy_workqueue(asus->led_workqueue); 398 - return rv; 379 + static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) 380 + { 381 + int retval; 382 + 383 + /* 384 + * bits 0-2: level 385 + * bit 7: light on/off 386 + * bit 8-10: environment (0: dark, 1: normal, 2: light) 387 + * bit 17: status unknown 388 + */ 389 + retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT, 390 + 0xFFFF); 391 + 392 + /* Unknown status is considered as off */ 393 + if (retval == 0x8000) 394 + retval = 0; 395 + 396 + if (retval >= 0) { 397 + if (level) 398 + *level = retval & 0x80 ? retval & 0x7F : 0; 399 + if (env) 400 + *env = (retval >> 8) & 0x7F; 401 + retval = 0; 399 402 } 400 403 401 - return 0; 404 + return retval; 405 + } 406 + 407 + static void kbd_led_set(struct led_classdev *led_cdev, 408 + enum led_brightness value) 409 + { 410 + struct asus_wmi *asus; 411 + 412 + asus = container_of(led_cdev, struct asus_wmi, kbd_led); 413 + 414 + if (value > asus->kbd_led.max_brightness) 415 + value = asus->kbd_led.max_brightness; 416 + else if (value < 0) 417 + value = 0; 418 + 419 + asus->kbd_led_wk = value; 420 + queue_work(asus->led_workqueue, &asus->kbd_led_work); 421 + } 422 + 423 + static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) 424 + { 425 + struct asus_wmi *asus; 426 + int retval, value; 427 + 428 + asus = container_of(led_cdev, struct asus_wmi, kbd_led); 429 + 430 + retval = kbd_led_read(asus, &value, NULL); 431 + 432 + if (retval < 0) 433 + return retval; 434 + 435 + return value; 402 436 } 403 437 404 438 static void asus_wmi_led_exit(struct asus_wmi *asus) ··· 458 392 if (asus->led_workqueue) 459 393 destroy_workqueue(asus->led_workqueue); 460 394 } 395 + 396 + static int asus_wmi_led_init(struct asus_wmi *asus) 397 + { 398 + int rv = 0; 399 + 400 + asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); 401 + if (!asus->led_workqueue) 402 + return -ENOMEM; 403 + 404 + if (read_tpd_led_state(asus) >= 0) { 405 + INIT_WORK(&asus->tpd_led_work, tpd_led_update); 406 + 407 + asus->tpd_led.name = "asus::touchpad"; 408 + asus->tpd_led.brightness_set = tpd_led_set; 409 + asus->tpd_led.brightness_get = tpd_led_get; 410 + asus->tpd_led.max_brightness = 1; 411 + 412 + rv = led_classdev_register(&asus->platform_device->dev, 413 + &asus->tpd_led); 414 + if (rv) 415 + goto error; 416 + } 417 + 418 + if (kbd_led_read(asus, NULL, NULL) >= 0) { 419 + INIT_WORK(&asus->kbd_led_work, kbd_led_update); 420 + 421 + asus->kbd_led.name = "asus::kbd_backlight"; 422 + asus->kbd_led.brightness_set = kbd_led_set; 423 + asus->kbd_led.brightness_get = kbd_led_get; 424 + asus->kbd_led.max_brightness = 3; 425 + 426 + rv = led_classdev_register(&asus->platform_device->dev, 427 + &asus->kbd_led); 428 + } 429 + 430 + error: 431 + if (rv) 432 + asus_wmi_led_exit(asus); 433 + 434 + return rv; 435 + } 436 + 461 437 462 438 /* 463 439 * PCI hotplug (for wlan rfkill) ··· 837 729 rfkill_destroy(asus->wwan3g.rfkill); 838 730 asus->wwan3g.rfkill = NULL; 839 731 } 732 + if (asus->gps.rfkill) { 733 + rfkill_unregister(asus->gps.rfkill); 734 + rfkill_destroy(asus->gps.rfkill); 735 + asus->gps.rfkill = NULL; 736 + } 737 + if (asus->uwb.rfkill) { 738 + rfkill_unregister(asus->uwb.rfkill); 739 + rfkill_destroy(asus->uwb.rfkill); 740 + asus->uwb.rfkill = NULL; 741 + } 840 742 } 841 743 842 744 static int asus_wmi_rfkill_init(struct asus_wmi *asus) ··· 877 759 878 760 result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g", 879 761 RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G); 762 + 763 + if (result && result != -ENODEV) 764 + goto exit; 765 + 766 + result = asus_new_rfkill(asus, &asus->gps, "asus-gps", 767 + RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS); 768 + 769 + if (result && result != -ENODEV) 770 + goto exit; 771 + 772 + result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb", 773 + RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB); 880 774 881 775 if (result && result != -ENODEV) 882 776 goto exit; ··· 927 797 * Hwmon device 928 798 */ 929 799 static ssize_t asus_hwmon_pwm1(struct device *dev, 930 - struct device_attribute *attr, 931 - char *buf) 800 + struct device_attribute *attr, 801 + char *buf) 932 802 { 933 803 struct asus_wmi *asus = dev_get_drvdata(dev); 934 804 u32 value; ··· 939 809 if (err < 0) 940 810 return err; 941 811 942 - value |= 0xFF; 812 + value &= 0xFF; 943 813 944 814 if (value == 1) /* Low Speed */ 945 815 value = 85; ··· 955 825 return sprintf(buf, "%d\n", value); 956 826 } 957 827 828 + static ssize_t asus_hwmon_temp1(struct device *dev, 829 + struct device_attribute *attr, 830 + char *buf) 831 + { 832 + struct asus_wmi *asus = dev_get_drvdata(dev); 833 + u32 value; 834 + int err; 835 + 836 + err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value); 837 + 838 + if (err < 0) 839 + return err; 840 + 841 + value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000; 842 + 843 + return sprintf(buf, "%d\n", value); 844 + } 845 + 958 846 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0); 847 + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0); 959 848 960 849 static ssize_t 961 850 show_name(struct device *dev, struct device_attribute *attr, char *buf) ··· 985 836 986 837 static struct attribute *hwmon_attributes[] = { 987 838 &sensor_dev_attr_pwm1.dev_attr.attr, 839 + &sensor_dev_attr_temp1_input.dev_attr.attr, 988 840 &sensor_dev_attr_name.dev_attr.attr, 989 841 NULL 990 842 }; 991 843 992 844 static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, 993 - struct attribute *attr, int idx) 845 + struct attribute *attr, int idx) 994 846 { 995 847 struct device *dev = container_of(kobj, struct device, kobj); 996 848 struct platform_device *pdev = to_platform_device(dev->parent); ··· 1002 852 1003 853 if (attr == &sensor_dev_attr_pwm1.dev_attr.attr) 1004 854 dev_id = ASUS_WMI_DEVID_FAN_CTRL; 855 + else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr) 856 + dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; 1005 857 1006 858 if (dev_id != -1) { 1007 859 int err = asus_wmi_get_devstate(asus, dev_id, &value); ··· 1021 869 * - reverved bits are non-zero 1022 870 * - sfun and presence bit are not set 1023 871 */ 1024 - if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 872 + if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 1025 873 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) 874 + ok = false; 875 + } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) { 876 + /* If value is zero, something is clearly wrong */ 877 + if (value == 0) 1026 878 ok = false; 1027 879 } 1028 880 ··· 1060 904 pr_err("Could not register asus hwmon device\n"); 1061 905 return PTR_ERR(hwmon); 1062 906 } 907 + dev_set_drvdata(hwmon, asus); 1063 908 asus->hwmon_device = hwmon; 1064 909 result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); 1065 910 if (result) ··· 1217 1060 acpi_status status; 1218 1061 int code; 1219 1062 int orig_code; 1063 + unsigned int key_value = 1; 1064 + bool autorelease = 1; 1220 1065 1221 1066 status = wmi_get_event_data(value, &response); 1222 1067 if (status != AE_OK) { ··· 1234 1075 code = obj->integer.value; 1235 1076 orig_code = code; 1236 1077 1078 + if (asus->driver->key_filter) { 1079 + asus->driver->key_filter(asus->driver, &code, &key_value, 1080 + &autorelease); 1081 + if (code == ASUS_WMI_KEY_IGNORE) 1082 + goto exit; 1083 + } 1084 + 1237 1085 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) 1238 1086 code = NOTIFY_BRNUP_MIN; 1239 1087 else if (code >= NOTIFY_BRNDOWN_MIN && ··· 1250 1084 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { 1251 1085 if (!acpi_video_backlight_support()) 1252 1086 asus_wmi_backlight_notify(asus, orig_code); 1253 - } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true)) 1087 + } else if (!sparse_keymap_report_event(asus->inputdev, code, 1088 + key_value, autorelease)) 1254 1089 pr_info("Unknown key %x pressed\n", code); 1255 1090 1256 1091 exit: ··· 1331 1164 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, 1332 1165 const char *buf, size_t count) 1333 1166 { 1334 - int value; 1167 + int value, rv; 1335 1168 1336 1169 if (!count || sscanf(buf, "%i", &value) != 1) 1337 1170 return -EINVAL; 1338 1171 if (value < 0 || value > 2) 1339 1172 return -EINVAL; 1340 1173 1341 - return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); 1174 + rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); 1175 + if (rv < 0) 1176 + return rv; 1177 + 1178 + return count; 1342 1179 } 1343 1180 1344 1181 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); ··· 1405 1234 1406 1235 /* We don't know yet what to do with this version... */ 1407 1236 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { 1408 - pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF); 1237 + pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); 1409 1238 asus->spec = rv; 1410 1239 } 1411 1240 ··· 1436 1265 pr_err("Can't find DSTS"); 1437 1266 return -ENODEV; 1438 1267 } 1268 + 1269 + /* CWAP allow to define the behavior of the Fn+F2 key, 1270 + * this method doesn't seems to be present on Eee PCs */ 1271 + if (asus->driver->wapf >= 0) 1272 + asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP, 1273 + asus->driver->wapf, NULL); 1439 1274 1440 1275 return asus_wmi_sysfs_init(asus->platform_device); 1441 1276 } ··· 1745 1568 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G); 1746 1569 rfkill_set_sw_state(asus->wwan3g.rfkill, bl); 1747 1570 } 1571 + if (asus->gps.rfkill) { 1572 + bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS); 1573 + rfkill_set_sw_state(asus->gps.rfkill, bl); 1574 + } 1575 + if (asus->uwb.rfkill) { 1576 + bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB); 1577 + rfkill_set_sw_state(asus->uwb.rfkill, bl); 1578 + } 1748 1579 1749 1580 return 0; 1750 1581 } ··· 1789 1604 1790 1605 static bool used; 1791 1606 1792 - int asus_wmi_register_driver(struct asus_wmi_driver *driver) 1607 + int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver) 1793 1608 { 1794 1609 struct platform_driver *platform_driver; 1795 1610 struct platform_device *platform_device;
+7
drivers/platform/x86/asus-wmi.h
··· 29 29 30 30 #include <linux/platform_device.h> 31 31 32 + #define ASUS_WMI_KEY_IGNORE (-1) 33 + 32 34 struct module; 33 35 struct key_entry; 34 36 struct asus_wmi; 35 37 36 38 struct asus_wmi_driver { 37 39 bool hotplug_wireless; 40 + int wapf; 38 41 39 42 const char *name; 40 43 struct module *owner; ··· 47 44 const struct key_entry *keymap; 48 45 const char *input_name; 49 46 const char *input_phys; 47 + /* Returns new code, value, and autorelease values in arguments. 48 + * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */ 49 + void (*key_filter) (struct asus_wmi_driver *driver, int *code, 50 + unsigned int *value, bool *autorelease); 50 51 51 52 int (*probe) (struct platform_device *device); 52 53 void (*quirks) (struct asus_wmi_driver *driver);
-1
drivers/platform/x86/dell-laptop.c
··· 612 612 if (!bufferpage) 613 613 goto fail_buffer; 614 614 buffer = page_address(bufferpage); 615 - mutex_init(&buffer_mutex); 616 615 617 616 ret = dell_setup_rfkill(); 618 617
+10
drivers/platform/x86/dell-wmi.c
··· 54 54 */ 55 55 56 56 static const struct key_entry dell_wmi_legacy_keymap[] __initconst = { 57 + { KE_IGNORE, 0x003a, { KEY_CAPSLOCK } }, 58 + 57 59 { KE_KEY, 0xe045, { KEY_PROG1 } }, 58 60 { KE_KEY, 0xe009, { KEY_EJECTCD } }, 59 61 ··· 87 85 { KE_IGNORE, 0xe013, { KEY_RESERVED } }, 88 86 89 87 { KE_IGNORE, 0xe020, { KEY_MUTE } }, 88 + 89 + /* Shortcut and audio panel keys */ 90 + { KE_IGNORE, 0xe025, { KEY_RESERVED } }, 91 + { KE_IGNORE, 0xe026, { KEY_RESERVED } }, 92 + 90 93 { KE_IGNORE, 0xe02e, { KEY_VOLUMEDOWN } }, 91 94 { KE_IGNORE, 0xe030, { KEY_VOLUMEUP } }, 92 95 { KE_IGNORE, 0xe033, { KEY_KBDILLUMUP } }, ··· 99 92 { KE_IGNORE, 0xe03a, { KEY_CAPSLOCK } }, 100 93 { KE_IGNORE, 0xe045, { KEY_NUMLOCK } }, 101 94 { KE_IGNORE, 0xe046, { KEY_SCROLLLOCK } }, 95 + { KE_IGNORE, 0xe0f7, { KEY_MUTE } }, 96 + { KE_IGNORE, 0xe0f8, { KEY_VOLUMEDOWN } }, 97 + { KE_IGNORE, 0xe0f9, { KEY_VOLUMEUP } }, 102 98 { KE_END, 0 } 103 99 }; 104 100
+27
drivers/platform/x86/eeepc-wmi.c
··· 56 56 "If your laptop needs that, please report to " 57 57 "acpi4asus-user@lists.sourceforge.net."); 58 58 59 + /* Values for T101MT "Home" key */ 60 + #define HOME_PRESS 0xe4 61 + #define HOME_HOLD 0xea 62 + #define HOME_RELEASE 0xe5 63 + 59 64 static const struct key_entry eeepc_wmi_keymap[] = { 60 65 /* Sleep already handled via generic ACPI code */ 61 66 { KE_KEY, 0x30, { KEY_VOLUMEUP } }, ··· 76 71 { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, 77 72 { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ 78 73 { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ 74 + { KE_KEY, HOME_PRESS, { KEY_CONFIG } }, /* Home/Express gate key */ 79 75 { KE_KEY, 0xe8, { KEY_SCREENLOCK } }, 80 76 { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, 81 77 { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, ··· 86 80 { KE_KEY, 0xef, { KEY_CAMERA_RIGHT } }, 87 81 { KE_END, 0}, 88 82 }; 83 + 84 + static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, 85 + unsigned int *value, bool *autorelease) 86 + { 87 + switch (*code) { 88 + case HOME_PRESS: 89 + *value = 1; 90 + *autorelease = 0; 91 + break; 92 + case HOME_HOLD: 93 + *code = ASUS_WMI_KEY_IGNORE; 94 + break; 95 + case HOME_RELEASE: 96 + *code = HOME_PRESS; 97 + *value = 0; 98 + *autorelease = 0; 99 + break; 100 + } 101 + } 89 102 90 103 static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, 91 104 void *context, void **retval) ··· 166 141 static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) 167 142 { 168 143 driver->hotplug_wireless = hotplug_wireless; 144 + driver->wapf = -1; 169 145 eeepc_dmi_check(driver); 170 146 } 171 147 ··· 177 151 .keymap = eeepc_wmi_keymap, 178 152 .input_name = "Eee PC WMI hotkeys", 179 153 .input_phys = EEEPC_WMI_FILE "/input0", 154 + .key_filter = eeepc_wmi_key_filter, 180 155 .probe = eeepc_wmi_probe, 181 156 .quirks = eeepc_wmi_quirks, 182 157 };
+172 -23
drivers/platform/x86/ideapad-laptop.c
··· 32 32 #include <linux/platform_device.h> 33 33 #include <linux/input.h> 34 34 #include <linux/input/sparse-keymap.h> 35 + #include <linux/backlight.h> 36 + #include <linux/fb.h> 35 37 36 38 #define IDEAPAD_RFKILL_DEV_NUM (3) 39 + 40 + #define CFG_BT_BIT (16) 41 + #define CFG_3G_BIT (17) 42 + #define CFG_WIFI_BIT (18) 43 + #define CFG_CAMERA_BIT (19) 37 44 38 45 struct ideapad_private { 39 46 struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; 40 47 struct platform_device *platform_device; 41 48 struct input_dev *inputdev; 49 + struct backlight_device *blightdev; 50 + unsigned long cfg; 42 51 }; 43 52 44 53 static acpi_handle ideapad_handle; ··· 164 155 } 165 156 166 157 /* 167 - * camera power 158 + * sysfs 168 159 */ 169 160 static ssize_t show_ideapad_cam(struct device *dev, 170 161 struct device_attribute *attr, ··· 195 186 196 187 static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); 197 188 189 + static ssize_t show_ideapad_cfg(struct device *dev, 190 + struct device_attribute *attr, 191 + char *buf) 192 + { 193 + struct ideapad_private *priv = dev_get_drvdata(dev); 194 + 195 + return sprintf(buf, "0x%.8lX\n", priv->cfg); 196 + } 197 + 198 + static DEVICE_ATTR(cfg, 0444, show_ideapad_cfg, NULL); 199 + 200 + static struct attribute *ideapad_attributes[] = { 201 + &dev_attr_camera_power.attr, 202 + &dev_attr_cfg.attr, 203 + NULL 204 + }; 205 + 206 + static mode_t ideapad_is_visible(struct kobject *kobj, 207 + struct attribute *attr, 208 + int idx) 209 + { 210 + struct device *dev = container_of(kobj, struct device, kobj); 211 + struct ideapad_private *priv = dev_get_drvdata(dev); 212 + bool supported; 213 + 214 + if (attr == &dev_attr_camera_power.attr) 215 + supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); 216 + else 217 + supported = true; 218 + 219 + return supported ? attr->mode : 0; 220 + } 221 + 222 + static struct attribute_group ideapad_attribute_group = { 223 + .is_visible = ideapad_is_visible, 224 + .attrs = ideapad_attributes 225 + }; 226 + 198 227 /* 199 228 * Rfkill 200 229 */ ··· 244 197 }; 245 198 246 199 const struct ideapad_rfk_data ideapad_rfk_data[] = { 247 - { "ideapad_wlan", 18, 0x15, RFKILL_TYPE_WLAN }, 248 - { "ideapad_bluetooth", 16, 0x17, RFKILL_TYPE_BLUETOOTH }, 249 - { "ideapad_3g", 17, 0x20, RFKILL_TYPE_WWAN }, 200 + { "ideapad_wlan", CFG_WIFI_BIT, 0x15, RFKILL_TYPE_WLAN }, 201 + { "ideapad_bluetooth", CFG_BT_BIT, 0x17, RFKILL_TYPE_BLUETOOTH }, 202 + { "ideapad_3g", CFG_3G_BIT, 0x20, RFKILL_TYPE_WWAN }, 250 203 }; 251 204 252 205 static int ideapad_rfk_set(void *data, bool blocked) ··· 312 265 return 0; 313 266 } 314 267 315 - static void __devexit ideapad_unregister_rfkill(struct acpi_device *adevice, 316 - int dev) 268 + static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) 317 269 { 318 270 struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); 319 271 ··· 326 280 /* 327 281 * Platform device 328 282 */ 329 - static struct attribute *ideapad_attributes[] = { 330 - &dev_attr_camera_power.attr, 331 - NULL 332 - }; 333 - 334 - static struct attribute_group ideapad_attribute_group = { 335 - .attrs = ideapad_attributes 336 - }; 337 - 338 283 static int __devinit ideapad_platform_init(struct ideapad_private *priv) 339 284 { 340 285 int result; ··· 406 369 return error; 407 370 } 408 371 409 - static void __devexit ideapad_input_exit(struct ideapad_private *priv) 372 + static void ideapad_input_exit(struct ideapad_private *priv) 410 373 { 411 374 sparse_keymap_free(priv->inputdev); 412 375 input_unregister_device(priv->inputdev); ··· 420 383 } 421 384 422 385 /* 386 + * backlight 387 + */ 388 + static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) 389 + { 390 + unsigned long now; 391 + 392 + if (read_ec_data(ideapad_handle, 0x12, &now)) 393 + return -EIO; 394 + return now; 395 + } 396 + 397 + static int ideapad_backlight_update_status(struct backlight_device *blightdev) 398 + { 399 + if (write_ec_cmd(ideapad_handle, 0x13, blightdev->props.brightness)) 400 + return -EIO; 401 + if (write_ec_cmd(ideapad_handle, 0x33, 402 + blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) 403 + return -EIO; 404 + 405 + return 0; 406 + } 407 + 408 + static const struct backlight_ops ideapad_backlight_ops = { 409 + .get_brightness = ideapad_backlight_get_brightness, 410 + .update_status = ideapad_backlight_update_status, 411 + }; 412 + 413 + static int ideapad_backlight_init(struct ideapad_private *priv) 414 + { 415 + struct backlight_device *blightdev; 416 + struct backlight_properties props; 417 + unsigned long max, now, power; 418 + 419 + if (read_ec_data(ideapad_handle, 0x11, &max)) 420 + return -EIO; 421 + if (read_ec_data(ideapad_handle, 0x12, &now)) 422 + return -EIO; 423 + if (read_ec_data(ideapad_handle, 0x18, &power)) 424 + return -EIO; 425 + 426 + memset(&props, 0, sizeof(struct backlight_properties)); 427 + props.max_brightness = max; 428 + props.type = BACKLIGHT_PLATFORM; 429 + blightdev = backlight_device_register("ideapad", 430 + &priv->platform_device->dev, 431 + priv, 432 + &ideapad_backlight_ops, 433 + &props); 434 + if (IS_ERR(blightdev)) { 435 + pr_err("Could not register backlight device\n"); 436 + return PTR_ERR(blightdev); 437 + } 438 + 439 + priv->blightdev = blightdev; 440 + blightdev->props.brightness = now; 441 + blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 442 + backlight_update_status(blightdev); 443 + 444 + return 0; 445 + } 446 + 447 + static void ideapad_backlight_exit(struct ideapad_private *priv) 448 + { 449 + if (priv->blightdev) 450 + backlight_device_unregister(priv->blightdev); 451 + priv->blightdev = NULL; 452 + } 453 + 454 + static void ideapad_backlight_notify_power(struct ideapad_private *priv) 455 + { 456 + unsigned long power; 457 + struct backlight_device *blightdev = priv->blightdev; 458 + 459 + if (read_ec_data(ideapad_handle, 0x18, &power)) 460 + return; 461 + blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 462 + } 463 + 464 + static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) 465 + { 466 + unsigned long now; 467 + 468 + /* if we control brightness via acpi video driver */ 469 + if (priv->blightdev == NULL) { 470 + read_ec_data(ideapad_handle, 0x12, &now); 471 + return; 472 + } 473 + 474 + backlight_force_update(priv->blightdev, BACKLIGHT_UPDATE_HOTKEY); 475 + } 476 + 477 + /* 423 478 * module init/exit 424 479 */ 425 480 static const struct acpi_device_id ideapad_device_ids[] = { ··· 522 393 523 394 static int __devinit ideapad_acpi_add(struct acpi_device *adevice) 524 395 { 525 - int ret, i, cfg; 396 + int ret, i; 397 + unsigned long cfg; 526 398 struct ideapad_private *priv; 527 399 528 - if (read_method_int(adevice->handle, "_CFG", &cfg)) 400 + if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) 529 401 return -ENODEV; 530 402 531 403 priv = kzalloc(sizeof(*priv), GFP_KERNEL); ··· 534 404 return -ENOMEM; 535 405 dev_set_drvdata(&adevice->dev, priv); 536 406 ideapad_handle = adevice->handle; 407 + priv->cfg = cfg; 537 408 538 409 ret = ideapad_platform_init(priv); 539 410 if (ret) ··· 545 414 goto input_failed; 546 415 547 416 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { 548 - if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg)) 417 + if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) 549 418 ideapad_register_rfkill(adevice, i); 550 419 else 551 420 priv->rfk[i] = NULL; 552 421 } 553 422 ideapad_sync_rfk_state(adevice); 554 423 424 + if (!acpi_video_backlight_support()) { 425 + ret = ideapad_backlight_init(priv); 426 + if (ret && ret != -ENODEV) 427 + goto backlight_failed; 428 + } 429 + 555 430 return 0; 556 431 432 + backlight_failed: 433 + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 434 + ideapad_unregister_rfkill(adevice, i); 435 + ideapad_input_exit(priv); 557 436 input_failed: 558 437 ideapad_platform_exit(priv); 559 438 platform_failed: ··· 576 435 struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); 577 436 int i; 578 437 438 + ideapad_backlight_exit(priv); 579 439 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 580 440 ideapad_unregister_rfkill(adevice, i); 581 441 ideapad_input_exit(priv); ··· 601 459 vpc1 = (vpc2 << 8) | vpc1; 602 460 for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { 603 461 if (test_bit(vpc_bit, &vpc1)) { 604 - if (vpc_bit == 9) 462 + switch (vpc_bit) { 463 + case 9: 605 464 ideapad_sync_rfk_state(adevice); 606 - else if (vpc_bit == 4) 607 - read_ec_data(handle, 0x12, &vpc2); 608 - else 465 + break; 466 + case 4: 467 + ideapad_backlight_notify_brightness(priv); 468 + break; 469 + case 2: 470 + ideapad_backlight_notify_power(priv); 471 + break; 472 + default: 609 473 ideapad_input_report(priv, vpc_bit); 474 + } 610 475 } 611 476 } 612 477 }
+2 -2
drivers/platform/x86/intel_ips.c
··· 403 403 404 404 thm_writew(THM_MPCPC, (new_tdp_limit * 10) / 8); 405 405 406 - turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDC_OVR_EN; 406 + turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDP_OVR_EN; 407 407 wrmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_override); 408 408 409 409 turbo_override &= ~TURBO_TDP_MASK; ··· 438 438 439 439 thm_writew(THM_MPCPC, (new_limit * 10) / 8); 440 440 441 - turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDC_OVR_EN; 441 + turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDP_OVR_EN; 442 442 wrmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_override); 443 443 444 444 turbo_override &= ~TURBO_TDP_MASK;
+2
drivers/platform/x86/intel_menlow.c
··· 477 477 return AE_ERROR; 478 478 } 479 479 480 + return AE_OK; 481 + 480 482 aux1_not_found: 481 483 if (status == AE_NOT_FOUND) 482 484 return AE_OK;
+19 -7
drivers/platform/x86/intel_mid_thermal.c
··· 493 493 494 494 /* Register each sensor with the generic thermal framework*/ 495 495 for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { 496 + struct thermal_device_info *td_info = initialize_sensor(i); 497 + 498 + if (!td_info) { 499 + ret = -ENOMEM; 500 + goto err; 501 + } 496 502 pinfo->tzd[i] = thermal_zone_device_register(name[i], 497 - 0, initialize_sensor(i), &tzd_ops, 0, 0, 0, 0); 498 - if (IS_ERR(pinfo->tzd[i])) 499 - goto reg_fail; 503 + 0, td_info, &tzd_ops, 0, 0, 0, 0); 504 + if (IS_ERR(pinfo->tzd[i])) { 505 + kfree(td_info); 506 + ret = PTR_ERR(pinfo->tzd[i]); 507 + goto err; 508 + } 500 509 } 501 510 502 511 pinfo->pdev = pdev; 503 512 platform_set_drvdata(pdev, pinfo); 504 513 return 0; 505 514 506 - reg_fail: 507 - ret = PTR_ERR(pinfo->tzd[i]); 508 - while (--i >= 0) 515 + err: 516 + while (--i >= 0) { 517 + kfree(pinfo->tzd[i]->devdata); 509 518 thermal_zone_device_unregister(pinfo->tzd[i]); 519 + } 510 520 configure_adc(0); 511 521 kfree(pinfo); 512 522 return ret; ··· 534 524 int i; 535 525 struct platform_info *pinfo = platform_get_drvdata(pdev); 536 526 537 - for (i = 0; i < MSIC_THERMAL_SENSORS; i++) 527 + for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { 528 + kfree(pinfo->tzd[i]->devdata); 538 529 thermal_zone_device_unregister(pinfo->tzd[i]); 530 + } 539 531 540 532 kfree(pinfo); 541 533 platform_set_drvdata(pdev, NULL);
+1 -3
drivers/platform/x86/intel_rar_register.c
··· 637 637 return error; 638 638 } 639 639 640 - const struct pci_device_id rar_pci_id_tbl[] = { 640 + static DEFINE_PCI_DEVICE_TABLE(rar_pci_id_tbl) = { 641 641 { PCI_VDEVICE(INTEL, 0x4110) }, 642 642 { 0 } 643 643 }; 644 644 645 645 MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); 646 - 647 - const struct pci_device_id *my_id_table = rar_pci_id_tbl; 648 646 649 647 /* field for registering driver to PCI device */ 650 648 static struct pci_driver rar_pci_driver = {
+1 -1
drivers/platform/x86/intel_scu_ipc.c
··· 725 725 intel_scu_devices_destroy(); 726 726 } 727 727 728 - static const struct pci_device_id pci_ids[] = { 728 + static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { 729 729 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)}, 730 730 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)}, 731 731 { 0,}
+10
drivers/platform/x86/msi-laptop.c
··· 538 538 }, 539 539 .callback = dmi_check_cb 540 540 }, 541 + { 542 + .ident = "MSI U270", 543 + .matches = { 544 + DMI_MATCH(DMI_SYS_VENDOR, 545 + "Micro-Star International Co., Ltd."), 546 + DMI_MATCH(DMI_PRODUCT_NAME, "U270 series"), 547 + }, 548 + .callback = dmi_check_cb 549 + }, 541 550 { } 542 551 }; 543 552 ··· 1005 996 MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*"); 1006 997 MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*"); 1007 998 MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnCR620:*"); 999 + MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnU270series:*");
+1
drivers/platform/x86/msi-wmi.c
··· 272 272 err_free_backlight: 273 273 backlight_device_unregister(backlight); 274 274 err_free_input: 275 + sparse_keymap_free(msi_wmi_input_dev); 275 276 input_unregister_device(msi_wmi_input_dev); 276 277 err_uninstall_notifier: 277 278 wmi_remove_notify_handler(MSIWMI_EVENT_GUID);
+20
drivers/platform/x86/samsung-laptop.c
··· 521 521 .callback = dmi_check_cb, 522 522 }, 523 523 { 524 + .ident = "N510", 525 + .matches = { 526 + DMI_MATCH(DMI_SYS_VENDOR, 527 + "SAMSUNG ELECTRONICS CO., LTD."), 528 + DMI_MATCH(DMI_PRODUCT_NAME, "N510"), 529 + DMI_MATCH(DMI_BOARD_NAME, "N510"), 530 + }, 531 + .callback = dmi_check_cb, 532 + }, 533 + { 524 534 .ident = "X125", 525 535 .matches = { 526 536 DMI_MATCH(DMI_SYS_VENDOR, ··· 607 597 "SAMSUNG ELECTRONICS CO., LTD."), 608 598 DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"), 609 599 DMI_MATCH(DMI_BOARD_NAME, "R519/R719"), 600 + }, 601 + .callback = dmi_check_cb, 602 + }, 603 + { 604 + .ident = "N150/N210/N220", 605 + .matches = { 606 + DMI_MATCH(DMI_SYS_VENDOR, 607 + "SAMSUNG ELECTRONICS CO., LTD."), 608 + DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), 609 + DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), 610 610 }, 611 611 .callback = dmi_check_cb, 612 612 },
+196
drivers/platform/x86/samsung-q10.c
··· 1 + /* 2 + * Driver for Samsung Q10 and related laptops: controls the backlight 3 + * 4 + * Copyright (c) 2011 Frederick van der Wyck <fvanderwyck@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/kernel.h> 14 + #include <linux/init.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/backlight.h> 17 + #include <linux/i8042.h> 18 + #include <linux/dmi.h> 19 + 20 + #define SAMSUNGQ10_BL_MAX_INTENSITY 255 21 + #define SAMSUNGQ10_BL_DEFAULT_INTENSITY 185 22 + 23 + #define SAMSUNGQ10_BL_8042_CMD 0xbe 24 + #define SAMSUNGQ10_BL_8042_DATA { 0x89, 0x91 } 25 + 26 + static int samsungq10_bl_brightness; 27 + 28 + static bool force; 29 + module_param(force, bool, 0); 30 + MODULE_PARM_DESC(force, 31 + "Disable the DMI check and force the driver to be loaded"); 32 + 33 + static int samsungq10_bl_set_intensity(struct backlight_device *bd) 34 + { 35 + 36 + int brightness = bd->props.brightness; 37 + unsigned char c[3] = SAMSUNGQ10_BL_8042_DATA; 38 + 39 + c[2] = (unsigned char)brightness; 40 + i8042_lock_chip(); 41 + i8042_command(c, (0x30 << 8) | SAMSUNGQ10_BL_8042_CMD); 42 + i8042_unlock_chip(); 43 + samsungq10_bl_brightness = brightness; 44 + 45 + return 0; 46 + } 47 + 48 + static int samsungq10_bl_get_intensity(struct backlight_device *bd) 49 + { 50 + return samsungq10_bl_brightness; 51 + } 52 + 53 + static const struct backlight_ops samsungq10_bl_ops = { 54 + .get_brightness = samsungq10_bl_get_intensity, 55 + .update_status = samsungq10_bl_set_intensity, 56 + }; 57 + 58 + #ifdef CONFIG_PM_SLEEP 59 + static int samsungq10_suspend(struct device *dev) 60 + { 61 + return 0; 62 + } 63 + 64 + static int samsungq10_resume(struct device *dev) 65 + { 66 + 67 + struct backlight_device *bd = dev_get_drvdata(dev); 68 + 69 + samsungq10_bl_set_intensity(bd); 70 + return 0; 71 + } 72 + #else 73 + #define samsungq10_suspend NULL 74 + #define samsungq10_resume NULL 75 + #endif 76 + 77 + static SIMPLE_DEV_PM_OPS(samsungq10_pm_ops, 78 + samsungq10_suspend, samsungq10_resume); 79 + 80 + static int __devinit samsungq10_probe(struct platform_device *pdev) 81 + { 82 + 83 + struct backlight_properties props; 84 + struct backlight_device *bd; 85 + 86 + memset(&props, 0, sizeof(struct backlight_properties)); 87 + props.type = BACKLIGHT_PLATFORM; 88 + props.max_brightness = SAMSUNGQ10_BL_MAX_INTENSITY; 89 + bd = backlight_device_register("samsung", &pdev->dev, NULL, 90 + &samsungq10_bl_ops, &props); 91 + if (IS_ERR(bd)) 92 + return PTR_ERR(bd); 93 + 94 + platform_set_drvdata(pdev, bd); 95 + 96 + bd->props.brightness = SAMSUNGQ10_BL_DEFAULT_INTENSITY; 97 + samsungq10_bl_set_intensity(bd); 98 + 99 + return 0; 100 + } 101 + 102 + static int __devexit samsungq10_remove(struct platform_device *pdev) 103 + { 104 + 105 + struct backlight_device *bd = platform_get_drvdata(pdev); 106 + 107 + bd->props.brightness = SAMSUNGQ10_BL_DEFAULT_INTENSITY; 108 + samsungq10_bl_set_intensity(bd); 109 + 110 + backlight_device_unregister(bd); 111 + 112 + return 0; 113 + } 114 + 115 + static struct platform_driver samsungq10_driver = { 116 + .driver = { 117 + .name = KBUILD_MODNAME, 118 + .owner = THIS_MODULE, 119 + .pm = &samsungq10_pm_ops, 120 + }, 121 + .probe = samsungq10_probe, 122 + .remove = __devexit_p(samsungq10_remove), 123 + }; 124 + 125 + static struct platform_device *samsungq10_device; 126 + 127 + static int __init dmi_check_callback(const struct dmi_system_id *id) 128 + { 129 + printk(KERN_INFO KBUILD_MODNAME ": found model '%s'\n", id->ident); 130 + return 1; 131 + } 132 + 133 + static struct dmi_system_id __initdata samsungq10_dmi_table[] = { 134 + { 135 + .ident = "Samsung Q10", 136 + .matches = { 137 + DMI_MATCH(DMI_SYS_VENDOR, "Samsung"), 138 + DMI_MATCH(DMI_PRODUCT_NAME, "SQ10"), 139 + }, 140 + .callback = dmi_check_callback, 141 + }, 142 + { 143 + .ident = "Samsung Q20", 144 + .matches = { 145 + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"), 146 + DMI_MATCH(DMI_PRODUCT_NAME, "SENS Q20"), 147 + }, 148 + .callback = dmi_check_callback, 149 + }, 150 + { 151 + .ident = "Samsung Q25", 152 + .matches = { 153 + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"), 154 + DMI_MATCH(DMI_PRODUCT_NAME, "NQ25"), 155 + }, 156 + .callback = dmi_check_callback, 157 + }, 158 + { 159 + .ident = "Dell Latitude X200", 160 + .matches = { 161 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 162 + DMI_MATCH(DMI_PRODUCT_NAME, "X200"), 163 + }, 164 + .callback = dmi_check_callback, 165 + }, 166 + { }, 167 + }; 168 + MODULE_DEVICE_TABLE(dmi, samsungq10_dmi_table); 169 + 170 + static int __init samsungq10_init(void) 171 + { 172 + if (!force && !dmi_check_system(samsungq10_dmi_table)) 173 + return -ENODEV; 174 + 175 + samsungq10_device = platform_create_bundle(&samsungq10_driver, 176 + samsungq10_probe, 177 + NULL, 0, NULL, 0); 178 + 179 + if (IS_ERR(samsungq10_device)) 180 + return PTR_ERR(samsungq10_device); 181 + 182 + return 0; 183 + } 184 + 185 + static void __exit samsungq10_exit(void) 186 + { 187 + platform_device_unregister(samsungq10_device); 188 + platform_driver_unregister(&samsungq10_driver); 189 + } 190 + 191 + module_init(samsungq10_init); 192 + module_exit(samsungq10_exit); 193 + 194 + MODULE_AUTHOR("Frederick van der Wyck <fvanderwyck@gmail.com>"); 195 + MODULE_DESCRIPTION("Samsung Q10 Driver"); 196 + MODULE_LICENSE("GPL");
+10 -1
drivers/platform/x86/thinkpad_acpi.c
··· 3186 3186 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 3187 3187 3188 3188 /* (assignments unknown, please report if found) */ 3189 + KEY_UNKNOWN, KEY_UNKNOWN, 3190 + 3191 + /* 3192 + * The mic mute button only sends 0x1a. It does not 3193 + * automatically mute the mic or change the mute light. 3194 + */ 3195 + KEY_MICMUTE, /* 0x1a: Mic mute (since ?400 or so) */ 3196 + 3197 + /* (assignments unknown, please report if found) */ 3189 3198 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3190 - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3199 + KEY_UNKNOWN, 3191 3200 }, 3192 3201 }; 3193 3202
+2
include/linux/input.h
··· 438 438 #define KEY_WIMAX 246 439 439 #define KEY_RFKILL 247 /* Key that controls all radios */ 440 440 441 + #define KEY_MICMUTE 248 /* Mute / unmute the microphone */ 442 + 441 443 /* Code 255 is reserved for special needs of AT keyboard driver */ 442 444 443 445 #define BTN_MISC 0x100