Merge tag 'platform-drivers-x86-v3.19-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86

Pull x86 platform driver update from Darren Hart:
 - thinkpad-acpi: Switch to software mute, cleanups
 - acerhdf: Bang-bang thermal governor, new models, cleanups
 - dell-laptop: New keyboard backlight support and documentation
 - toshiba_acpi: Keyboard backlight updates, hotkey handling
 - dell-wmi: Keypress filtering, WMI event processing
 - eeepc-laptop: Multiple cleanups, improved error handling, documentation
 - hp_wireless: Inform the user if hp_wireless_input_setup()/add() fails
 - misc: Code cleanups, quirks, various new IDs

* tag 'platform-drivers-x86-v3.19-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (33 commits)
  platform/x86/acerhdf: Still depends on THERMAL
  Documentation: Add entry for dell-laptop sysfs interface
  acpi: Remove _OSI(Linux) for ThinkPads
  thinkpad-acpi: Try to use full software mute control
  acerhdf: minor clean up
  acerhdf: added critical trip point
  acerhdf: Use bang-bang thermal governor
  acerhdf: Adding support for new models
  acerhdf: Adding support for "manual mode"
  dell-smo8800: Add more ACPI ids and change description of driver
  platform: x86: dell-laptop: Add support for keyboard backlight
  toshiba_acpi: Add keyboard backlight mode change event
  toshiba_acpi: Change notify funtion to handle more events
  toshiba_acpi: Move hotkey enabling code to its own function
  dell-wmi: Don't report keypresses on keybord illumination change
  dell-wmi: Don't report keypresses for radio state changes
  hp_wireless: Inform the user if hp_wireless_input_setup()/add() fails
  toshiba-acpi: Add missing ID (TOS6207)
  Sony-laptop: Deletion of an unnecessary check before the function call "pci_dev_put"
  platform: x86: Deletion of checks before backlight_device_unregister()
  ...
Esse commit está contido em:
Linus Torvalds
2014-12-18 20:24:55 -08:00
22 arquivos alterados com 1781 adições e 415 exclusões

Ver arquivo

@@ -38,7 +38,8 @@ config ACER_WMI
config ACERHDF
tristate "Acer Aspire One temperature and fan driver"
depends on THERMAL && ACPI
depends on ACPI && THERMAL
select THERMAL_GOV_BANG_BANG
---help---
This is a driver for Acer Aspire One netbooks. It allows to access
the temperature sensor and to control the fan.
@@ -128,10 +129,10 @@ config DELL_WMI_AIO
be called dell-wmi-aio.
config DELL_SMO8800
tristate "Dell Latitude freefall driver (ACPI SMO8800/SMO8810)"
tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
depends on ACPI
---help---
Say Y here if you want to support SMO8800/SMO8810 freefall device
Say Y here if you want to support SMO88XX freefall devices
on Dell Latitude laptops.
To compile this driver as a module, choose M here: the module will

Ver arquivo

@@ -50,7 +50,7 @@
*/
#undef START_IN_KERNEL_MODE
#define DRV_VER "0.5.26"
#define DRV_VER "0.7.0"
/*
* According to the Atom N270 datasheet,
@@ -119,116 +119,152 @@ struct fancmd {
u8 cmd_auto;
};
struct manualcmd {
u8 mreg;
u8 moff;
};
/* default register and command to disable fan in manual mode */
static const struct manualcmd mcmd = {
.mreg = 0x94,
.moff = 0xff,
};
/* BIOS settings */
struct bios_settings_t {
struct bios_settings {
const char *vendor;
const char *product;
const char *version;
unsigned char fanreg;
unsigned char tempreg;
u8 fanreg;
u8 tempreg;
struct fancmd cmd;
int mcmd_enable;
};
/* Register addresses and values for different BIOS versions */
static const struct bios_settings_t bios_tbl[] = {
static const struct bios_settings bios_tbl[] = {
/* AOA110 */
{"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
{"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
{"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
{"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
{"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
{"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} },
{"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
{"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
{"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
{"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0},
{"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0},
{"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00}, 0},
{"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00}, 0},
{"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00}, 0},
{"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00}, 0},
{"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00}, 0},
{"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00}, 0},
{"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00}, 0},
/* AOA150 */
{"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
{"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0},
{"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00}, 0},
/* LT1005u */
{"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00}, 0},
/* Acer 1410 */
{"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3115", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3117", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3119", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v1.3204", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0},
/* Acer 1810xx */
{"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3115", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3115", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3117", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3117", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3119", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3119", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v1.3204", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v1.3204", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00}, 0},
/* Acer 5755G */
{"Acer", "Aspire 5755G", "V1.20", 0xab, 0xb4, {0x00, 0x08}, 0},
{"Acer", "Aspire 5755G", "V1.21", 0xab, 0xb3, {0x00, 0x08}, 0},
/* Acer 521 */
{"Acer", "AO521", "V1.11", 0x55, 0x58, {0x1f, 0x00}, 0},
/* Acer 531 */
{"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
{"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00}, 0},
{"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00}, 0},
/* Acer 751 */
{"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} },
{"Acer", "AO751h", "V0.3206", 0x55, 0x58, {0x21, 0x00}, 0},
{"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00}, 0},
/* Acer 753 */
{"Acer", "Aspire One 753", "V1.24", 0x93, 0xac, {0x14, 0x04}, 1},
/* Acer 1825 */
{"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} },
{"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00}, 0},
/* Acer Extensa 5420 */
{"Acer", "Extensa 5420", "V1.17", 0x93, 0xac, {0x14, 0x04}, 1},
/* Acer Aspire 5315 */
{"Acer", "Aspire 5315", "V1.19", 0x93, 0xac, {0x14, 0x04}, 1},
/* Acer Aspire 5739 */
{"Acer", "Aspire 5739G", "V1.3311", 0x55, 0x58, {0x20, 0x00}, 0},
/* Acer TravelMate 7730 */
{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} },
{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00}, 0},
/* Acer TravelMate TM8573T */
{"Acer", "TM8573T", "V1.13", 0x93, 0xa8, {0x14, 0x04}, 1},
/* Gateway */
{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
{"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} },
{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} },
{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} },
{"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },
{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00}, 0},
{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00}, 0},
{"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
/* Packard Bell */
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
{"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0},
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0},
{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00}, 0},
{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0},
{"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
{"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00}, 0},
/* pewpew-terminator */
{"", "", "", 0, 0, {0, 0} }
{"", "", "", 0, 0, {0, 0}, 0}
};
static const struct bios_settings_t *bios_cfg __read_mostly;
static const struct bios_settings *bios_cfg __read_mostly;
/*
* this struct is used to instruct thermal layer to use bang_bang instead of
* default governor for acerhdf
*/
static struct thermal_zone_params acerhdf_zone_params = {
.governor_name = "bang_bang",
};
static int acerhdf_get_temp(int *temp)
{
@@ -275,6 +311,12 @@ static void acerhdf_change_fanstate(int state)
fanstate = state;
ec_write(bios_cfg->fanreg, cmd);
if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) {
if (verbose)
pr_notice("turning off fan manually\n");
ec_write(mcmd.mreg, mcmd.moff);
}
}
static void acerhdf_check_param(struct thermal_zone_device *thermal)
@@ -401,6 +443,21 @@ static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip,
{
if (trip == 0)
*type = THERMAL_TRIP_ACTIVE;
else if (trip == 1)
*type = THERMAL_TRIP_CRITICAL;
else
return -EINVAL;
return 0;
}
static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip,
unsigned long *temp)
{
if (trip != 0)
return -EINVAL;
*temp = fanon - fanoff;
return 0;
}
@@ -410,6 +467,10 @@ static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip,
{
if (trip == 0)
*temp = fanon;
else if (trip == 1)
*temp = ACERHDF_TEMP_CRIT;
else
return -EINVAL;
return 0;
}
@@ -429,6 +490,7 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = {
.get_mode = acerhdf_get_mode,
.set_mode = acerhdf_set_mode,
.get_trip_type = acerhdf_get_trip_type,
.get_trip_hyst = acerhdf_get_trip_hyst,
.get_trip_temp = acerhdf_get_trip_temp,
.get_crit_temp = acerhdf_get_crit_temp,
};
@@ -481,9 +543,7 @@ static int acerhdf_set_cur_state(struct thermal_cooling_device *cdev,
}
if (state == 0) {
/* turn fan off only if below fanoff temperature */
if ((cur_state == ACERHDF_FAN_AUTO) &&
(cur_temp < fanoff))
if (cur_state == ACERHDF_FAN_AUTO)
acerhdf_change_fanstate(ACERHDF_FAN_OFF);
} else {
if (cur_state == ACERHDF_FAN_OFF)
@@ -558,7 +618,7 @@ static int str_starts_with(const char *str, const char *start)
static int acerhdf_check_hardware(void)
{
char const *vendor, *version, *product;
const struct bios_settings_t *bt = NULL;
const struct bios_settings *bt = NULL;
/* get BIOS data */
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
@@ -660,12 +720,20 @@ static int acerhdf_register_thermal(void)
if (IS_ERR(cl_dev))
return -EINVAL;
thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
&acerhdf_dev_ops, NULL, 0,
thz_dev = thermal_zone_device_register("acerhdf", 2, 0, NULL,
&acerhdf_dev_ops,
&acerhdf_zone_params, 0,
(kernelmode) ? interval*1000 : 0);
if (IS_ERR(thz_dev))
return -EINVAL;
if (strcmp(thz_dev->governor->name,
acerhdf_zone_params.governor_name)) {
pr_err("Didn't get thermal governor %s, perhaps not compiled into thermal subsystem.\n",
acerhdf_zone_params.governor_name);
return -EINVAL;
}
return 0;
}
@@ -722,9 +790,15 @@ MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5755G:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:");
MODULE_ALIAS("dmi:*:*Acer*:pnAO521*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5739G:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*One*753:");
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5315:");
MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:");
MODULE_ALIAS("dmi:*:*Acer*:TM8573T:");
MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:");
@@ -733,6 +807,7 @@ MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:");
MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:");
MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:");
MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:");
MODULE_ALIAS("dmi:*:*Acer*:pnExtensa 5420*:");
module_init(acerhdf_init);
module_exit(acerhdf_exit);

Ver arquivo

@@ -843,8 +843,7 @@ static int asus_backlight_init(struct asus_laptop *asus)
static void asus_backlight_exit(struct asus_laptop *asus)
{
if (asus->backlight_device)
backlight_device_unregister(asus->backlight_device);
backlight_device_unregister(asus->backlight_device);
asus->backlight_device = NULL;
}

Ver arquivo

@@ -189,6 +189,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X551CA",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"),
},
.driver_data = &quirk_asus_wapf4,
},
{
.callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X55A",

Ver arquivo

@@ -1308,8 +1308,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
static void asus_wmi_backlight_exit(struct asus_wmi *asus)
{
if (asus->backlight_device)
backlight_device_unregister(asus->backlight_device);
backlight_device_unregister(asus->backlight_device);
asus->backlight_device = NULL;
}

Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff

Ver arquivo

@@ -1,5 +1,5 @@
/*
* dell-smo8800.c - Dell Latitude ACPI SMO8800/SMO8810 freefall sensor driver
* dell-smo8800.c - Dell Latitude ACPI SMO88XX freefall sensor driver
*
* Copyright (C) 2012 Sonal Santan <sonal.santan@gmail.com>
* Copyright (C) 2014 Pali Rohár <pali.rohar@gmail.com>
@@ -209,7 +209,13 @@ static int smo8800_remove(struct acpi_device *device)
static const struct acpi_device_id smo8800_ids[] = {
{ "SMO8800", 0 },
{ "SMO8801", 0 },
{ "SMO8810", 0 },
{ "SMO8811", 0 },
{ "SMO8820", 0 },
{ "SMO8821", 0 },
{ "SMO8830", 0 },
{ "SMO8831", 0 },
{ "", 0 },
};
@@ -228,6 +234,6 @@ static struct acpi_driver smo8800_driver = {
module_acpi_driver(smo8800_driver);
MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO8800/SMO8810)");
MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO88XX)");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sonal Santan, Pali Rohár");

Ver arquivo

@@ -65,10 +65,8 @@ static const struct key_entry dell_wmi_legacy_keymap[] __initconst = {
/* Battery health status button */
{ KE_KEY, 0xe007, { KEY_BATTERY } },
/* This is actually for all radios. Although physically a
* switch, the notification does not provide an indication of
* state and so it should be reported as a key */
{ KE_KEY, 0xe008, { KEY_WLAN } },
/* Radio devices state change */
{ KE_IGNORE, 0xe008, { KEY_RFKILL } },
/* The next device is at offset 6, the active devices are at
offset 8 and the attached devices at offset 10 */
@@ -145,57 +143,154 @@ static const u16 bios_to_linux_keycode[256] __initconst = {
static struct input_dev *dell_wmi_input_dev;
static void dell_wmi_process_key(int reported_key)
{
const struct key_entry *key;
key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
reported_key);
if (!key) {
pr_info("Unknown key %x pressed\n", reported_key);
return;
}
pr_debug("Key %x pressed\n", reported_key);
/* Don't report brightness notifications that will also come via ACPI */
if ((key->keycode == KEY_BRIGHTNESSUP ||
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video)
return;
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
}
static void dell_wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
acpi_size buffer_size;
u16 *buffer_entry, *buffer_end;
int len, i;
status = wmi_get_event_data(value, &response);
if (status != AE_OK) {
pr_info("bad event status 0x%x\n", status);
pr_warn("bad event status 0x%x\n", status);
return;
}
obj = (union acpi_object *)response.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER) {
const struct key_entry *key;
int reported_key;
u16 *buffer_entry = (u16 *)obj->buffer.pointer;
int buffer_size = obj->buffer.length/2;
if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) {
pr_info("Received unknown WMI event (0x%x)\n",
buffer_entry[1]);
kfree(obj);
return;
}
if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0))
reported_key = (int)buffer_entry[2];
else if (buffer_size >= 2)
reported_key = (int)buffer_entry[1] & 0xffff;
else {
pr_info("Received unknown WMI event\n");
kfree(obj);
return;
}
key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
reported_key);
if (!key) {
pr_info("Unknown key %x pressed\n", reported_key);
} else if ((key->keycode == KEY_BRIGHTNESSUP ||
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
/* Don't report brightness notifications that will also
* come via ACPI */
;
} else {
sparse_keymap_report_entry(dell_wmi_input_dev, key,
1, true);
}
if (!obj) {
pr_warn("no response\n");
return;
}
if (obj->type != ACPI_TYPE_BUFFER) {
pr_warn("bad response type %x\n", obj->type);
kfree(obj);
return;
}
pr_debug("Received WMI event (%*ph)\n",
obj->buffer.length, obj->buffer.pointer);
buffer_entry = (u16 *)obj->buffer.pointer;
buffer_size = obj->buffer.length/2;
if (!dell_new_hk_type) {
if (buffer_size >= 3 && buffer_entry[1] == 0x0)
dell_wmi_process_key(buffer_entry[2]);
else if (buffer_size >= 2)
dell_wmi_process_key(buffer_entry[1]);
else
pr_info("Received unknown WMI event\n");
kfree(obj);
return;
}
buffer_end = buffer_entry + buffer_size;
while (buffer_entry < buffer_end) {
len = buffer_entry[0];
if (len == 0)
break;
len++;
if (buffer_entry + len > buffer_end) {
pr_warn("Invalid length of WMI event\n");
break;
}
pr_debug("Process buffer (%*ph)\n", len*2, buffer_entry);
switch (buffer_entry[1]) {
case 0x00:
for (i = 2; i < len; ++i) {
switch (buffer_entry[i]) {
case 0xe043:
/* NIC Link is Up */
pr_debug("NIC Link is Up\n");
break;
case 0xe044:
/* NIC Link is Down */
pr_debug("NIC Link is Down\n");
break;
case 0xe045:
/* Unknown event but defined in DSDT */
default:
/* Unknown event */
pr_info("Unknown WMI event type 0x00: "
"0x%x\n", (int)buffer_entry[i]);
break;
}
}
break;
case 0x10:
/* Keys pressed */
for (i = 2; i < len; ++i)
dell_wmi_process_key(buffer_entry[i]);
break;
case 0x11:
for (i = 2; i < len; ++i) {
switch (buffer_entry[i]) {
case 0xfff0:
/* Battery unplugged */
pr_debug("Battery unplugged\n");
break;
case 0xfff1:
/* Battery inserted */
pr_debug("Battery inserted\n");
break;
case 0x01e1:
case 0x02ea:
case 0x02eb:
case 0x02ec:
case 0x02f6:
/* Keyboard backlight level changed */
pr_debug("Keyboard backlight level "
"changed\n");
break;
default:
/* Unknown event */
pr_info("Unknown WMI event type 0x11: "
"0x%x\n", (int)buffer_entry[i]);
break;
}
}
break;
default:
/* Unknown event */
pr_info("Unknown WMI event type 0x%x\n",
(int)buffer_entry[1]);
break;
}
buffer_entry += len;
}
kfree(obj);
}
@@ -213,11 +308,16 @@ static const struct key_entry * __init dell_wmi_prepare_new_keymap(void)
for (i = 0; i < hotkey_num; i++) {
const struct dell_bios_keymap_entry *bios_entry =
&dell_bios_hotkey_table->keymap[i];
keymap[i].type = KE_KEY;
keymap[i].code = bios_entry->scancode;
keymap[i].keycode = bios_entry->keycode < 256 ?
u16 keycode = bios_entry->keycode < 256 ?
bios_to_linux_keycode[bios_entry->keycode] :
KEY_RESERVED;
if (keycode == KEY_KBDILLUMTOGGLE)
keymap[i].type = KE_IGNORE;
else
keymap[i].type = KE_KEY;
keymap[i].code = bios_entry->scancode;
keymap[i].keycode = keycode;
}
keymap[hotkey_num].type = KE_END;

Ver arquivo

@@ -417,8 +417,7 @@ static ssize_t cpufv_disabled_store(struct device *dev,
switch (value) {
case 0:
if (eeepc->cpufv_disabled)
pr_warn("cpufv enabled (not officially supported "
"on this model)\n");
pr_warn("cpufv enabled (not officially supported on this model)\n");
eeepc->cpufv_disabled = false;
return count;
case 1:
@@ -580,60 +579,59 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
mutex_lock(&eeepc->hotplug_lock);
pci_lock_rescan_remove();
if (eeepc->hotplug_slot) {
port = acpi_get_pci_dev(handle);
if (!port) {
pr_warning("Unable to find port\n");
goto out_unlock;
}
if (!eeepc->hotplug_slot)
goto out_unlock;
bus = port->subordinate;
if (!bus) {
pr_warn("Unable to find PCI bus 1?\n");
goto out_put_dev;
}
if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
pr_err("Unable to read PCI config space?\n");
goto out_put_dev;
}
absent = (l == 0xffffffff);
if (blocked != absent) {
pr_warn("BIOS says wireless lan is %s, "
"but the pci device is %s\n",
blocked ? "blocked" : "unblocked",
absent ? "absent" : "present");
pr_warn("skipped wireless hotplug as probably "
"inappropriate for this model\n");
goto out_put_dev;
}
if (!blocked) {
dev = pci_get_slot(bus, 0);
if (dev) {
/* Device already present */
pci_dev_put(dev);
goto out_put_dev;
}
dev = pci_scan_single_device(bus, 0);
if (dev) {
pci_bus_assign_resources(bus);
pci_bus_add_device(dev);
}
} else {
dev = pci_get_slot(bus, 0);
if (dev) {
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
}
out_put_dev:
pci_dev_put(port);
port = acpi_get_pci_dev(handle);
if (!port) {
pr_warning("Unable to find port\n");
goto out_unlock;
}
bus = port->subordinate;
if (!bus) {
pr_warn("Unable to find PCI bus 1?\n");
goto out_put_dev;
}
if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
pr_err("Unable to read PCI config space?\n");
goto out_put_dev;
}
absent = (l == 0xffffffff);
if (blocked != absent) {
pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
blocked ? "blocked" : "unblocked",
absent ? "absent" : "present");
pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
goto out_put_dev;
}
if (!blocked) {
dev = pci_get_slot(bus, 0);
if (dev) {
/* Device already present */
pci_dev_put(dev);
goto out_put_dev;
}
dev = pci_scan_single_device(bus, 0);
if (dev) {
pci_bus_assign_resources(bus);
pci_bus_add_device(dev);
}
} else {
dev = pci_get_slot(bus, 0);
if (dev) {
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
}
out_put_dev:
pci_dev_put(port);
out_unlock:
pci_unlock_rescan_remove();
mutex_unlock(&eeepc->hotplug_lock);
@@ -821,11 +819,15 @@ static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
return 0;
}
static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
{
eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
if (eeepc->wlan_rfkill) {
rfkill_unregister(eeepc->wlan_rfkill);
rfkill_destroy(eeepc->wlan_rfkill);
@@ -897,9 +899,9 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
if (result == -EBUSY)
result = 0;
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
exit:
if (result && result != -ENODEV)
@@ -915,7 +917,7 @@ static int eeepc_hotk_thaw(struct device *device)
struct eeepc_laptop *eeepc = dev_get_drvdata(device);
if (eeepc->wlan_rfkill) {
bool wlan;
int wlan;
/*
* Work around bios bug - acpi _PTS turns off the wireless led
@@ -923,7 +925,8 @@ static int eeepc_hotk_thaw(struct device *device)
* we should kick it ourselves in case hibernation is aborted.
*/
wlan = get_acpi(eeepc, CM_ASL_WLAN);
set_acpi(eeepc, CM_ASL_WLAN, wlan);
if (wlan >= 0)
set_acpi(eeepc, CM_ASL_WLAN, wlan);
}
return 0;
@@ -935,9 +938,9 @@ static int eeepc_hotk_restore(struct device *device)
/* Refresh both wlan rfkill state and pci hotplug */
if (eeepc->wlan_rfkill) {
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
}
if (eeepc->bluetooth_rfkill)
@@ -977,18 +980,28 @@ static struct platform_driver platform_driver = {
#define EEEPC_EC_SFB0 0xD0
#define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
static inline int eeepc_pwm_to_lmsensors(int value)
{
return value * 255 / 100;
}
static inline int eeepc_lmsensors_to_pwm(int value)
{
value = clamp_val(value, 0, 255);
return value * 100 / 255;
}
static int eeepc_get_fan_pwm(void)
{
u8 value = 0;
ec_read(EEEPC_EC_FAN_PWM, &value);
return value * 255 / 100;
return eeepc_pwm_to_lmsensors(value);
}
static void eeepc_set_fan_pwm(int value)
{
value = clamp_val(value, 0, 255);
value = value * 100 / 255;
value = eeepc_lmsensors_to_pwm(value);
ec_write(EEEPC_EC_FAN_PWM, value);
}
@@ -1002,15 +1015,19 @@ static int eeepc_get_fan_rpm(void)
return high << 8 | low;
}
#define EEEPC_EC_FAN_CTRL_BIT 0x02
#define EEEPC_FAN_CTRL_MANUAL 1
#define EEEPC_FAN_CTRL_AUTO 2
static int eeepc_get_fan_ctrl(void)
{
u8 value = 0;
ec_read(EEEPC_EC_FAN_CTRL, &value);
if (value & 0x02)
return 1; /* manual */
if (value & EEEPC_EC_FAN_CTRL_BIT)
return EEEPC_FAN_CTRL_MANUAL;
else
return 2; /* automatic */
return EEEPC_FAN_CTRL_AUTO;
}
static void eeepc_set_fan_ctrl(int manual)
@@ -1018,10 +1035,10 @@ static void eeepc_set_fan_ctrl(int manual)
u8 value = 0;
ec_read(EEEPC_EC_FAN_CTRL, &value);
if (manual == 1)
value |= 0x02;
if (manual == EEEPC_FAN_CTRL_MANUAL)
value |= EEEPC_EC_FAN_CTRL_BIT;
else
value &= ~0x02;
value &= ~EEEPC_EC_FAN_CTRL_BIT;
ec_write(EEEPC_EC_FAN_CTRL, value);
}
@@ -1156,8 +1173,7 @@ static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
{
if (eeepc->backlight_device)
backlight_device_unregister(eeepc->backlight_device);
backlight_device_unregister(eeepc->backlight_device);
eeepc->backlight_device = NULL;
}
@@ -1216,7 +1232,7 @@ static void eeepc_input_exit(struct eeepc_laptop *eeepc)
static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
{
if (!eeepc->inputdev)
return ;
return;
if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
pr_info("Unknown key %x pressed\n", event);
}
@@ -1224,6 +1240,7 @@ static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
{
struct eeepc_laptop *eeepc = acpi_driver_data(device);
int old_brightness, new_brightness;
u16 count;
if (event > ACPI_MAX_SYS_NOTIFY)
@@ -1234,34 +1251,32 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
count);
/* Brightness events are special */
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
/* Ignore them completely if the acpi video driver is used */
if (eeepc->backlight_device != NULL) {
int old_brightness, new_brightness;
/* Update the backlight device. */
old_brightness = eeepc_backlight_notify(eeepc);
/* Convert event to keypress (obsolescent hack) */
new_brightness = event - NOTIFY_BRN_MIN;
if (new_brightness < old_brightness) {
event = NOTIFY_BRN_MIN; /* brightness down */
} else if (new_brightness > old_brightness) {
event = NOTIFY_BRN_MAX; /* brightness up */
} else {
/*
* no change in brightness - already at min/max,
* event will be desired value (or else ignored)
*/
}
eeepc_input_notify(eeepc, event);
}
} else {
/* Everything else is a bona-fide keypress event */
if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
eeepc_input_notify(eeepc, event);
return;
}
/* Ignore them completely if the acpi video driver is used */
if (!eeepc->backlight_device)
return;
/* Update the backlight device. */
old_brightness = eeepc_backlight_notify(eeepc);
/* Convert event to keypress (obsolescent hack) */
new_brightness = event - NOTIFY_BRN_MIN;
if (new_brightness < old_brightness) {
event = NOTIFY_BRN_MIN; /* brightness down */
} else if (new_brightness > old_brightness) {
event = NOTIFY_BRN_MAX; /* brightness up */
} else {
/*
* no change in brightness - already at min/max,
* event will be desired value (or else ignored)
*/
}
eeepc_input_notify(eeepc, event);
}
static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
@@ -1293,8 +1308,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
*/
if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
eeepc->cpufv_disabled = true;
pr_info("model %s does not officially support setting cpu "
"speed\n", model);
pr_info("model %s does not officially support setting cpu speed\n",
model);
pr_info("cpufv disabled to avoid instability\n");
}
@@ -1320,8 +1335,8 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
Check if cm_getv[cm] works and, if yes, assume cm should be set. */
if (!(eeepc->cm_supported & (1 << cm))
&& !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
pr_info("%s (%x) not reported by BIOS,"
" enabling anyway\n", name, 1 << cm);
pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
name, 1 << cm);
eeepc->cm_supported |= 1 << cm;
}
}

Ver arquivo

@@ -1153,8 +1153,7 @@ fail_hotkey1:
fail_hotkey:
platform_driver_unregister(&fujitsupf_driver);
fail_backlight:
if (fujitsu->bl_device)
backlight_device_unregister(fujitsu->bl_device);
backlight_device_unregister(fujitsu->bl_device);
fail_sysfs_group:
sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
&fujitsupf_attribute_group);
@@ -1178,8 +1177,7 @@ static void __exit fujitsu_cleanup(void)
platform_driver_unregister(&fujitsupf_driver);
if (fujitsu->bl_device)
backlight_device_unregister(fujitsu->bl_device);
backlight_device_unregister(fujitsu->bl_device);
sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
&fujitsupf_attribute_group);

Ver arquivo

@@ -85,6 +85,9 @@ static int hpwl_add(struct acpi_device *device)
int err;
err = hp_wireless_input_setup();
if (err)
pr_err("Failed to setup hp wireless hotkeys\n");
return err;
}

Ver arquivo

@@ -246,6 +246,7 @@ static const struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap),
AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap),
AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"

Ver arquivo

@@ -729,8 +729,7 @@ static int ideapad_backlight_init(struct ideapad_private *priv)
static void ideapad_backlight_exit(struct ideapad_private *priv)
{
if (priv->blightdev)
backlight_device_unregister(priv->blightdev);
backlight_device_unregister(priv->blightdev);
priv->blightdev = NULL;
}

Ver arquivo

@@ -33,7 +33,7 @@
* performance by allocating more power or thermal budget to the CPU or GPU
* based on available headroom and activity.
*
* The basic algorithm is driven by a 5s moving average of tempurature. If
* The basic algorithm is driven by a 5s moving average of temperature. If
* thermal headroom is available, the CPU and/or GPU power clamps may be
* adjusted upwards. If we hit the thermal ceiling or a thermal trigger,
* we scale back the clamp. Aside from trigger events (when we're critically

Ver arquivo

@@ -271,8 +271,7 @@ static int oaktrail_backlight_init(void)
static void oaktrail_backlight_exit(void)
{
if (oaktrail_bl_device)
backlight_device_unregister(oaktrail_bl_device);
backlight_device_unregister(oaktrail_bl_device);
}
static int oaktrail_probe(struct platform_device *pdev)

Ver arquivo

@@ -820,7 +820,7 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
{
static bool extended;
if (str & 0x20)
if (str & I8042_STR_AUXDATA)
return false;
/* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/

Ver arquivo

@@ -354,8 +354,7 @@ static void __exit msi_wmi_exit(void)
sparse_keymap_free(msi_wmi_input_dev);
input_unregister_device(msi_wmi_input_dev);
}
if (backlight)
backlight_device_unregister(backlight);
backlight_device_unregister(backlight);
}
module_init(msi_wmi_init);

Ver arquivo

@@ -3140,8 +3140,7 @@ static void sony_nc_backlight_setup(void)
static void sony_nc_backlight_cleanup(void)
{
if (sony_bl_props.dev)
backlight_device_unregister(sony_bl_props.dev);
backlight_device_unregister(sony_bl_props.dev);
}
static int sony_nc_add(struct acpi_device *device)
@@ -3716,8 +3715,7 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
dev->event_types = type2_events;
out:
if (pcidev)
pci_dev_put(pcidev);
pci_dev_put(pcidev);
pr_info("detected Type%d model\n",
dev->model == SONYPI_DEVICE_TYPE1 ? 1 :

Ver arquivo

@@ -6557,6 +6557,17 @@ static struct ibm_struct brightness_driver_data = {
* bits 3-0 (volume). Other bits in NVRAM may have other functions,
* such as bit 7 which is used to detect repeated presses of MUTE,
* and we leave them unchanged.
*
* On newer Lenovo ThinkPads, the EC can automatically change the volume
* in response to user input. Unfortunately, this rarely works well.
* The laptop changes the state of its internal MUTE gate and, on some
* models, sends KEY_MUTE, causing any user code that responds to the
* mute button to get confused. The hardware MUTE gate is also
* unnecessary, since user code can handle the mute button without
* kernel or EC help.
*
* To avoid confusing userspace, we simply disable all EC-based mute
* and volume controls when possible.
*/
#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
@@ -6611,11 +6622,21 @@ enum tpacpi_volume_capabilities {
TPACPI_VOL_CAP_MAX
};
enum tpacpi_mute_btn_mode {
TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */
/* We don't know what mode 1 is. */
TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */
TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */
};
static enum tpacpi_volume_access_mode volume_mode =
TPACPI_VOL_MODE_MAX;
static enum tpacpi_volume_capabilities volume_capabilities;
static bool volume_control_allowed;
static bool software_mute_requested = true;
static bool software_mute_active;
static int software_mute_orig_mode;
/*
* Used to syncronize writers to TP_EC_AUDIO and
@@ -6633,6 +6654,8 @@ static void tpacpi_volume_checkpoint_nvram(void)
return;
if (!volume_control_allowed)
return;
if (software_mute_active)
return;
vdbg_printk(TPACPI_DBG_MIXER,
"trying to checkpoint mixer state to NVRAM...\n");
@@ -6694,6 +6717,12 @@ static int volume_set_status_ec(const u8 status)
dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
/*
* On X200s, and possibly on others, it can take a while for
* reads to become correct.
*/
msleep(1);
return 0;
}
@@ -6776,6 +6805,57 @@ unlock:
return rc;
}
static int volume_set_software_mute(bool startup)
{
int result;
if (!tpacpi_is_lenovo())
return -ENODEV;
if (startup) {
if (!acpi_evalf(ec_handle, &software_mute_orig_mode,
"HAUM", "qd"))
return -EIO;
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
"Initial HAUM setting was %d\n",
software_mute_orig_mode);
}
if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd",
(int)TP_EC_MUTE_BTN_NONE))
return -EIO;
if (result != TP_EC_MUTE_BTN_NONE)
pr_warn("Unexpected SAUM result %d\n",
result);
/*
* In software mute mode, the standard codec controls take
* precendence, so we unmute the ThinkPad HW switch at
* startup. Just on case there are SAUM-capable ThinkPads
* with level controls, set max HW volume as well.
*/
if (tp_features.mixer_no_level_control)
result = volume_set_mute(false);
else
result = volume_set_status(TP_EC_VOLUME_MAX);
if (result != 0)
pr_warn("Failed to unmute the HW mute switch\n");
return 0;
}
static void volume_exit_software_mute(void)
{
int r;
if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode)
|| r != software_mute_orig_mode)
pr_warn("Failed to restore mute mode\n");
}
static int volume_alsa_set_volume(const u8 vol)
{
dbg_printk(TPACPI_DBG_MIXER,
@@ -6883,7 +6963,12 @@ static void volume_suspend(void)
static void volume_resume(void)
{
volume_alsa_notify_change();
if (software_mute_active) {
if (volume_set_software_mute(false) < 0)
pr_warn("Failed to restore software mute\n");
} else {
volume_alsa_notify_change();
}
}
static void volume_shutdown(void)
@@ -6899,6 +6984,9 @@ static void volume_exit(void)
}
tpacpi_volume_checkpoint_nvram();
if (software_mute_active)
volume_exit_software_mute();
}
static int __init volume_create_alsa_mixer(void)
@@ -7083,16 +7171,20 @@ static int __init volume_init(struct ibm_init_struct *iibm)
"mute is supported, volume control is %s\n",
str_supported(!tp_features.mixer_no_level_control));
rc = volume_create_alsa_mixer();
if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
}
if (software_mute_requested && volume_set_software_mute(true) == 0) {
software_mute_active = true;
} else {
rc = volume_create_alsa_mixer();
if (rc) {
pr_err("Could not create the ALSA mixer interface\n");
return rc;
}
pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
pr_info("Console audio control enabled, mode: %s\n",
(volume_control_allowed) ?
"override (read/write)" :
"monitor (read only)");
}
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
"registering volume hotkeys as change notification\n");
@@ -9089,6 +9181,10 @@ MODULE_PARM_DESC(volume_control,
"Enables software override for the console audio "
"control when true");
module_param_named(software_mute, software_mute_requested, bool, 0444);
MODULE_PARM_DESC(software_mute,
"Request full software mute control");
/* ALSA module API parameters */
module_param_named(index, alsa_index, int, 0444);
MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");

Ver arquivo

@@ -186,6 +186,7 @@ static struct toshiba_acpi_dev *toshiba_acpi;
static const struct acpi_device_id toshiba_device_ids[] = {
{"TOS6200", 0},
{"TOS6207", 0},
{"TOS6208", 0},
{"TOS1900", 0},
{"", 0},
@@ -928,9 +929,7 @@ static int lcd_proc_open(struct inode *inode, struct file *file)
static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
{
u32 in[TCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 };
u32 out[TCI_WORDS];
acpi_status status;
u32 hci_result;
if (dev->tr_backlight_supported) {
bool enable = !value;
@@ -941,20 +940,9 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
value--;
}
in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT;
status = tci_raw(dev, in, out);
if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) {
pr_err("ACPI call to set brightness failed");
return -EIO;
}
/* Extra check for "incomplete" backlight method, where the AML code
* doesn't check for HCI_SET or HCI_GET and returns TOS_SUCCESS,
* the actual brightness, and in some cases the max brightness.
*/
if (out[2] > 0 || out[3] == 0xE000)
return -ENODEV;
return out[0] == TOS_SUCCESS ? 0 : -EIO;
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
hci_result = hci_write1(dev, HCI_LCD_BRIGHTNESS, value);
return hci_result == TOS_SUCCESS ? 0 : -EIO;
}
static int set_lcd_status(struct backlight_device *bd)
@@ -1406,12 +1394,6 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
if (ret)
return ret;
/* Update sysfs entries on successful mode change*/
ret = sysfs_update_group(&toshiba->acpi_dev->dev.kobj,
&toshiba_attr_group);
if (ret)
return ret;
toshiba->kbd_mode = mode;
}
@@ -1586,10 +1568,32 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
return exists ? attr->mode : 0;
}
/*
* Hotkeys
*/
static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
{
acpi_status status;
u32 result;
status = acpi_evaluate_object(dev->acpi_dev->handle,
"ENAB", NULL, NULL);
if (ACPI_FAILURE(status))
return -ENODEV;
result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE);
if (result == TOS_FAILURE)
return -EIO;
else if (result == TOS_NOT_SUPPORTED)
return -ENODEV;
return 0;
}
static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
struct serio *port)
{
if (str & 0x20)
if (str & I8042_STR_AUXDATA)
return false;
if (unlikely(data == 0xe0))
@@ -1648,9 +1652,45 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev,
pr_info("Unknown key %x\n", scancode);
}
static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev)
{
u32 hci_result, value;
int retries = 3;
int scancode;
if (dev->info_supported) {
scancode = toshiba_acpi_query_hotkey(dev);
if (scancode < 0)
pr_err("Failed to query hotkey event\n");
else if (scancode != 0)
toshiba_acpi_report_hotkey(dev, scancode);
} else if (dev->system_event_supported) {
do {
hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value);
switch (hci_result) {
case TOS_SUCCESS:
toshiba_acpi_report_hotkey(dev, (int)value);
break;
case TOS_NOT_SUPPORTED:
/*
* This is a workaround for an unresolved
* issue on some machines where system events
* sporadically become disabled.
*/
hci_result =
hci_write1(dev, HCI_SYSTEM_EVENT, 1);
pr_notice("Re-enabled hotkeys\n");
/* fall through */
default:
retries--;
break;
}
} while (retries && hci_result != TOS_FIFO_EMPTY);
}
}
static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
{
acpi_status status;
acpi_handle ec_handle;
int error;
u32 hci_result;
@@ -1677,7 +1717,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
* supported, so if it's present set up an i8042 key filter
* for this purpose.
*/
status = AE_ERROR;
ec_handle = ec_get_handle();
if (ec_handle && acpi_has_method(ec_handle, "NTFY")) {
INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work);
@@ -1708,10 +1747,9 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
goto err_remove_filter;
}
status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL);
if (ACPI_FAILURE(status)) {
error = toshiba_acpi_enable_hotkeys(dev);
if (error) {
pr_info("Unable to enable hotkeys\n");
error = -ENODEV;
goto err_remove_filter;
}
@@ -1721,7 +1759,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
goto err_remove_filter;
}
hci_result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE);
return 0;
err_remove_filter:
@@ -1810,8 +1847,7 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
rfkill_destroy(dev->bt_rfk);
}
if (dev->backlight_dev)
backlight_device_unregister(dev->backlight_dev);
backlight_device_unregister(dev->backlight_dev);
if (dev->illumination_supported)
led_classdev_unregister(&dev->led_dev);
@@ -1967,41 +2003,29 @@ error:
static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
{
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
u32 hci_result, value;
int retries = 3;
int scancode;
int ret;
if (event != 0x80)
return;
if (dev->info_supported) {
scancode = toshiba_acpi_query_hotkey(dev);
if (scancode < 0)
pr_err("Failed to query hotkey event\n");
else if (scancode != 0)
toshiba_acpi_report_hotkey(dev, scancode);
} else if (dev->system_event_supported) {
do {
hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value);
switch (hci_result) {
case TOS_SUCCESS:
toshiba_acpi_report_hotkey(dev, (int)value);
break;
case TOS_NOT_SUPPORTED:
/*
* This is a workaround for an unresolved
* issue on some machines where system events
* sporadically become disabled.
*/
hci_result =
hci_write1(dev, HCI_SYSTEM_EVENT, 1);
pr_notice("Re-enabled hotkeys\n");
/* fall through */
default:
retries--;
break;
}
} while (retries && hci_result != TOS_FIFO_EMPTY);
switch (event) {
case 0x80: /* Hotkeys and some system events */
toshiba_acpi_process_hotkeys(dev);
break;
case 0x92: /* Keyboard backlight mode changed */
/* Update sysfs entries */
ret = sysfs_update_group(&acpi_dev->dev.kobj,
&toshiba_attr_group);
if (ret)
pr_err("Unable to update sysfs entries\n");
break;
case 0x81: /* Unknown */
case 0x82: /* Unknown */
case 0x83: /* Unknown */
case 0x8c: /* Unknown */
case 0x8e: /* Unknown */
case 0x8f: /* Unknown */
case 0x90: /* Unknown */
default:
pr_info("Unknown event received %x\n", event);
break;
}
}
@@ -2020,16 +2044,12 @@ static int toshiba_acpi_suspend(struct device *device)
static int toshiba_acpi_resume(struct device *device)
{
struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));
u32 result;
acpi_status status;
int error;
if (dev->hotkey_dev) {
status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB",
NULL, NULL);
if (ACPI_FAILURE(status))
error = toshiba_acpi_enable_hotkeys(dev);
if (error)
pr_info("Unable to re-enable hotkeys\n");
result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE);
}
return 0;